Comments 18
А зачем вы используете для валидации Origin директиву if если есть более "правильный" способ — map?
Именно поэтому я и начал с валидации регулярок в if. В будущем планирую добавить проверки для map (там будут примерно те же проблемы) и возможно добавить какую-то рекомендательную проверку по переписыванию if на map. Тут есть над чем подумать:)
Чаще всего проблема с map, в том, что он должен идти где-то в http локейшионе и получается, что map слегка оторван от конкретного виртуал хоста.
if'ы же можно поместить внутрь server/location контекстов и поэтому с ними слегка проще работать. Особенно если виртуалхосты имеют тенденцию мигрировать между серверами.
— улучшить работу с переменными, добавить новых директив которые могут их предоставлять. Например, сейчас нет поддержки server_name :(
— продолжить улучшать работу с регулярками, что мы можно было делать более хитрые проверки. Кстати, я его обернул в самостоятельное приложение (бывает полезно, когда нужно быстренько проверить регулярочку): Regex Ninja
— разобраться с разными стьюпидами и написать хорошую документацию
Ну и, конечно же, написать новых проверок:)
Например, для Open Redirect'ов в реврайтах:
location /a {
rewrite (.*)$ https://example.com$1 permanent;
}
location /b {
rewrite ^/(.*)$ https://example.com$1 permanent;
}
Экплуатация:
$ http -h http://localhost/a%0a.evil.com
HTTP/1.1 301 Moved Permanently
Connection: keep-alive
Content-Length: 185
Content-Type: text/html
Date: Sat, 29 Apr 2017 10:07:21 GMT
Location: https://example.com.evil.com
Server: nginx/1.13.0
$ http -h http://localhost/b.evil.com
HTTP/1.1 301 Moved Permanently
Connection: keep-alive
Content-Length: 185
Content-Type: text/html
Date: Sat, 29 Apr 2017 10:07:40 GMT
Location: https://example.comb.evil.com
Server: nginx/1.13.0
Спасибо за очень интересный инструмент, который поможет закрыть много дырок в конфигах.
Хочу заметить, что часть дырок можно избежать заранее, если стараться по максимуму использовать map и избегать if (как завещал Игорь Сысоев).
Например, это хорошо подходит для http_origin. Вариант с регуляркой в if
if ($http_origin ~* ((^https://www\.yandex\.ru)|(^https://ya\.ru)/)) {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
}
можно переделать на более безопасный вариант с map:
map $http_origin $ok_origin {
"https://www.yandex.ru" "1";
"https://ya.ru" "1";
}
if ($ok_origin) {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
}
Получается более безопасная, читабельная и масштабируемая конфигурация.
Хотя, стоит признать, что в вашем примере была просто проблема с регуляркой — нужно было просто добавить $ в конец.
Ещё хочу добавить — проблема с переопределением вышестоящих настроек встречается не только у add_header, но и у error_page.
Ещё хочу добавить — проблема с переопределением вышестоящих настроек встречается не только у add_header, но и у error_page.
А так же у proxy_set_header. Думаю, что список таких директив можно продолжить.
А давайте продолжим список! Главное, что бы это могло привести к проблемам безопасности.
К примеру, с proxy_set_header
я могу придумать кейс в котором это может стать проблемой (хоть пока и не встречал). А вот не сознательное переопределение error_page
не выглядит чем-то серьезным.
Скажу сразу, что создание тулзы, которая ищет косяки в конфигах, это крутое занятие и я уважаю эту работу.
Ну и… висела ваша статья перез глазами у меня несколько дней. Вроде и придраться как-бы не к чему, так как привые конфиги отбраковываются, а утилитка показывает как все плохо.
И вот сегодня ягодка созрела: зачем вообще писать такие кривые конфиги? Ваша тулза будет хороша начинающим юзерам, которые конфигурируют nginx. Если же человек руку набил на нем и набил руку на регулярках, то пользы как бы и нет.
Вообще весь смысл статьи в том, что надо правильно писать регулярки, или не писать из вовсе, если не умеешь (например отличная альтернатива с map).
location ~ /v1/((?<action>[^.]*)\.json)?$ {
— вообще режет глаз.
v1/((?<action>[^\\w]*)\.json)?
— верный вариант. Если там встречаются {|_ и т.д., то надо добавить их в "словарик" или просто оторвать яйца тому, что апи разрабывает, так как он ничерта не понимает в том, как надо разрабатывать. Так что этот пример из неоткуда, и в нормальной жизни (и в компании яндекс, надеюсь), он не может случится.
try_files $uri $uri/ /index.php?q=$uri;
— не видел ни одного гайда для нубов, где бы использовали $uri, вместо $request_uri в этой связке.
Ваши примеры реврайтов из comment_10197332…
location /a { return 302 https://example.com$request_uri; }
правильный вариант, и рабочий пример https://0x10k.com/a%0A.evil.com
, и оффиц. сайт об этом трындит.
Я все к тому, что у вас очень уж простые случаи, ничего серьезного. Было бы больше ценности статьи (и меньше маркетинга пиара), если бы вы показали серьезные ляпы и их детект.
Хотелось бы только узнать на сколько она применима в случае если у меня на серверах стоит какая-нибудь панель управления хостингом типа ИСП\Адженти\Весты\Плеска?
Честно говоря, ничего не могу сказать по этому поводу. Я не большой сторонник панелей управления, поэтому опыта работы с ними крайне мало. Быть может, кто-то с большим опытом подскажет как правильно сделать интеграцию, какие существуют подводные камни и вот это все. А может и сделает это самостоятельно ;-)
==================== Results ===================
No issues found.
==================== Summary ===================
Total issues:
Unspecified: 0
Low: 0
Medium: 0
High: 0
что я делаю не так? :)
Gixy — open source от Яндекса, который сделает конфигурирование Nginx безопасным