1/22/2011

Lets end these silly ideas about HTTP "GET vs POST security."

I came across a question on Stack Overflow asked about two years back:
...between a http POST and GET, what are the differences from a security perspective? Is one inherently more secure then another? I realize that POST doesn't expose information on the URL but is there any real value in that or is it just security through obscurity? What is the best practice here?
So, this is is a great and valid question, but unfortunately I see the wrong thoughts about this propagating all over the place to the point where some persons hold the belief that GET in inherently insecure simply because variables are shown in the address bar. I decided to post an answer to that question even though it was two years old, simply because I didn't entirely agree with the accepted answer as there was simply a massive shortage of detail provided, and agreeing with things dogmatically isn't helpful: we don't know what the issues related to these requests are so we can't contextualize it, and we flatly agree with something rather than understand why.

First, lets discuss what these two methods are. 

In the HTTP protocol, you can provide multiple methods of interacting with a resource (for example, index.html could be a resource) and you specify particulars in differnt ways depending on the method and what you're trying to do. In general, web browsers only deal with two of the eight methods:
  • OPTIONS
  • GET
  • HEAD
  • POST
  • PUT
  • DELETE
  • TRACE
  • CONNECT
All of these methods do their own special job within the HTTP protocol, as specified by RFC2616 section 9, but I'm only going to talk about GET and POST, feel free to research these on your own.

When your web browser wants to load a resource, it will generally send a GET request. While you may request data through a post, that generally goes against convention, POST is intended to submit 

Now, lets pretend we have a very basic form that looks like this:


Your browser doesn't use magic to get that resource, it submits something that looks like this in raw-text to the server:






So to quickly summarize this, your GET requests puts the resource in the first line, it's asking for the root to submit a variable username=swordfish, another password=hunter2, and extra=lolcatzThe rest of the content explains to the server what host we're connecting to, what data we are accepting, what our browser is, the character set, and a bunch of information that is really outside of what we're talking about here.


Now you know what a GET request looks like on it's lowest level, what about a POST request?





So, to explain the above here, we're requesting the root (that one / after POST means root, which is like requesting example.com directly), and then we're sending the same sorts of information about who we are, and lastly we're sending the exact same information that we sent in the get request, it's just way down there.


So what's the difference between GET and POST?


A GET method is considered idempotent and safe, and if you read through the RFC I posted way up at the start, you'd know that means they're not intended to take action other than retrieval, and that the request shouldn't have side-effects. This lets web browsers request a resource without an "oops" taking place, such as deleting a hundred records. 


For example, the URL http://example.com/?deleteUserID=1337 should be considered unsafe as it preforms an action, which is generally reserved for post. 


Now, what about http://example.com/?viewUserProfileID=1337 which should let us view a profile? Well, that's fine, it didn't take an action, it returned data.


Okay, yes, RFC21616 does describe 'security concerns' in section 15.1.3, but what is explained is somewhat annoying. It basically says some web servers might log the page address because it's part of the URI. Not to get into a fight with the W3C or anything, but this is exceptionally short-sighted.


Why am I contradicting the w3c?


The way they've worded section 15.1.3 is short-sighted and assumes that somehow a webserver, programs on a server, and web-browser are designed to work the way they've said, and this means that only GET is really a threat because it's a common convention to log the entire URI in the log files.


Well, I've got news for you, 
  • My web server logs could just as easily track all the data, regardless of it being POST or GET
  • My programs on the server could easily log all the data sent in the request, regardless of being POST or GET
  • My web-browser ("user agent") doesn't have to be one of these fancy popular things, I could have written it myself to maliciously log everything, regardless of it being POST or GET
  • Regular HTTP requests that are not sent over SSL can be eavesdropped and/or modified between my machine and the web server (commonly called Man-in-the-middle attack), regardless of it being POST or GET
The only 'security' you're accomplishing here, is preventing someone from checking out your browser history, or running off with server logs from a popular web server (Apache/IIS/XAMPP) that doesn't log POST data (keep in mind, my PHP file (or other language) can very easily keep it's own log file of your POST requests).


What if I use SSL?


Here's what those above requests would look like if sent to encrypted.google.com over SSL, between my machine and the google webserver:





So what have we actually secured against?
  • Man in the middle attacks
  • Evesdropping
  • Some other more complex things that SSL takes care of
So, the entire block of data is encrypted in communication between here and there, but that doesn't prevent you from using a normal browser to bookmark https://example.com/?deleteUserID=1337 and making this request, which goes back to the concept of safe request methods in HTTP: methods with no action.

What if I wasn't using a normal browser? What if I could replay a POST request? I could just as easily delete that person. This isn't security.

If your browser isn't doing what the W3C wants it to do, it doesn't mean it's still safe because it's a GET or a POST. HTTP works regardless of your browser, you can open a telnet session and send raw-text to any webserver to do whatever you want.

Once those SSL requests get to the webserver, they're decrypted and the PHP file can just as easily log all the data you sent along (which only makes sense, it's the one that needs the decrypted data and does something with it). Once you've sent that data, your browser or virus on your computer could just as easily log all that data somewhere else.


Using SSL is a great addition to security, but thinking your even a fraction more secure using POST requests than GET is completely naive:
  • You're only protecting against what's common, not what's possible.
  • You're only preventing the very un-informed from logging into your https://email.example.com/?user=awesome&pass=hunter2
    • You haven't stopped: hackers, viruses, the website admin, your system admin, someone checking over your shoulder, the guy sitting in Starbucks running firesheep. And you won't, regardless of it being POST or GET.
Summary
  • Don't use GET to do anything that preforms an action (such as logging in) as it's against design.
  • Your girlfriend will find out what's in your inbox regardless of your login being POST.
  • Use SSL to get real security, not imaginary security.
  • Make sure you understand where the security really is.
  • Trust nobody.
So please, stop thinking you're protecting someone's information because "most browsers dont log POST." That's entirely asinine from a security perspective: you're not making it secure, you're simply making it harder for people who don't understand the technology in the first place.




More discussion:


There's a discussion on Reddit regarding this.

9/06/2010

DIY CD wallet for car console

Something that's always bothered me about my car console is that it's clearly designed to store my CDs in, but at the same time it's only big enough for at-most 10 CDs in their case, and if I take them out I scratch up my Oomph! disk collection and need to order them from Germany, or even worse I can't flip through them easily I have to jumble around with a stack of them just to find one disk. A CD wallet would be great, but I can't easily access that, and I hate those damn visor strap CD things after my last one scratched them up and only held about 20.

So what am I doing? It's 6pm, I'm going to make and document how long it takes me to make a better one.

I took a magazine (actually it's a offer to buy stocks for Potash from BHPbillition for $130 when they're worth $148, LOL WUT?), and some scissors. CD cases to judge size.

I took a CD case to see how high the flaps should be. I need to bind this like a thicker book would be, so we're going to end up using the first few centimetres of the already-bound pages to space it out. Just put a CD on it so it aligns with the open-side of the magazine, and crease into it where it is. Trim off the extra length on the top of the magazine (the CD case should have about a bit of space on both sides)

6:07pm (Junky scissors caused shredded paper everywhere).

Folded pages inward like they do with big bound textbooks (grab a few pages, fold the previous crease in to the centre, grab some more, keep going...)

6:12pm.

It needs to be bound together at the bottom... found me some paper-clips, going to cut some holes through it... corkscrew anyone?

6:19 pm,

This is taking longer than I thought, maybe I should have found a hole-punch rather than just a knife.


Just have to fold each flap in so the CDs stay in.

6:27, there's a lot of page in this...
Started folding multiple pages then separating.

6:30. Almost done....



6:32: I should have just put a ribbon around the thing's outside walls and cut it smaller... Oh well, only 20 more pages.

6:37. Done. Going to put CDs in it and take a picture later when I get it into my car.

Total cost: I cut up a booklet sent to me by people trying to talk me out of $20 a share.


Alternate solution:

A few sheets of paper, fold it back and forth like a Chinese fan, cut CD-sized holes along every downward fold, put CDs in holes and you're done. Probably only going to take 5 minutes, just fold back and forth, then snip a curve across the lower side. Probably want to use a card-stock?

Less fun solution: Goto the store and buy one of those folders with separators, cut to size for console.

8/31/2010

Crypto chat: vZero

Abstract:
Data over the Internet is insecure. This is entirely due to it's implementation rather than the Internet's design. This has lead to a lot of private communications only appearing to be private, but in reality, entirely out in the open and easily someone you can eaves-drop in on. A common solution to this problem has been to implement Secure Sockets Layer, which makes your client encrypt data before it's transmitted to a server, where it's decrypted The data it's self is only encrypted during the transmission between Client and Server. This sounds good because someone who listens in on the line will be unable to see what happens. Unfortunately, there are still many exploitable vectors to look at. The intended recipient should be the only one who gets the unencrypted message, not any of the middle men.

I intend to create a chat system that encrypts and decrypts on the client-side only, without any user-based access (attempting to support a more anonymous Internet).

Design:
Implementing the SJCL, with limited configurations (initially; version 0) around other JavaScript code, using jQuery for ajax transactions to php file which interacts with a one-table database. You may select a channel for communication, this may be used for greater privacy (but not security, as all data is public in this system). Within a chat party, only data which is successfully decrypted will display; if you decrypt something with the wrong key, it won't display anything. To the user, you are only in the proper 'channel' of conversation.

Issues:
1) The SJCL presently returns and expects malformed JSON objects.
2) The SJCL encrypted object does not explicitly identify all pertinent details.
3) The decrypted data is not sanitized for the web browser: This allows for a Mallory-based attack if you decrypt a malicious javascript payload.

Implementation:
Total weight of the code is less than 150 lines. It works, I don't have any serious glitches, but version 0 is working quite nicely. Data is posted and special MySQL characters get escaped, all data in a party is sent to the client to get decrypted. Security of information is in the encryption, not in hiding access to it. Data is removed after it ages 1 hour (this is variable).

Future features:
  • Configuration panel to modify cryptographic settings
  • A mechanism to preserve data. Cookies, HTML5 database, a login? Not sure yet...
  • Make the chat window modular. Multiple tabs, pop-ups, jQueryUI-Dialogs...
  • More CSS to the boring page. Zebra stripe messages.
  • Box to prepend something like a name-- Or issue 'names' to users.
  • Server should reject non-encrypted data. Examine it somehow.
  • Option to easily view raw data in a party, so everyone knows what's going on with the data.
  • Deal with various issues around SJCL (ie, failed decryption should not error).
  • Put over SSL.

Thoughts:
I wonder how the Ulam Spiral will alter cryptography...

Why?
I can't stand most chat systems. They're insecure, they're buggy, MSN has that stupid half-my-screen advertisement if I mouse-over it. Without a login, there's no 'password to your account,' so crazy ex-girlfriends don't try and guess my passwords every weekend. I can change streams whenever I want, it's very cloak-and-dagger style. I like it. It's not intended for computer illiterate folks.

7/20/2010

The off button

The off button. Get rid of it.


For those of us who use computers, who honestly still uses the power button to turn off their computer? Normally this is a process from the start menu. For some reason, makers of boxes have kept this functionality left over from the 80s that there should be an off button-- After all, there is an on one, right?

I keep my computer on the floor, near my feet. Something that really bothers me is when I'm using my computer as a foot rest, and for some insane reason the power button gets placed right where my foot likes to go. This happens all the time when I get a new box, and my feet need to re-learn where to put themselves. I'll be working on something for a while, playing a game, watching a movie or something and have my feet up then click, my foot just triggered the land mine under my desk and everything going into shutdown right away without any prompts or way to stop it.

So I decided this is insane, why do we even have this button to turn it off? When is it actually a good idea for your computer to randomly lose power?

The button should only be to turn it on. If we really have a stalled out problem, the button should be moved somewhere for emergencies. Computers have built in software that can turn them off, we don't need a hardware button to turn them off.

Computers don't need hard-buttons to turn them off within an instant of being pushed, and it's a real nuisance and doesn't make any sense from a usability perspective.

I know this is often dependant on your operating system, but I wish the damn button didn't even exist.

I'd love to see box designers start doing things like this:

This would be wonderful. Plus, your computer is that much more badass if this was your power button. And lets be honest, for most of us that use computers needing to turn your computer off is something you want to be sure about, not happen because you bumped the damn thing -- Just like nuclear missile launches!

Just in case you ended up reading this wanting to know how to deal with this on Windows...
Control panel; then Hardware; then Power; now select what the power buttons do (and then disable them).