У меня есть веб-сайт, который использует jQuery ajax $.post
для сохранения данных HTML в скрипт PHP.
Данные для $.post
представляют собой сериализованные данные формы текстовой области (где пользователь редактирует CSS, JavaScript и HTML).
Все работает хорошо, пока я не включу основной набор правил OWASP ModSecurity V3.0.
В журнале Apache я вижу такие ошибки, как NoScript XSS InjectionChecker: HTML Injection
, XSS Filter - Category 4: Javascript URI Vector
, HTTP Response Splitting Attack
, Inbound Anomaly Score Exceeded
и meta found within ARGS:
.
В наборе основных правил OWASP ModSecurity V3.0, если я отключу rules/REQUEST-921-PROTOCOL-ATTACK.conf
и rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf
, то все будет работать.
Похоже, что ModSecurity предпочитает формат JSON, но как мне сохранить этот необработанный код html, css и javascript из редактора на сервер? В целях безопасности я хотел бы оставить эти правила включенными.
В наборе основных правил OWASP ModSecurity V3.0, если я отключу
правило отключать не нужно — достаточно создать исключение. Это «ложное срабатывание», к сожалению, в случае проверки XSS оно встречается немного чаще.
Вы не упомянули совпавшие правила и аргументы, а также полную строку журнала, поэтому я предлагаю вам прочитать соответствующую документацию:
https://coreruleset.org/docs/concepts/false_positives_tuning/
Похоже, ModSecurity предпочитает формат JSON.
Нет, ModSecurity (и любые типы наборов правил) не предпочитает какую-либо структуру данных. Он просто знает формат JSON и знает, как с ним обращаться. Это ложное срабатывание также будет ложным срабатыванием в случае формы с кодом www-urlencode.
Принятый ответ технически верен, однако, по моему мнению, создание исключений со временем сделает правила ModSecurity бесполезными.
Для разработчиков на одном арендаторе/выделенном сервере, на котором выполняется собственное приложение, лучше всего разработать методы, позволяющие избежать срабатывания правил ModSecurity.
Основываясь на этом вопросе и принятом ответе, я решил преобразовать все сомнительные данные в base64, а затем декодировать их на сервере.
//javascript
function html4post(str) {
var bytes = new TextEncoder().encode(str);
const binString = Array.from(bytes, (byte) =>
String.fromCodePoint(byte),
).join("");
return encodeURIComponent(btoa(binString));
}
console.info(html4post('<meta name = "distribution" content = "global"><p>I can now post this html via AJAX with ModSecurity rules enabled</p>'));
// PG1ldGEgbmFtZT0iZGlzdHJpYnV0aW9uIiBjb250ZW50PSJnbG9iYWwiPjxwPkkgY2FuIG5vdyBwb3N0IHRoaXMgaHRtbCB2aWEgQUpBWCB3aXRoIE1vZFNlY3VyaXR5IHJ1bGVzIGVuYWJsZWQ8L3A%2B
//PHP
$html = $_POST['html'];
echo base64_decode($html);
// <meta name = "distribution" content = "global"><p>I can now post this html via AJAX with ModSecurity rules enabled</p>