GET
requests can be forced upon you easily. Basically, suppose that there is a secure server to which you talk with GET
requests under the protection of HTTPS and certificate pinning and whatever else you may imagine as some extra protection. Let's call www.example.com
this server. Some of these requests are intended to have an effect, e.g. a GET
request to:
https://www.example.com/sendEmail?to=foo@bar.com
triggers a process on your server which culminates in sending an email to the specified address.
Now, an industrious attacker follows you around and wait for you to sit down in some fast food restaurant with free WiFi; he knows that you will connect to that WiFi an engage into some casual Web browsing. The attacker whips out his own portable WiFi access points (like that one) and waits for you to connect to his hardware. At that point, the attacker can see and modify all your traffic. Of course, SSL keeps him out. However, when casually browsing, you don't visit only HTTPS Web site. If your browser ever makes a connection to an HTTP Web site (without SSL), then the attacker just has to insert the following text in the returned HTML:
<img src="https://www.example.come/sendEmail?to=francisco@vatican.va" />
and boom! You've just spammed the Pope. Indeed, upon seeing that small piece of HTML, your browser dutifully sends a GET
request to the specified address. This works regardless of the provenance of the page in which this HTML tag appears; the GET
requests from <img>
tags totally evade the Same-Origin Policy.
POST
requests cannot be fabricated that way. Therefore, regardless of how sure you are that you talk to the servers you intend, you shall use GET
requests for read-only processing only.