# Host Header Injection

Атаки на HTTP-заголовок Host используют уязвимые веб-сайты, которые обрабатывают значение заголовка Host небезопасным способом. Если сервер неявно доверяет заголовку Host и не проверяет или не экранирует его должным образом, злоумышленник может использовать этот ввод для внедрения вредоносной полезной нагрузки, которая манипулирует поведением сервера. Атаки, связанные с внедрением полезной нагрузки непосредственно в заголовок Host, часто называются атаками "внедрения заголовка Host".

Готовые веб-приложения обычно не знают, в каком домене они развернуты, если это не указано вручную в конфигурационном файле во время установки.

Поскольку заголовок Host фактически является контролируемым пользователем, такая практика может привести к ряду проблем. Если вводимые данные не приведены в надлежащий вид или не проверены, заголовок Host становится потенциальным вектором для использования целого ряда других уязвимостей, в частности:

* Отравление веб-кэша.
* Недостатки бизнес-логики в конкретной функциональности.
* SSRF на основе маршрутизации.
* Классические уязвимости на стороне сервера, такие как SQL-инъекции.

## 2. Типичный уязвимый код:

Сброс пароля - одна из самых распространенных целей для Header Injection; вот пример того, как выглядит уязвимый код:

```
public void resetPasswordLink(HttpServletRequest request) {

    // retrieves the host from the request header
    String host = request.getHeader("Host");
    
    String email = request.getParameter("email");
    HttpSession session = request.getSession();

    if (session != null) {
        String token = generateResetToken(email);
        
        // Password reset link is constructed with the retrieved host
        // for the token that has just been generated.
        StringBuilder resetLinkBuilder = new StringBuilder()
                .append(host)
                .append("?reset")
                .append(token);
        
        // Send the email
        sendEmail(email, resetLinkBuilder.toString());
    }
}
```

Обратите внимание, что в параметре Хост заголовка. Злоумышленник может воспользоваться этим и перехватить POST запрос, чтобы произвольно изменить Host из заголовка запроса. Таким образом, письмо, которое получит жертва, будет выглядеть безопасным, однако при переходе по ссылке, которая была сгенерирована (с атакующим Host ), злоумышленник получит токен сброса пароля, а значит, сможет полностью сбросить пароль жертвы.

## 3. Смягчения:

Чтобы предотвратить атаки на HTTP-заголовок Host, самый простой подход заключается в том, чтобы не использовать Host в коде на стороне сервера. Дважды проверьте, действительно ли каждый URL должен быть абсолютным. Часто оказывается, что вместо него можно использовать относительный URL. Это простое изменение поможет вам предотвратить уязвимости отравления веб-кэша, в частности.

### 3.1. Белый список разрешенных доменов:

Вероятно, самая простая техника - это создание белого списка возможных доменов, с которых вы обычно отправляете запрос. Это, конечно, следует использовать только в том случае, если предполагаемое поведение вашего приложения заключается в отправке конкретного запроса с различных доменов.

```
public void resetPasswordLink(HttpServletRequest request) {

    // retrieves the host from the request header
    String host = request.getHeader("Host");
    
    String email = request.getParameter("email");
    HttpSession session = request.getSession();
    
    // create the whitelist for the allowed domains
    List <String> allowedDomains = Arrays.asList(
        "bobisecure.com",
        "bank.bobisecure.com",
        "s3.bobisecure.com"
    );
    
    // check whether the given `host` exists in the whitelist
    if (session != null && allowedDomains.contains(host)) {
        String token = generateResetToken(email);
        
        // Password reset link is constructed with the retrieved host
        // for the token that has just been generated.
        StringBuilder resetLinkBuilder = new StringBuilder()
                .append(host)
                .append("?reset")
                .append(token);
        
        // Send the email
        sendEmail(email, resetLinkBuilder.toString());
    }
}
```

### 3.2. Защита абсолютных URL-адресов:

Если вам приходится использовать абсолютные URL, то необходимо вручную указать текущий домен в конфигурационном файле и ссылаться на это значение вместо заголовка Host. В отличие от предыдущего пункта, конечная точка вашего приложения будет иметь дело только с единственным возможным URL. Такой подход устраняет угрозу, например, отравления при сбросе пароля.

{% hint style="danger" %}
Также важно убедиться, что вы не поддерживаете дополнительные заголовки, которые могут быть использованы для построения таких атак, в частности X-Forwarded-Host . Помните, что они могут поддерживаться по умолчанию.
{% endhint %}

## 4. Выводы:

Выполнение простых, но часто упускаемых из виду пунктов, которые мы здесь рассмотрели, защитит ваше приложение от любого типа инъекций в заголовок Host.

Помните, что в целом вы никогда не должны доверять заголовку Host, если это не является действительно необходимым!


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://notes.kraken-security.ru/kraken/secure-coding/server-side/host-header-injection.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
