Main Tutorials

ModSecurity exclude rules for editing posts and pages in WordPress

wordpress modsecurity

When editing post or page in WordPress, sometime the server’s firewall will block my IP address, and the log showed the following error:

Terminal

lfd: (mod_security) mod_security triggered by xx.xx.xx.xx : 5 in the last 300 secs

The quick fix is to restart the modem or uses a VPN to get a new IP to access the server and remove the firewall rule.

Reason
The WordPress autosave interval will send AJAX post to auto-save a draft or revision of the editing post every 60 seconds, and it hits the ModSecurity rule, 5 in the last 300 secs.

1. WordPress auto-save interval.

1.1 We can increase the auto-save interval in wp-config.php to a longer interval so that it won’t trigger the rule.

wp-config.php

<?php

  define('AUTOSAVE_INTERVAL', 300 ); // seconds, 5 mins
                                     // this means auto save draft every 5 mins
?>

Or we can disable the auto-save or post revisions feature.

wp-config.php

<?php
  // disable the auto-save
  define('WP_POST_REVISIONS', false );
?>

2. Apache + ModSecurity + CSF/LFD

2.1 For Apache + ModSecurity, we can create some ModSecurity exclude rules for specified WordPress actions. The ModSecurity rule id and WordPress’s URI is available at the ModSecurity audit log, modsec_audit.log.

/usr/local/apache/conf/modsec2/whitelist.conf

<LocationMatch "/wp-admin/page.php">
SecRuleRemoveById 300013 300014 300015 300016 300017
</LocationMatch>

<LocationMatch "/wp-admin/post.php">
SecRuleRemoveById 300013 300014 300015 300016 300017
</LocationMatch>

<LocationMatch "/wp-admin/admin-ajax.php">
SecRuleRemoveById 300013 300014 300015 300016 300017
</LocationMatch>

SecRule REQUEST_URI  "/wp-admin/async-upload.php" phase:1,nolog,allow,ctl:ruleEngine=Off
SecRule REQUEST_URI  "/wp-admin/async-upload.php" phase:2,nolog,allow,ctl:ruleEngine=Off

3. Nginx + ModSecurity 3 + OWASP CRS

3.1 For Nginx + ModSecurity 3 and OWASP CRS, there is a file named REQUEST-903.9002-WORDPRESS-EXCLUSION-RULES.conf, it contains a set of ModSecurity rules that should be excluded in WordPress.

By default, the "OWASP ModSecurity 903 WordPress exclusion rules" is disabled, we need to enable it in the crs-setup.conf file manually.

/usr/local/coreruleset-3.2.0/crs-setup.conf

SecAction \
 "id:900130,\
  phase:1,\
  nolog,\
  pass,\
  t:none,\
  setvar:tx.crs_exclusions_wordpress=1" # enable the WordPress exclusion rules

3.2 For those installed the popular Yoast SEO, when save the SEO meta description with some commands or scripts, it will trigger the ModSecurity remote code execution (RCE) rule.

Review the following ModSecurity’s audit log. The variable ARGS:yoast_wpseo_metadesc triggers the RCE rules.

modsec_audit.log

ModSecurity: Warning. Matched "Operator `Rx' with parameter

  ...against variable `ARGS:yoast_wpseo_metadesc' (Value: `In the terminal, we can use `javac -version`
    to check the JDK version, and `java -version` to check  (16 characters omitted)' )

  [severity "2"] [ver "OWASP_CRS/3.2.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"]
  [tag "language-shell"] [tag "platform-unix"] [tag "attack-rce"] [tag "OWASP_CRS"]
  [tag "OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION"] [tag "WASCTC/WASC-31"] [tag "OWASP_TOP_10/A1"]
  [tag "PCI/6.5.2"] [hostname "45.79.28.78"] [uri "/wp-admin/post.php"]
  [unique_id "1593418195"] [ref "o75,40v9413,116"]

In the below example, we exclude the OWASP_CRS rule for the variable ARGS:yoast_wpseo_metadesc.

REQUEST-903.9002-WORDPRESS-EXCLUSION-RULES.conf

# Edit posts and pages
# /wp-admin/post.php, /wp-admin/post.php?t=[timestamp]
# - Themes do not properly escape post_title in HTML, so beware of XSS
#   and be conservative in excluding this parameter.
# - Parameter _wp_http_referer can appear multiple times.
SecRule REQUEST_FILENAME "@endsWith /wp-admin/post.php" \
    "id:9002700,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    chain"
    SecRule ARGS:action "@rx ^(?:edit|editpost)$" \
        "t:none,\
        chain"
        SecRule &ARGS:action "@eq 1" \
            "t:none,\
            ctl:ruleRemoveTargetByTag=attack-sqli;ARGS:post_title,\
            ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:content,\
            ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:yoast_wpseo_metadesc,\
            ctl:ruleRemoveById=920272,\
            ctl:ruleRemoveById=921180"

Hosting Provider for help
If you are not familiar with the ModSecurity rule exclusion, please contact your hosting provider for help.

References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
8 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Hai
2 years ago

I try fobbiden wp-admin to wordpress 5.8.4

christian zagarskas
4 years ago

This post was helpful even in 2019, it solved 1/2 of our 403 Forbidden error in WordPress, however, we had an additional step to take: we needed to DISABLE “mod_evasive” – as this Apache module was blocking admin ajax from multiple runs.

jwillberg
7 years ago

Good wordpress modsecurity rules from Malware Experts – https://malware.expert

Sameera
10 years ago

My Site hosdted on SHARED SERVER.

then what happen for me? hwo can i change mod security ? like this

Dan
9 years ago
Reply to  Sameera

You can’t change mod_security on a shared server – but you can go ahead with the other tips (turn off auto save, or change its interval).

Jamez
10 years ago

Thanks! This is exactly what was happening on my server as well! Thanks for the insight to see that it was WordPress auto-save as well providing solutions to fix it.

Phids
11 years ago

Thank you for this. This same problem has been happening to me lately while I am in WordPress, and I could not figure out why. This sheds some light on the matter.