GET considered harmful; Sometimes. · 17. Mai 2004, 16:01

Important Update (18.6.04) - See the Follow-Up article: Securing Forms with POST is not enough.

There is a security issue that seems to be cropping up in a lot of web applications, which could be avoided easily. If you code for the web, you really should know this. Even if you are only using web applications knowing about GET vs. POST and security, will help you recognize when you are affected by harmful GETs.

The situation

In the WWW as it used mostly around the internet, there are basically two request methods that are being widely used: GET and POST. (Actually the W3C defines a broader number of HTTP request methods, but they are mostly forced to live in the shadows.) You don't have to be a web developer to figure out the basic difference: GET request have all the variables in the URL, so they can be conveniently bookmarked, sent by E-Mail or posted as links on web pages. With POST requests the variables are not passed in the URL, but "somehow hidden". People that are writing scripts or whole applications for the web probably know that "somehow hidden" means that the variables are passed in the HTTP headers. They probably also have a general idea of when to use POST and when to use GET.

The problem

Unfortunately the general idea about using POST and GET that a lot of people have, seems to miss an important fact. Actually it's less of a fact, but it's more a connection of facts. I don't know why, but there is a somewhat scary number of people that I am sure know all the facts, but they don't make that single important connection between those facts. The w3c knows the facts, and so they tell you when to Use GET and when not to use it:

  • Use GET if:
    • The interaction is more like a question (i.e., it is a safe operation such as a query, read operation, or lookup).
  • Use POST if:
    • The interaction is more like an order, or
    • The interaction changes the state of the resource in a way that the user would perceive (e.g., a subscription to a service), or
    • The user be held accountable for the results of the interaction.

So there, always follow that advice and you're safe. Of course knowing about a recommendation doesn't make us automatically follow it, which personally I would consider a good trait. When recommendations are followed like dogmas without questioning the "why?" we miss out on the (often important) opportunities when it is better to NOT follow the recommendation, and do the opposite. So what is the reason for avoiding GET in certain situations. In the above document we get told:

In the same section [9.1], HTTP/1.1 states, the convention is that GET is used for safe interactions and SHOULD NOT have the significance of taking an action other than retrieval. Indeed, if you use GET for interactions with side-effects, your make your system insecure. For example, a malicious Web page publisher outside a firewall might put a URI in an HTML page so that, when someone inside the firewall unwittingly follows the link, that person activates a function on another system within the firewall.

The potential vulnerability

I suppose a lot of people seem to think this is a somewhat manageable risk, because I keep seeing web-applications that ignore this and still use harmful GETs. They show you a list of items, and next to each you see a link to do someting with it: "Deactivate this plugin", "Install this template", "Delete this post" and so forth. Stop reading for a moment and try think like a bad guy wanting to exploit that.


So what did you come up with? The most obvious is probably social hacking ("Hey check out this link!"). This is bad enough, since you can read everywhere how phishing emails are on the rise. "But our users are internet-savvy people, they won't fall for that". Well, the harmful GET is a lot more dangerous than that. You probably also came up with some technical measures to exploit this, I assume you thought of JavaScript to hide the browser status bar, exploiting bugs in IE and Mozilla to disguise Links, embedding forms in links, or links in forms to disguise them, using meta or header-redirects to make a user execute harmful GETs etc. That is bad enough, but may still not convince some people. You guessed it, it's even worse than that. Interestingly most of the people I talked with came up with all these ideas, but they missed the simplest possibility: Images.

Connecting the facts

Everybody that publishes on the web knows that the web is not only about styled text, but also embedded stuff like images (and other objects). And everybody knows that you Browser will get them for you automatically, and he will actually GET them for you using a GET request. None of these facts are news to anybody, I assume. I also assume you just made that connection of two facts, I mentioned earlier. It seems most people (myself included) only make that connection, when the two facts ( harmful GETs and the mechanism of your browser loading images) are mentioned in the same context. Now you know how ridiculously easy it is to exploit harmful GETs. To spell it out: There is a URL that by simply being called, will make some permanent change to your site. Just as you yourself can click the link inside the web application, anybody can get your browser to call that url by embedding it in the src-attribute of an img-Tag, or by setting it as a background image in a stylesheet, of a simple HTML page that you are viewing. And since it is your browser making that request it will likely be authenticated by the virtue of cookies. The Server has no way to know the difference between you actively clicking a URL, or your browser requesting that URL only because of embedded images in another document.


If you are a developer: Always use POST if the request is going to make any permanent changes, like inserting, updating or deleting Data. And in this case, it's actually OK to follow this advice like a dogma. If you are a user and find out that you are using an application that does this wrong, contact the author privately and give him the ability to fix it and in the meantime make sure you never stay logged in any longer than absolutely necessary and don't do anything parallel to being logged in.

Important Update (18.6.04) - See the Follow-Up article: Securing Forms with POST is not enough.