On Monday 14 September 2009 07:20:29 pm Sj Tib wrote:
I have joined a development group where developers have created a “REST”
interface that passes username and password as parameters (with every
call) though the call is made over https e.g.
https://?user=&pwd=.
Ew. But no real problem there.
It is not truly a REST
interface as they have designed it to make all calls as POST (instead of
using the other HTTP verbs like PUT/DELETE/GET).
So they’re using POST and a querystring?
I am not comfortable
with the username and pwd being sent in with every HTTPS call - doesn’t
feel right
This is how HTTP Authentication often works.
- Even if it is a POST with https can’t someone see the username and
password in the url going over the network?
No, unless you’re using a proxy server.
I am assuming the network
sees the url in deciding where to forward it to.
Not at all.
Basic way this would work, at a low level:
- You tell your HTTP library to fetch
https://foo.com/bar/baz?user=smith&pwd=god.
- The library asks your dns server what foo.com is.
- The dns server returns an IP address, call it 1.2.3.4.
- The library opens a secure (encrypted) connection to 1.2.3.4.
- The library sends “POST /bar/baz?user=smith&pwd=god HTTP/1.1” over
the
secure channel.
- The library sends a few newlines, then the body of the post.
- 1.2.3.4 sends the response over the secure channel.
Keep in mind, by “http library”, I mean “code running inside your
program”.
So, the only thing the network can see is:
- You asked for foo.com
-
foo.com is 1.2.3.4
- You connected to 1.2.3.4
- You had some sort of encrypted communication with 1.2.3.4. (Or maybe
it was
garbage, who knows?)
That’s it. Every part of the URL after the hostname is sent over the
same
encrypted channel as the POST body. (Again, unless you’re using a
proxy.)
Is it any more/less
vulnerable if GET/PUT/DELETE is used with https and the username/pwd is
passed in url?
Completely irrelevant.
It’s still ludicrously bad design – you should be authenticating with a
cookie or with HTTP authentication, not with the URL or the post body.
But
it’s not particularly insecure inside a REST call, assuming that call is
being
made deep inside the app.
However, there are a few potential vulnerabilities, if you do this in a
browser. The most obvious one is, the URL (complete with username and
password) is now in your history. Some people won’t care – I click
“save
password” a lot.
But some people don’t save passwords, or would like to be able to use a
public
computer without the password sticking around. And I certainly wouldn’t
want
any shoulder-surfer to be able to read my password right out of the URL.
If every REST
call is an https call won’t there be significant processing overheads
not only on the server side but also on the PDA client side?
Depends. Do you value your clients’ data? Yes? Use https.
On the server side, you can put an https proxy in front of it. You can
even
get machines which will do this in hardware. It’s pretty much a “throw
money
at it” kind of problem. Again, ask yourself – do you value your
clients’
data? Is your clients’ data worth that expense? Probably.
On the client side, it’ll drain slightly more battery on an iPhone, but
nothing significant, especially compared to what you’re already doing
parsing
the HTML, applying styles, doing animations, etc etc.
It’s worth mentioning that, depending on the sensitivity of the data
involved,
you might be able to improve performance by switching to something as
basic as
HTTP challenge/response, and using straight HTTP. Anyone will be able to
intercept/mangle the data itself, but they won’t get your password, and
you
could always force HTTPS for any destructive operations, or for anything
particularly sensitive.
But, if you use a session cookie, you’ll want HTTPS again, because any
eavesdropper can now hijack your session and use that to login.
- What is the best practice security model to be used with REST API
when the interface will be opened up to the world for all kinds of apps
to be built on top of it? (Not planning on OAuth as the data is not
expected to be consumed by other website apps)
In my opinion, abstract the authentication away, and never put it in the
URL
– it’s just bad taste. Once properly abstracted, you should be able to
do
what Rails does with restful_authentication – you can transparently
support
http or https (whichever the client wants) or force one or the other,
and you
can transparently support HTML form + cookie authentication, HTTP
authentication, CAS, or anything else you care to implement.
Anyone accessing this from a web browser probably wants to use HTML and
cookies, while anyone accessing this as an API would probably find it
easier to
use HTTP auth. People in the outside world should use HTTPS (and you can
force
it), while anything inside your network (or on the same machine) could
probably use HTTP.