mirror of https://github.com/yandex/gixy
53 lines
3.6 KiB
Markdown
53 lines
3.6 KiB
Markdown
# [http_splitting] HTTP Splitting
|
||
|
||
HTTP Splitting - уязвимость, возникающая из-за неправильной обработки входных данных.
|
||
Зачастую может быть для атак на приложение стоящее за Nginx (HTTP Request Splitting) или на клиентов приложения (HTTP Response Splitting).
|
||
|
||
Уязвимость возникает в случае, когда атакующий может внедрить символ перевода строки `\n` или `\r` в запрос или ответ формируемый Nginx.
|
||
|
||
## Как самостоятельно обнаружить?
|
||
При анализе конфигурации всега стоит обращать внимание на:
|
||
- какие переменные используются в директивах, отвечающих за формирование запросов (могут ли они содержать CRLF), например: `rewrite`, `return`, `add_header`, `proxy_set_header` или `proxy_pass`;
|
||
- используются ли переменные `$uri` и `$document_uri` и если да, то в каких директивах, т.к. они гарантированно содержат урлдекодированное значение;
|
||
- переменные, выделенные из групп с исключающим диапазоном: `(?P<myvar>[^.]+)`.
|
||
|
||
Пример плохой конфигурации с переменной, полученной из группы с исключающим диапазоном:
|
||
```nginx
|
||
server {
|
||
listen 80 default;
|
||
|
||
location ~ /v1/((?<action>[^.]*)\.json)?$ {
|
||
add_header X-Action $action;
|
||
return 200 "OK";
|
||
}
|
||
}
|
||
```
|
||
|
||
Пример эксплуатации данной конфигурации:
|
||
```http
|
||
GET /v1/see%20below%0d%0ax-crlf-header:injected.json HTTP/1.0
|
||
Host: localhost
|
||
|
||
HTTP/1.1 200 OK
|
||
Server: nginx/1.11.10
|
||
Date: Mon, 13 Mar 2017 21:21:29 GMT
|
||
Content-Type: application/octet-stream
|
||
Content-Length: 2
|
||
Connection: close
|
||
X-Action: see below
|
||
x-crlf-header:injected
|
||
|
||
OK
|
||
```
|
||
|
||
Из примера видно, что злоумышленник смог добавить заголовок ответа `x-crlf-header: injected`. Это случилось благодаря стечению нескольких обстоятельств:
|
||
- `add_header` не кодирует/валидирует переданные ему значения, считая что автор знает о последствиях;
|
||
- значение пути нормализуется перед обработкой локейшена;
|
||
- переменная `$action` была выделена из группы регулярного выражения с исключающим диапазоном: `[^.]*`;
|
||
- таким образом, значение переменной `$action` равно `see below\r\nx-crlf-header:injected` и при её использовании в формировании ответа добавился заголовок.
|
||
|
||
## Что делать?
|
||
- старайтесь использовать более безопасные переменные, например, `$request_uri` вместо `$uri`;
|
||
- запретите перевод строки в исключающем диапазоне, например, `/some/(?<action>[^/\s]+)` вместо `/some/(?<action>[^/]+`;
|
||
- возможно, хорошей идеей будет добавить валидацию `$uri` (только если вы знаете, что делаете).
|