WordPress 404 Error when updating or posting
It’s time for a new icon! This is my official “Sherlock Holmes deerstalker hat” icon, which is reserved for when I have to do some strange detective work in order to solve a baffling problem. Looking at it again, it looks a bit like a snail, but trust me – it’s a deerstalker!
Since moving from a free blog hosted on WordPress.com to my self-hosted WordPress blog, everything has been going very smoothly. I have had more control, and been able to insert some Google Ads into popular posts, which should just about cover my hosting costs. Things were going swimmingly until I decided to update one of my posts and immediately got a 404 Not Found error message. Adding new posts seemed to be fine and, to add to the conundrum, some posts would let me update.
A lot of the forums I read indicated that this was a problem with mod_security rather than WordPress itself. So what is mod_security? It’s a web application firewall that works either embedded into Apache (the webserver), or as a reverse proxy. Its job is to filter out attempts to compromise your site, such as cross-site scripting or SQL injection attacks. This is a good thing.
The WordPress issue arises, though, because the mod_security rules run on POST, i.e. when you click the Update button. If your blog post contains text or characters that violate the mod_security rules, then you’ll get a 404 Not Found error page. Fear not, for there are ways to get around this. Unfortunately, to continue the Sherlock Holmes analogy, they’re not “elementary, my dear Watson”.
The Ideal Method
The first way to prevent this error is to stop mod_security from scanning POST commands. If your server, or hosting provider, is running mod_security 2.5 or above, then skip this section. In older versions of mod_security you can override the settings using a file called .htaccess which is in the root directory of your blog. Simply add the line:
to the .htaccess file, and all should be well. If you’re running a newer version of mod_security then you can exclude some files in the wp-admin directory from the filter. You will need access to the system files on your web server, or your friendly hosting provider might add these rules for you.
Add the following rules to the /usr/local/apache/conf/modsec2/whitelist.conf file:
<LocationMatch "/wp-admin/post.php"> SecRuleRemoveById 300015 300016 300017 </LocationMatch> <LocationMatch "/wp-admin/admin-ajax.php"> SecRuleRemoveById 300015 300016 300017 </LocationMatch> <LocationMatch "/wp-admin/page.php"> SecRuleRemoveById 300015 300016 300017 </LocationMatch>
Again, this will solve the problem. However, what if you don’t have access to your server or can’t get your hosting provider to add the changes?
If you can’t do the above fix, then the only option is to modify the content of your blog post, so that it doesn’t look like a potential attack.
The posts I wanted to update contained phrases like “select restore from backup”, “delete everything from…”. If you’re savvy with SQL, you’ll know that they look like SQL commands. It seemed that mod_security was being a little over-zealous and thought that I was trying to run a SQL injection attack! Therefore I was presented with the 404 page and prevented from proceeding.
You can work around this. Avoid using words like “select” or “delete” particularly if they’re followed by the word “from”. If you must use them, then disguise the words by substituting letters for their HTML codes using this table. So switch to HTML view in the WordPress editor and change occurrences of the word “select” to “select”, “delete” to “delete” and so on.
It’s not pretty, but it works. Remember as well that if you switch back to Visual view, then your HTML codes will be lost! It’s good that we can workaround this problem, but I wonder how long it will be before mod_security is updated to prevent the use of ASCII codes in this way.