WordPress display 404 after updating post ?
This bug is annoying me a very long time. In WordPress, after updating or saving a new post or existing post, sometime, it will redirect to a 404 page, and this is happening randomly, no idea to identify what is the root caused.
After read few similar posts – this and this, I find out this is due to the
mod_security filtering installed on Apache – If a post contains certain pre-defined dangerous “word combination” like “exec” or “SQL inject commands” like “insert”, the post will be filtered and WordPress just return a 404 page.
Here’s my solution :
1. Disabled mod_security
Many suggest disable the
mod_security module by putting following rules in
#... <IfModule mod_security.c> SecFilterEngine Off SecFilterPost Off </IfModule> <IfModule mod_env.c> SetEnv MODSEC_ENABLE Off PassEnv MODSEC_ENABLE </IfModule> #...
Unfortunately, the above solution is not working for me. Digging into
httpd.conf, find out that my Apache is using latest
mod_secuirty2, then I try following rule again :
#... <IfModule mod_sec2.c> SecFilterEngine Off SecFilterPost Off </IfModule> #...
But, not working either. You can try your luck :)
2. Bypass mod_security Rules
After Googling, find out that “
mod_security 2” is no longer support
.htaccess overrides, you need to bypass those rules via config file manually.
To fix it, find ‘
/usr/local/apache/conf/modsec2/exclude.conf, and append below content at the beginning of the file.
<locationmatch "/wp-admin/post.php"> SecRuleRemoveById 300013 SecRuleRemoveById 300015 SecRuleRemoveById 300016 SecRuleRemoveById 300017 </locationmatch>
/wp-admin/post.php to update the post, now,
mod_security will bypass the rules – 300013, 300015, 300016, 300017. Restart Apache server. Update the previous problem-post again, it’s now updated successfully, no more redirect to 404 page, it works!
You can also put the ignore rules in
3. Which Rule Id To Filter?
Wait, how do we know which rules to filter? You can find this information in
modsec_audit.log – All filtered or intercepted URLs will be logged in this file.
# your problem-post URL here... --2950df1e-H-- Message: Access denied with code 500 (phase 2). Pattern match "((select|grant|delete|insert|drop|alter|replace|truncate|update|create|rename|describe)[[:space:]]+[A-Z|a-z|0-9|\ \*| |\\,]+[[:space:]]+(from|into|table|database|index|view)[[:space:]]+ [A-Z|a-z|0-9|\\*| |\\,]|UNION SELECT.*\\'.*\\'.*,[0-9].*INTO.*FROM)" at REQUEST_BODY. [file "/usr/local/apache/conf/modsec2.user.conf"] [line "345"] [id "300013"] [rev "1"] [msg "Generic SQL injection protection"] [severity "CRITICAL"] Action: Intercepted (phase 2) #...
Filter by URL or your IP, to identify which rules are triggered when you update the post. In the above case, the post’s URL hits rule “300013“, and you need to bypass this rule id in order to update the post.
mod_securitylogs may have logged the error messages to somewhere else, do consult your hosting provider for detail.