I've been through the “seven layers of the candy cane forest” on this one… :)
Our plugin receives data via a POST request. On a particular site that has our plugin installed, we observed odd behavior. In one specific scenario, the POST requests were erroneously generating a 404 (Not Found) error.
I started very broad and narrowed the problem down bit by bit by bit until I was left with the following reproduction scenario. The puzzling error occurs for:
- Any “POST" request
- to any URL at or below /
- that provides x-www-form-urlencoded data
- with
or
("or" followed by a space; not case sensitive) followed immediately by a number anywhere in the submitted data (not just field values) (e.g.an ARM or 30-year fixed-rate mortgage
)
I checked the other installed plugins. Nothing. I checked the templates. Nada. I checked a few other sites with our plugin installed but still couldn't reproduce the bug.
From everything I can tell, this is an incredibly specific problem on the single site in question. Due to the reproduction scenario, I'm guessing it's due to some overambitious anti-SQL injection code.
Is there any code present by default in Wordpress that could be causing this problem? My guess is that this problem is to blame on something else (e.g. a firewall, a .htaccess
rule, etc), but I thought I'd check with the experts! :)
Update:
We've also observed this issue with a post data in the format "[operator] having [string]", such as < having x
, or having y
, and having z
, etc. Given that HAVING
is an SQL keyword, I suspect this is further evidence of a poorly configured security tool. Note that these various observations were made on different servers, so it's not just something funky on this single server. I guess multiple servers could be misconfigured/have strict security protocols in place, though...
Another Update:
I've run into this issue again. This time, I've simplified the problem POST payload to simply the string <strong>
. Any POSTed data that includes this string (in-line with the other conditions above) generates a 404.
I've been through the “seven layers of the candy cane forest” on this one… :)
Our plugin receives data via a POST request. On a particular site that has our plugin installed, we observed odd behavior. In one specific scenario, the POST requests were erroneously generating a 404 (Not Found) error.
I started very broad and narrowed the problem down bit by bit by bit until I was left with the following reproduction scenario. The puzzling error occurs for:
- Any “POST" request
- to any URL at or below http://example/wp-content/
- that provides x-www-form-urlencoded data
- with
or
("or" followed by a space; not case sensitive) followed immediately by a number anywhere in the submitted data (not just field values) (e.g.an ARM or 30-year fixed-rate mortgage
)
I checked the other installed plugins. Nothing. I checked the templates. Nada. I checked a few other sites with our plugin installed but still couldn't reproduce the bug.
From everything I can tell, this is an incredibly specific problem on the single site in question. Due to the reproduction scenario, I'm guessing it's due to some overambitious anti-SQL injection code.
Is there any code present by default in Wordpress that could be causing this problem? My guess is that this problem is to blame on something else (e.g. a firewall, a .htaccess
rule, etc), but I thought I'd check with the experts! :)
Update:
We've also observed this issue with a post data in the format "[operator] having [string]", such as < having x
, or having y
, and having z
, etc. Given that HAVING
is an SQL keyword, I suspect this is further evidence of a poorly configured security tool. Note that these various observations were made on different servers, so it's not just something funky on this single server. I guess multiple servers could be misconfigured/have strict security protocols in place, though...
Another Update:
I've run into this issue again. This time, I've simplified the problem POST payload to simply the string <strong>
. Any POSTed data that includes this string (in-line with the other conditions above) generates a 404.
- Look how lonely my question is. So sad. – rinogo Commented Feb 10, 2016 at 23:25
- 5 This sounds like something mod_security might do. There's nothing in WordPress that would do this, aside from accidentally generating a 404 due to POSTing query vars to a WordPress URL. – Milo Commented Feb 15, 2016 at 19:18
- 1 What's the name of the form field you're submitting? It may be a reserved term which will cause a 404 if its value affects the main query. – John Blackbourn Commented Mar 11, 2016 at 12:51
- That's the interesting thing - I can even get the error to occur if the string in question appears in a form name! Given all of this weirdness, I'm leaning strongly toward this not being due to Wordpress. – rinogo Commented Mar 12, 2016 at 2:39
- 1 2017 follow-up: I believe the culprit of this issue was a Wordpress firewall/security plugin. I don't recall exactly (not sure if we ever got to the bottom of it), but that certainly seems like the most likely explanation. – rinogo Commented Feb 17, 2017 at 19:21
1 Answer
Reset to default 0As suggested by @Jeff Mattson, hours of research and testing suggest that this is probably due to mod_security. I also investigated the likelihood of it being due to Suhosin, but I don't think it's to blame.
Here's the deal. It doesn't really help if we verify that the problem is due to mod_security. We don't control the servers that run our plugin and our efforts to disable mod_security via .htaccess
have failed.
Fortunately, there's light at the end of the tunnel. Regardless of what is causing the problem, a fix that is nearly guaranteed to fix the problem is to simply modify our POST
data.
The solution I plan to implement is to Base62 encode the data that we're sending to our plugin. Base64 would probably work as well, but I'd like to solve this problem once and for all, and due to its limited character set, Base62 is the safer bet when dealing with a neurotic beast like mod_security.
This should work because mod_security looks for certain "trouble" strings in submitted data. I doubt the module is sophisticated enough to attempt applying a bunch of different encodings to submitted data (plus, doing so would adversely affect performance), so this is nearly guaranteed to fix our problems.
Yay!