Should I use GET
or POST
for retrieving sensitive data, given that:
In addition to Cássio Mazzochi Molin's excellent answer, you should use HTTPS but you should (generally) use:
The reason to use GET when retrieving is that the action does not have side-effects, therefore there is no reason to use POST. The only previously applicable reason to use POST was when retrieving JSON via AJAX, because old browsers had bugs meaning that another domain that the user had open in their browser could steal the data from the JSON using a tag (JSON Hijacking). Disallowing GET prevented this attack because
always uses the GET method. See this answer. Note that using POST here means you should disable GET server-side for this method.
The reason to use POST for sending sensitive data is that it prevents data leakage via the query string (although another way would be to use GET with custom headers set, although POST makes much more sense). The reason is that query string data in the URL is logged by proxy servers, by server logs as default, and can also be stored in browser history, making it not a great place to transmit personal or otherwise sensitive details. Note that during transit over HTTPS they would be encrypted, it is just that they can leak from the encrypted state into other non-encrypted or non-controlled locations. Of course, going back to RFC 7231, if you're making changes based on this sent sensitive data, POST is the better idea as it'll prevent the browser accidentally sending it again in most cases.
One more reason to use POST is that modern browsers don't appear to cache the results of POST requests by default. However, this should not be relied upon. It is much better to set Cache-control: no-store
header in your response either way, any time that sensitive data is output.