WAF- OWASP Firewall

  • Hallo Leute,


    ich hoffe es kann mir jemand zu meinem Problem weiterhelfen.

    Mir wird im Wordpress-Admin Bereich die Funktion admin-ajax.php von der Firewall (OWASP) jedes mal beim triggern blockiert. Weiß jemand mit welchen Schritten man die [uri "/wp-admin/admin-ajax.php"] auf die White-List setzen kann?


    PS: Nutze einen Root-Server mit Open Litespeed.


    LG

  • Man kann natürlich die admin-ajax url komplett whitelisten, aber dann bohrst du natürlich diesbezüglich ein Loch in die WAF und alle Angriffe über diese URL werden durchgelassen.

    Sinnvollerer wäre es m.E. rauszufinden welche Regel(n) denn nun darüber eigentlich getriggert wurde und nur diese dann einzuschränken.

    Leider ist aus deinem Screenshot nicht ersichtlich welche Regel das ist. (Oder ich habe es übersehen)


    Wenn du aber tatsächlich alles über admin-ajax.php zulassen willst willst, dann geht das z.B. (in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf) mit:

    Code
    SecRule REQUEST_URI "@beginsWith /DEINWORDPRESSPFAD/wp-admin/admin-ajax.php" "id:...,phase:1,allow,nolog,ctl:ruleEngine=off"

    (Noch eine eindeutige id einfügen)

    Phase1 setzt schon recht hoch an. Evtl. langt weniger.

    Alles über admin-ajax.php ist dann aber ungeschützt.


    Falls du es nicht so rigoros machen möchtest, müsstest du halt rausfinden auf welchem Weg die false positives zustande kommen.

    Evtl. hilft dir das dabei: ;)

    ModSecurity Tuning


    EDIT:

    Für Wordpress würde ich auch noch die Ausnahmen hinzufügen die in den OWASP-rules selbst schon enthalten sind mit:

    Code
    SecRule REQUEST_URI "@beginsWith /DEINWORDPRESSPFAD/" setvar:tx.crs_exclusions_wordpress=1
  • Hab gerade noch "zwischen den Zeilen" deines Screenshots gesehen, dass es sich (zumindest in diesem Fall) um 941310 handelt, also eine der XSS Attacken.

    Die könntest du alle so ausschließen, ohne gleich alles über ajax.php aufzumachen:

    Code
    SecRule REQUEST_URI "@beginsWith /DEINWORDPRESSPFAD/" "id:...,phase:2,pass,nolog,t:none, \
            ctl:ruleRemoveByTag=OWASP_CRS/WEB_ATTACK/XSS"


    Falls du als einziger Zugriff auf dein WP-Backend hast, oder alle die das haben zuverlässig sind, dann kannst du auch generell alle POST-requests außer denen über die Kommentarfunktion zulassen (Die Angriffe auf WP erfolgen ja entweder über GET oder über die die Comments) :

    Code
    SecRule REQUEST_URI "@beginsWith /DEINWORDPRESSPFAD/" "id:...,phase:2,allow,nolog,t:none,chain"
    SecRule REQUEST_URI "!@beginsWith /DEINWORDPRESSPFAD/wp-comments-post.php" "chain"
    SeCRule REQUEST_METHOD "POST" "ctl:ruleEngine=off"

    So mache ich das bei meinen WP-Installationen und das funktioniert recht gut.

  • Vielen Dank für deinen informativen Input!


    Ich hätte mehrere Versuche unternommen, aber leider klappt es einfach nicht. Es gibt zwei ID's die immer wieder auftauchen, sobald ich meinen Pagebuilder versuche zu nutzen:


    Code
    ModSecurity: Access denied with code 302 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `5' ) [file "/etc/modsecurity.d/owasp-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "80"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "2"] [ver "OWASP_CRS/3.3.2"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [hostname "WEBLINK"] [uri "/wp-admin/admin-ajax.php"] [unique_id "1638470531"] [ref ""]
    
    ModSecurity: Warning. Matched "Operator `Rx' with parameter `\xbc[^\xbe>]*[\xbe>]|<[^\xbe]*\xbe' against variable `ARGS:params[content]' (Value: `TEXT</strong> u (1532 characters omitted)' ) [file "/etc/modsecurity.d/owasp-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf"] [line "527"] [id "941310"] [rev ""] [msg "US-ASCII Malformed Encoding XSS Filter - Attack Detected"] [data "Matched Data: \xbcdTEXTn ARGS:params[content]: TEXT (1355 characters omitted)"] [severity "2"] [ver "OWASP_CRS/3.3.2"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-tomcat"] [tag "attack-xss"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/152/242"] [hostname "WEBLINK"] [uri "/wp-admin/admin-ajax.php"] [unique_id "1638470531"] [ref "o33,47v2926,1458t:urlDecodeUni,t:lowercase,t:urlDecode,t:htmlEntityDecode,t:jsDecode"]
    ---IpYsrMLa---H--
    content-type: text/html
    location: /RUNCLOUD-MODSEC-WAF-BLOCKED


    Dazu habe ich deinen Rat befolgt und das bestehende File (das vorher REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example hieß) mit folgenden Lines ergänzt:

    Filename: REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf

    Code
    SecRule REQUEST_URI "@endsWith /wp-admin/admin-ajax.php" "id:941310,phase:2,pass,nolog,t:none, \
            ctl:ruleRemoveByTag=OWASP_CRS/WEB_ATTACK/XSS"
    SecRule REQUEST_URI "@endsWith /wp-admin/admin-ajax.php" "id:949110,phase:2,pass,nolog,t:none, \
            ctl:ruleRemoveByTag=OWASP_CRS/WEB_ATTACK/XSS"

    Ich habe dazu das @endsWith Tag hergenommen, da die Regel letztendlich für jede Webapp, die von mir angelegt wurde, greifen sollte.


    Auch die Idee mit generell POST find ich klasse!

    Hat aber bedauerlicherweise hat die Regel auch nicht gegriffen.

    Code
    SecRule REQUEST_URI "@beginsWith /home/runcloud/webapps/APNAME/" "id:941310,phase:2,allow,nolog,t:none,chain"
    SecRule REQUEST_URI "!@beginsWith /home/runcloud/webapps/APNAME/wp-comments-post.php" "chain"
    SeCRule REQUEST_METHOD "POST" "ctl:ruleEngine=off"
    SecRule REQUEST_URI "@beginsWith /APNAME/" "id:949110,phase:2,allow,nolog,t:none,chain"
    SecRule REQUEST_URI "!@beginsWith /APNAME/wp-comments-post.php" "chain"
    SeCRule REQUEST_METHOD "POST" "ctl:ruleEngine=off"


    Kann das sein, dass ich die geänderte conf.example -> .conf, irgendwo in einer anderen .conf Datei einbinden muss?

  • Also zunächst mal:

    Als id in deine Regel darf nicht die schon vorhandene rule-id rein! Das muss eine eigene, eindeutige, von dir vergebene Nummer sein. (Fang mit 1000 aufsteigend an)

    Doppelte ids in den Regeln sind nicht erlaubt. Eigentlich sollte das angemosert worden sein, was mich zu der Frage bringt:


    Hast du die Config auch neu eingelesen mit "sudo service apache2 restart"?


    Die Datei REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf sollte schon über die OWAS-Config eingebunden sein.

    (Bei mir liegt die in /usr/share/modsecurity-crs/owasp-crs.load)

    Falls nicht muss die Datei tatsächlich noch eingebunden werden in /etc/apache2/mods-available/security2.conf

    mit Include /etc/modsecurity/rules/*.conf


    EDIT:

    Ob das mit @endsWith funktioniert weiß ich nicht, weil ich momentan nicht sicher bin, ob in REQUEST_URI noch die Parameter mit dabei sind oder nicht. Müsste man mal in der Doku nachsehen.

  • yes!!, hat funktioniert bestens

    Prima. Freut mich. :)

    Was hältst du von der Variante die Regeln generell zu entfernen, wenn man der Meinung ist, dass die ein False-Positiv auslösen?

    Kann man durchaus machen. Habe ich auch für einige Regeln so gemacht. (Das muss dann allerdings in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf)

    Das ist immer Abwägungssache, wie weit man die Firewall zurückfahren will.

  • ah perfekt, gut zu wissen fürs nächste Mal, danke!


    "weit man die Firewall zurückfahren will."- hätt ich noch ne Verstädnissfrage:


    Würde diese Ausnahme nicht gleich alle Regeln mit dem Tag WEB_ATTACK/XSS aufheben?

    Code
    SecRule REQUEST_URI "@beginsWith /DEINWORDPRESSPFAD/" "id:...,phase:2,pass,nolog,t:none, \
    
    ctl:ruleRemoveByTag=OWASP_CRS/WEB_ATTACK/XSS"


    Da wäre dann doch der Ansatz etwas besser, dass man sagt, man pickt sich genau die eine Regel raus, die die Störung verursacht. Bin mir aber auch nicht sicher ob man das Filtern kann wie bei den anderen Beispielen mit @beginsWith oder @endsWith.

  • Würde diese Ausnahme nicht gleich alle Regeln mit dem Tag WEB_ATTACK/XSS aufheben?

    Ja, genau.

    Da wäre dann doch der Ansatz etwas besser, dass man sagt, man pickt sich genau die eine Regel raus, die die Störung verursacht.

    Wenn das bei dir ausreicht, dann ist das in der Tat die bessere Lösung.

    Einfach ruleRemoveByTag=TAG durch ruleRemoveById=ID ersetzen.