gixy/docs/ru/plugins/ssrf.md

61 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# [ssrf] Server Side Request Forgery
Server Side Request Forgery - уязвимость, позволяющая выполнять различного рода запросы от имени веб-приложения (в нашем случае от имени Nginx).
Возникает, когда атакующий может контролировать адрес проксируемого сервера (второй аргумент директивы `proxy_pass`).
## Как самостоятельно обнаружить?
Наиболее распространенно два класса ошибок конфигурации, которые приводят к этой проблеме:
- отсутствие директивы [internal](http://nginx.org/ru/docs/http/ngx_http_core_module.html#internal). Её смысл заключается в указании того, что определенный location может использоваться только для внутренних запросов;
- небезопасное внутреннее перенаправление.
### Отсутствие директивы internal
Классический пример уязвимости типа SSRF в виду отсутствия директивы `internal` выглядит следующим образом:
```nginx
location ~ /proxy/(.*)/(.*)/(.*)$ {
proxy_pass $1://$2/$3;
}
```
Злоумышленник, полностью контролируя адрес проксируемого сервера, может выполнять произвольные запросы от имени Nginx.
### Небезопасное внутреннее перенаправление
Подразумевается, что в вашей конфигурации есть internal location, которые использует какие-либо данные из запроса в качестве адреса проксируемого сервера.
Например:
```nginx
location ~* ^/internal-proxy/(?<proxy_proto>https?)/(?<proxy_host>.*?)/(?<proxy_path>.*)$ {
internal;
proxy_pass $proxy_proto://$proxy_host/$proxy_path ;
proxy_set_header Host $proxy_host;
}
```
Согласно документации Nginx внутренними запросами являются:
> - запросы, перенаправленные директивами **error_page**, index, random_index и **try_files**;
> - запросы, перенаправленные с помощью поля “X-Accel-Redirect” заголовка ответа вышестоящего сервера;
> - подзапросы, формируемые командой “include virtual” модуля ngx_http_ssi_module и директивами модуля ngx_http_addition_module;
> - запросы, изменённые директивой **rewrite**.]>
Соответственно, любой "неосторожный" реврайт позволит злоумышленнику сделать внутренний запрос и контролировать адрес проксируемого сервера.
Пример плохой конфигурации:
```nginx
rewrite ^/(.*)/some$ /$1/ last;
location ~* ^/internal-proxy/(?<proxy_proto>https?)/(?<proxy_host>.*?)/(?<proxy_path>.*)$ {
internal;
proxy_pass $proxy_proto://$proxy_host/$proxy_path ;
proxy_set_header Host $proxy_host;
}
```
## Что делать?
Есть несколько правил, которых стоит придерживаться в подобного рода конфигурациях:
- использовать только internal location для проксирования;
- по возможности запретить передачу пользовательских данных;
- обезопасить адрес проксируемого сервера:
* если количество проксируемых хостов ограниченно (например, у вас S3), то лучше их захардкодить и выбирать при помощи `map` или иным удобным для вас образом;
* если по какой-то причине нет возможности перечислить все возможные хосты для проксирования, его стоит подписать.