Гюльчатай закрой личико или базовая защита веб-морды 🙈
#Безопасность
На днях я писал, что плотно заняться безопасностью можно и нужно на втором этапе жизни проекта, когда уже пошел поток клиентов, но есть вещи, которые можно сделать сразу на этапе запуска.
Прежде всего начнем с тюнинга Nginx (у вас же он, правда?)
Про самое очевидное: сразу забудьте про то, что такое сайт без SSL, купите хоть самый дешевый или сделайте бесплатный через
let's encrypt Все запросы, что прилетают на http сразу отправляйте редиректом на https. Как вариант запись эта может выглядеть так:
return 301
https://$host$request_uri;
А чтобы браузер в последствии всегда автоматически переходил на https добавьте заголовок HSTS
add_header Strict-Transport-Security 'max-age=31536000';
Помимо этого заголовка неплохо было бы включить и встроенные механизмы защиты браузера
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
add_header X-Frame-Options "sameorigin";
Старайтесь использовать актуальные настройки ssl_protocols и ssl_ciphers (их, как и вообще весь ssl конфиг можно сгенерить на
мозиле)
Проверить уровень настройки SSL можно
на ssllabs и там же посмотреть рекомендации по улучшению
Я тебя не знаю, уходи!
Закройте обращения по ip или любому непонятному адресу к вашему приложению. Для этого просто последним в sites-enabled у вас должен быть конфиг default_server
server {
listen 80 default_server;
return 444;
}
Ответ 444, сразу же скидывает соединение не возвращая никакого тела, что позволит помимо мусорного трафика, также снизить и нагрузку. (Для https подключения можно сделать похожий конфиг)
С базовыми вещами по nginx разобрались, теперь возьмем уровень чуть повыше.
Любые запросы к своему API пропускайте через
модуль лимитов nginx и отдавайте код 429. После чего обязательно настройте мониторинг на отлов ответов с этим кодом. Это даст вам возможность оперативно поймать потенциальный брутфорс или кривые интеграции, когда сторонний разработчик запустил while (true) и ушел пить кофе.
Иногда нам может потребоваться включить для тех или иных обращений CORS, чтобы на других доменах нашего или интеграционного проекта разработчики могли сделать ajax запросы без прокидывания через свой backend. В этом случае я часто вижу на разных проектах ребята не долго думая делают:
Access-Control-Allow-Origin: *
Так как данный заголовок поддерживает, либо доступ с любого домена, либо только с одного, без перечислений. Решается проблема, либо через
map в nginx с установкой нужной переменной (сравниваем желаемый хост с http_origin) и последующей передачей через add_header того же домена в заголовке
Access-Control-Allow-Origin либо проще это контролировать через конфиги приложения, как по мне.
Перебейте заголовок Server, который по дефолту отдает Nginx. Сделать это можно либо через server_tokens off; (который при этом все равно будет показывать, что используется nginx, но без версии), либо через бекенд часть приложения, заменив его на то, что вашей душе угодно.
Помимо этого проверьте что вообще за заголовки отдаются вашим приложением (всякие Powered-By и прочие, тоже надо погасить. Чем меньше злоумышленнику на входе будет информации, тем лучше)
Горшочек с медом
Техника honeypot не новая, но почему-то многие ей пренебрегают. Заключается она в том, чтобы добавить стандартные для всех сканеров или ручных тестеров роуты при попадании на которые вы получите тем или иным способом оповещение и включите более детальную аналитику по запросам злоумышленника.
Допустим вы можете оставить "открытым" cgi-bin или pma (phpmyadmin) или любой другой дефолтный url, да хоть .git (главное чтобы реального git'а там не было:)) и как только получаете туда обращение, значит кто-то проверяет пути, которые обычный человек точно не будет смотреть, а это повод задуматься.
На этом, пожалуй, пока что всё. Конечно подход должен быть более комплексным, как с точки зрения защиты доступов к серверам (vpn, ssh-ключи, iptables и т.д.), анализ трафика и прочее, но это уже другая история