Я пытаюсь устранить проблему с ModSecurity. Использование ModSecurity 2.9.2 на Apache 2.4.33. Я максимально упростил ситуацию, но наткнулся на стену. Я работаю в конфигурации виртуального хоста. Вот что я пытаюсь сделать:
SecAction "pass,setenv:TESTPAGE=1,nolog,id:10001001"
Header always set X-Debug "IsTest" env=TESTPAGE
Без других правил это должен всегда устанавливайте заголовок X-Debug, но это не так. Чтобы понять, почему, сначала я удалил SecAction и сделал следующее:
RewriteRule .* - [E=TESTPAGE]
Header always set X-Debug "IsTest" env=TESTPAGE
Разумеется, в этом случае заголовок был установлен, поэтому я знаю, что заголовки работают, и переменные среды могут быть установлены / проверены. Затем я попробовал это:
SecAction "deny,status:503,setenv:TESTPAGE=1,nolog,id:10001001"
И действительно, меня заблокировали с помощью http-кода 503, поэтому я знаю, что SecAction обрабатывается. Учитывая эти две вещи, единственная возможность состоит в том, что ModSec не может установить переменную среды должным образом, но я не знаю какой-либо причины, почему это должно быть так.
По какой-то причине настройка «запретить» больше не блокирует обработку страницы. Таким образом, я все еще получаю набор кодов состояния, или если я сохраняю «deny», но удаляю директиву «status», я получаю код 403, который, как я полагаю, используется по умолчанию для «deny», но сама страница все равно загружается. Не уверен, имеет ли это та же причина, что и неустановленная переменная среды.
Оказывается, это произошло из-за внутренней перезаписи с помощью mod_rewrite из-за запуска этого в контексте приложения Symfony2, которое перезаписывает все запросы к своему контроллеру app.php. То же самое произойдет в CMS, такой как wordpress, которая перезаписывает все в index.php, или в других схемах предварительной настройки URL-адресов, которые перезаписывают URL-адреса внутри. (Обратите внимание, это не проблема с перенаправлениями браузера, поскольку они приводят к полностью новому запросу, только с внутренней перезаписью.) В основном после завершения вашей последней перезаписи логика apache htaccess и конфигурации запускается снова, и при этом запуске что установлены ваши окончательные переменные среды и тому подобное. Поэтому, если переменная была установлена до перезаписи, она не будет доступна после (например, когда я пытаюсь установить заголовок в вопросе здесь).
Хотя эти две строки в вопросе смежные ...
SecAction "pass,setenv:TESTPAGE=1,nolog,id:10001001"
Header always set X-Debug "IsTest" env=TESTPAGE
Первая строка выполняется во время фазы тела запроса (modsec Phase 2) по умолчанию, поскольку я не указал фазу. Перезапись в app.php (из-за того, что правило .htaccess не показано) происходит позже. И поэтому, когда установлен заголовок, переменной больше нет.
Однако все переменные перед перезаписью по-прежнему доступны с префиксом redirect_. Чтобы исправить это, мне нужно написать вот так:
SecAction "pass,setenv:TESTPAGE=1,nolog,id:10001001"
Header always set X-Debug "IsTest" env=REDIRECT_TESTPAGE
Или, если я не уверен, будет ли перенаправлен запрос, я могу использовать обе версии:
SecAction "pass,setenv:TESTPAGE=1,nolog,id:10001001"
Header always set X-Debug "IsTest" env=TESTPAGE
Header always set X-Debug "IsTest" env=REDIRECT_TESTPAGE
(Может быть способ их объединить; не уверен, можно ли использовать логику ИЛИ в операторах apache 'env'; прокомментируйте, если да!)
Редактировать: Что касается запрета, который больше не работает, то это тоже в некотором смысле связано с перенаправлением. Mod Security по умолчанию выдавал ошибку 500, но страница ошибок 500 по умолчанию, 500.shtml, не существует. Таким образом, платформа перехватывала этот запрос и отправляла его обратно в app.php, который затем просматривал URL-адрес запроса и продолжал загружать первоначально запрошенную страницу, несмотря на ошибку. Если настроенный ErrorDocument существует, deny работает правильно и этот документ отображается.