0

I have a website that uses jQuery ajax $.post to save html data to a PHP script.

The data for $.post is serialized textarea form data (where the user edits css, javascript & html).

All works well until I enable OWASP ModSecurity Core Rule Set V3.0.

In my apache log I see errors like NoScript XSS InjectionChecker: HTML Injection, XSS Filter - Category 4: Javascript URI Vector, HTTP Response Splitting Attack, Inbound Anomaly Score Exceeded & meta found within ARGS:

In OWASP ModSecurity Core Rule Set V3.0 if I disable rules/REQUEST-921-PROTOCOL-ATTACK.conf & rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf then everything is working.

It looks like ModSecurity prefers JSON like format, but how can I save these raw html, css & javascript code from the editor to the server? For security, I would like to keep these rules turned on.

2 Answers 2

0

In OWASP ModSecurity Core Rule Set V3.0 if I disable

you don't need to disable the rule - it's enough to create an exclusion. This is a "false positive" hit, unfortunately it's a bit more frequent in case of XSS check.

You didn't mention the matched rule(s) and argument(s), nor the complete log line, so I suggest you to read the relevant documentation:

https://coreruleset.org/docs/concepts/false_positives_tuning/

It looks like ModSecurity prefers JSON like format

No, ModSecurity (and any types of rule set) does not prefer any data structure. It just knows the JSON format and knows how to handle it. This false positive would be false positive in case of www-urlencoded form too.

0

The accepted answer is technically correct, however in my opinion creating exclusions overtime will render the ModSecurity rules useless.

For developers on single tenant/dedicated server running custom application, it is best to develop methods to avoid triggering ModSecurity rules.

Based on this question and the accepted answer, I have adopted to convert all questionable data to base64 and then decode it in the server.

//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.log(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>

Not the answer you're looking for? Browse other questions tagged or ask your own question.