As @Philipp states, any URI may have a query string, regardless of the HTTP method (GET, POST, PUT, ...) it is used with.
The RFCs do not, in general, explicitly discuss query strings, even when discussing methods like GET where we expect to see them. A rare explicit mention is in RFC 2068:
some applications have traditionally used GETs and HEADs with query
URLs (those containing a "?" in the rel_path part)
You might want to follow links from RFC 7237, which lists a number of non-traditional HTTP methods, to see if any explicitly describe their handling of query string parameters; I checked a few and found no explicit discussion.
Now, all that said, there are a couple of security issues which tie into this imprecision.
- Inappropriate use of query string parameters
- Cache-busting and the uptight WAF
- General ambiguity problems
There are times when query string parameters are not appropriate - for example, consider RFC 2616:
Authors of services which use the HTTP protocol SHOULD NOT use GET
based forms for the submission of sensitive data, because this will
cause this data to be encoded in the Request-URI. Many existing
servers, proxies, and user agents will log the request URI in some
place where it might be visible to third parties. Servers can use
POST-based form submission instead.
This is good... but query strings are not prohibited on POST requests, merely not expected. As it turns out, some web servers (Tomcat, for example, and PHP programs that use
$_REQUEST) will quietly take all parameters to a POST, whether they be in the query string or in the body, and make them accessible to the application as input parameters. I've seen a case where a POST form functioned quite smoothly being fed query string parameters for months before someone realized that it was happening (and that sensitive information was being logged that shouldn't).
One thing that some applications will do is append a bogus query string to requests as a way of ensuring they get fresh, non-cached content. Because the server usually ignores query strings it isn't expecting, this can usually be safely done by the client application.
The exception is when tight controls are in place, like a Web Application Firewall, that consider unknown or unexpected query strings to be signs of a malicious scan or attack. If the WAF knows that
/foo/bar isn't supposed to have query string parameters, and a request comes in for
/foo/bar?_fresh=20150819, the WAF may block that request.
In short, the looseness which allows query strings in places and URIs not anticipated means that tightening security controls can block functionality as a side effect.
This is really a superset of the other issues, but the lack of well-defined rules over when a query string may or may not be used means that security issues are introduced. Because each server may choose to handle query strings in weird places differently, the security practitioner can't predict the threat model without testing to see how things work in their setup - and even then such testing is usually incomplete (e.g., it's hard to think of every crazy thing an attacker might do with query strings). If there were hard and fast rules ("query strings are not permitted on POST requests") this would be easier.
Jon Postel's famous guideline for Internet protocols:
Be liberal in what you accept, and conservative in what you send
Is good for interoperability, but bad for security. The more liberal a system tries to be in accepting inputs, the more security problems are likely to be introduced. And in the case of query strings in HTTP methods, the RFCs end up leaving ambiguity that requires very liberal system interpretations.