Неверный заголовок HTTP_HOST для приложения Django, запущенного в Cloud Run
У меня есть приложение Django, запущенное в Cloud Run. Cloud Run настроен как бэкэнд-сервис для External Application Load Balancer.
Сервис работает с различными пользовательскими доменами. Список доменов постоянно меняется, поэтому управление доменами было перенесено на уровень политики безопасности Cloud Armor, чтобы избежать повторного развертывания сервиса после обновления списка доменов. На уровне Django разрешены все хосты: ALLOWED_HOSTS = ["*"]
example.net
разрешен политикой безопасности Cloud Armor, и каждый запрос к этому хосту обрабатывается приложением Django в Cloud Run.
Я начал получать запросы от некоторых сканирующих ботов, и некоторые из этих запросов вызывают ошибку на уровне приложения Django: Invalid HTTP_HOST header: 'mydomain.com%7d'. The domain name provided is not valid according to RFC 1034/1035.
Вот другие значения из трассировки этой ошибки:
Report at //example。com
Invalid HTTP_HOST header: 'example.net%7d'. The domain name provided is not valid according to RFC 1034/1035.
Request Method: GET
Request URL: http://example.net%7d//example%E3%80%82com
Django Version: 3.2.25
...
META:
...
HTTP_ACCEPT = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
HTTP_ACCEPT_ENCODING = 'gzip'
HTTP_ACCEPT_LANGUAGE = 'en-US,en;q=0.9,ca;q=0.8'
HTTP_CACHE_CONTROL = 'no-cache'
HTTP_FORWARDED = 'for="replaced.ip.address";proto=https'
HTTP_HOST = 'example.net%7d'
PATH_INFO = '//example。com'
QUERY_STRING = ''
RAW_URI = '//example%E3%80%82com'
...
В то же время в журналах на уровне балансировщика нагрузки эти значения не отображаются, и кажется, что значение хоста меняется до того, как попадает в Cloud Run:
Журнал балансировщика нагрузки:
httpRequest: {
...
requestMethod: "GET"
requestUrl: "https://example.net/"
status: 400
...
}
Журнал запуска облака:
httpRequest: {
requestMethod: "GET"
requestUrl: "https://example.net%7d//example%E3%80%82com"
status: 400
}
Главный вопрос: как можно воспроизвести такое поведение? Как можно изменить значения HOST и PATH на лету после того, как запрос прошел балансировщик нагрузки? Или это что-то связанное с Django, и эти значения добавляются во время обработки запроса?
Я пробовал отправлять запросы с недопустимым значением хоста, чтобы воспроизвести ошибку, но эти запросы отклонялись балансировщиком нагрузки и не достигали приложения Cloud Run.