0

I have a mobile app which uses public key pinning to make sure that I only connect to servers from my CA. This works great with https, and it makes it so that nobody can really proxy my server and read the requests without going through some degree of trouble.

A colleague came up with an idea that certificate pinning makes it so that POST requests aren't really as useful because we don't make requests unless the certificate/public key of the server we're talking to matches the pinned one on the mobile app. Therefore, people wouldn't be able to snoop the POST body at all.

Is there any reason why GET would be less secure than POST for a case when public key pinning is present for mobile apps?

fjlksahfob
  • 103
  • 3

2 Answers2

2

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.

Tom Leek
  • 168,808
  • 28
  • 337
  • 475
  • Kids these days! Nothing better to do than sit around McDonalds sniffing wifi and waiting for their chance to spam the pope. – Digital Chris Jun 12 '14 at 17:08
  • It's trivial to perform XSRF with POST, using the method as a mechanism to protect against XSRF is ineffective. – David Jun 12 '14 at 17:13
  • Thanks for the response, Tom. One follow-up, how could the hacker determine the URL https://www.example.come/sendEmail?to= ? My understanding of this situation was that my client's calls would not be snoop-able with cert pinning + HTTPS, am I wrong in this? Thanks again for helping a noob like me out. – fjlksahfob Jun 12 '14 at 17:15
  • 1
    @fjlksahfob: They cannot determine the URL as it is encrypted, but [URLs are not really secure](http://security.stackexchange.com/q/58215/8340) as they can [easily be brute forced from word lists](http://security.stackexchange.com/a/59557/8340). `sendEmail` is a name you'd expect to be used and the `to` parameter name isn't that unusual either. – SilverlightFox Jun 13 '14 at 11:14
  • 1
    Tom - POST requests are just as easy. Even though the Same Origin Policy stops the request from being read, the request is still made from the browser. However, if the [`X-Requested-With` or `Origin` headers](http://stackoverflow.com/a/22533680/413180) are checked, then this can prevent AJAX requests from succeeding (the mobile app could either use one of these or supply a custom one). – SilverlightFox Jun 13 '14 at 11:19
2

Certificate pinning is completely orthogonal to the HTTP method used in the request. Certificate pinning is useful to prevent against MITM attacks and ensure confidentiality and integrity of your communications channel. Whether that channel carries requests with method POST or GET or a mix is irrelevant.

POST requests are not more secure than GET requests. If CSRF is your concern, both POST and GET are vulnerable to CSRF, the techniques for POST CSRF are well established.

You refer to the ""POST body", but that doesn't matter. An attacker can't seen any part of the HTTP requests when HTTPS is in use. The entire connection is encrypted, not just the POST body.

Use the most appropriate method for the operation you're performing. If retrieving data without a state change is your goal, use GET. If you're changing state, use POST (or even PUT, DELETE, etc., if you want to be fully RESTful).

David
  • 15,814
  • 3
  • 48
  • 73