
Why does your API still use HTTP Basic Auth? - sjtgraham
http://swaggadocio.com/post/48223179207/why-the-hell-does-your-api-still-use-http-basic-auth
======
patio11
This would be improved by a recognition that security involves trade offs,
particular when you have existing apps in production that you don't want to
break compatibility with. That isn't a laughable consideration: "A security
problem in customer's code? Fire them as a customer!" Would indeed be
effective at reducing their exposure but is not in their interests and has
certain drawbacks with regards to one's odds of remaining employed as a
security professional. Many apps - probably most apps - are not under active
development, because the customer believes them to work. Sudden breaking API
changes are bad news for them, possibly irreversibly bad news if e.g. the
original developer can't be located to fix the problem.

A more sensible resolution to this issue, as a hypotherical security
professional at an API company, would be moving more of the burden for
security onto the company rather than the API consumer, by e.g. limiting the
downside risk of a credentials compromise. (Similar to how banks don't say
"The bad guys got your password? Sucks to be you, your balance is now $0", one
would be well-advised to eventually have something on the roadmap to e.g.
disallow unauthorized or poorly considered code from causing business
catastrophe prior to getting a human in the loop.). You'd also want to e.g.
make sure your sample code is secure of of the box, and write your first-party
libraries to "just work" to the maximum extent possible, such that greenfield
development would tend to be secured by default.

That's being pretty generic, but it's my understanding that many API companies
actually do put quite of bit of work into internal anti-abuse tooling, for
this and related reasons.

~~~
tomjen3
I don't think this is something you can mitigate with libraries, especially
not as you need client libraries for a dozen or so languages and I (at least)
wouldn't be willing to install software just to try out some service -- you
pointed out in your blog how much users dread installing software, in my mind
client libraries are even worse as you have to install them and their
dependencies (which may or may not conflict with your own) which may involve
more or less crappy tools (e.g. my JRuby build now depends on maven, because I
need to use your client libraries) before you can even test the service.

So just use HTTPS and leave it at that.

------
poutine
As an API and security professional I've found to be secure and performant one
should do the following with APIs:

\- Dont listen on HTTP, force HTTPS (Tune your ciphers! see
<https://www.ssllabs.com/ssltest/index.html>)

\- Ensure that any client libraries you supply for API interaction must verify
the server certificate

\- Only use the users password to obtain a long random key from the server
either through an admin web interface where possible or by an API request that
supplies the username and password and receives the key.

\- Make authenticated requests of the API with the key

\- Store any passwords as bcrypt hash in the DB for security

\- Only store the key as SHA2-256 hash in your DB for performance

\- Actually yes do use HTTP Basic as it's a convenient way to transmit the key
(see how Stripe does it) making things easy for your users and perfectly
secure as long as you prohibit plain HTTP.

\- Stay the heck away from HMAC's and signing requests, you have SSL, properly
tuned it's secure. HMAC is pointless here and really confuses the users.

~~~
veesahni
Users should use "a long random key"

But you should store "the key as SHA2-256 hash in your DB"

why hash it?

~~~
poutine
Because if someone gets access to your database somehow you're not exposing
all of the keys for all of your users.

While you're likely in serious trouble if someone gets your DB this helps
minimize damage. Besides to authenticate a request you dont need the plaintext
of the key, a hash is fine.

~~~
acqq
Storing SHA in the database or anything not produced by PBKDF2, bcrypt or
scrypt is wrong and doesn't help you much "minimizing damage." Advising SHA
doesn't seem to come from a real professional.

~~~
poutine
I don't think you understand the distinction here, this is a random key, not a
user generated password. The purpose of using something like bcrypt is to
protect against brute forcing hashed passwords.

You cannot brute force search against a large random number that is hashed
with unsalted SHA or the like. This would require you to guess the number,
hash it and check to see if the hashes match. A large random number encoded as
a 64 character string is simply too big to guess, even at millions of guesses
per second.

Thus using bcrypt to protect your api keys does nothing but impose a serious
bottleneck in how many api requests per second you may authenticate.

~~~
krallin
Exactly!

------
pc
(I work at Stripe.)

We've thought about closing HTTP access in the past. As with a lot of
security, it's a usability trade-off.

We work hard to make sure that people only ever access Stripe over HTTPS. Most
people use the Stripe API through an existing library. Since the API doesn't
work over HTTP, any such library is guaranteed to use HTTPS. Stripe itself is
on Chrome's built-in HSTS list, sets HSTS headers, etc.

The scenario Stevie describes is unlikely to be an issue unless the user is
implementing his or her own library. In that case, though, they're almost
certainly going to be using test API credentials. Stripe's API will never
return a successful response when you access it over HTTP, so you'll figure
out that you can't do this on the very first request.

More broadly, what exactly is being defended against isn't particularly clear.
There are much easier ways for someone implementing their own library to screw
up (skipping cert verification is extremely common and leaves you perpetually
vulnerable to HTTPS MITM), and there are many other plausible vectors for an
attacker.

Even if we _did_ change this, we'd only have solved one small class of
accidental key leaks. You could accidentally specify "stripe.com" instead of
"api.stripe.com", for example, and stripe.com will of course always accept
HTTP. Or you could typo the domain and send your key to someone else entirely.

If we ever did want to solve this, we'd probably do something like:

\- Monitor HTTP Authorization headers sent to api.stripe.com.

\- Notify the user if they ever accidentally send a secret key in the clear.

\- In addition to notifying the user, we could potentially roll the key
automatically (though this runs the risk of breaking production code).

But I don't think disabling HTTP helps much. (I do think it'd be good if we
started monitoring the frequency with which this happens -- if it's common, we
should certainly do something like the above; if it ~never happens, it
presumably doesn't matter.)

Separately, I think that the HMAC-based signature scheme that Stevie proposes
is something we might want to do at some stage. A very early version of Stripe
actually had something very similar. The issue with all protocols in this vein
is that they involve considerably more complexity on the user's end and are
harder to debug. But they definitely have some nice security properties.

------
martin-adams
If we're worried about a man-in-the-middle attack sniffing insecure credential
on port 80. If the host closed port 80, couldn't the man in the middle just
open it up again, you know, in the middle?

Maybe one recommendation should be supported vendor supplied SDKs which don't
touch HTTP, only HTTPS. Another option is to detect credentials being sent
over HTTP and notifying the clients, maybe deactivating their key if action
isn't taken in a period of time.

~~~
rst
I think the idea is that if the real port 80 never answers, real customers are
highly unlikely to set up their apps in the vulnerable state in the first
place. That said, having port 80 open, but returning an appropriate error code
to all attempts to use the API, would probably have the same effect (while
still answering on port 80, for anyone who just wants to ping it to see "are
they up" --- one of the excuses the OP has heard for leaving port 80 open).

~~~
chmullig
No, that's exactly the problem the post is complaining about. It still results
in credentials being sent in plaintext in the original request.

~~~
sp332
Right, but the problem will be caught when the app is still in development.
Then the devs will fix the app and by the time it gets to end-users, it won't
do that anymore.

------
louischatriot
This is an important issue, but as the article says, Auth Basic over SSL is
perfectly secure (if you don't redirect 80 to 443 of course). And since it is
so simple to set up and use, I can see why some providers would use it (I do
for example).

Summary of the article: [http://tldr.io/tldrs/516fc7e340d4a84c4100020e/why-
the-hell-d...](http://tldr.io/tldrs/516fc7e340d4a84c4100020e/why-the-hell-
does-your-api-still-use-http-basic-auth)

~~~
sjtgraham
Great TL;DR. Is that algorithmically generated or by a human?

~~~
eigenvector
It's crowd-sourced from actual people using a browser extension.

<http://tldr.io/what-is-tldr>

(see how I gave you a tl;dr of the link explaining how the tl;dr is
generated?)

~~~
iaskwhy
Is there a tl;dr page for that page? :)

~~~
louischatriot
Actually, there is: [http://tldr.io/tldrs/50509fb5e37267fc34000007/tl-dr-what-
is-...](http://tldr.io/tldrs/50509fb5e37267fc34000007/tl-dr-what-is-it)

But this page is a bit outdated, this is what we use now:
[http://tldr.io/tldrs/514d1c2ec02bf6ba46001aba/more-on-the-
tl...](http://tldr.io/tldrs/514d1c2ec02bf6ba46001aba/more-on-the-tldr-io-
extension)

------
tptacek
Don't use the "signature" gem. Rails already provides a MessageVerifier class
that wraps OpenSSL's HMAC; the "signature" wrapper uses "==" to compare HMAC
values, and is thus timeable.

Really, don't use HMAC-of-the password authentication tokens at all, though.
They're not nearly as secure as TLS.

Better still, don't use passwords in your API at all. Passwords are for
humans. APIs use keys.

~~~
corresation
_Better still, don't use passwords in your API at all. Passwords are for
humans. APIs use keys._

You make great points, but just as a point of clarification (because I saw
numerous people confused by this yesterday), this is merely nomenclature, no?
What you are calling a key is really a long, random password (in Amazon's case
the secret Access key).

~~~
mechanical_fish
Nomenclature is important. As the joke says, naming things is one of the only
two difficult problems in computing. [1]

A good password is a long string of random characters, and an API key is a
long string of random characters, but they are not the same because the
semantics are different. Passwords are typically chosen by customers, changed
(let's be honest) very rarely and on a haphazard schedule, often reused across
a bunch of different systems no matter how frantically we wave our hands, and
(most important of all) have "user" semantics and scope: a password lets a
user log in and do logged-in-user stuff.

Whereas an API key can be issued by the system, and is thereby guaranteed
(assuming a clueful programmer) to be long and random and unique and not
shared with the customer's Gmail account and bank account. You can expire it
often. You can issue more than one per customer. (With passwords, this is
theoretically possible but practically impossible; customers barely understand
how to handle _one_ password.) You can issue it to entities that aren't
themselves customers, and that don't have "user" semantics. You can scope it
to particular uses, issuing a key that is only good for checking balances but
not for initiating transactions, for example.

\---

[1] The other being cache coherency. And avoiding off-by-one errors when
enumerating lists.

~~~
poutine
You also hash the two differently in your database. With passwords you want to
bcrypt (or similar) them to protect against exposure of the DB and an attacker
brute forcing the hashes. Since this is virtually impossible for long random
strings you're able to just SHA2-256 the keys for DB storage. This becomes
important because you're likely checking the key every API request and bcrypt
would be a significant API rate limiter.

~~~
tptacek
Exactly what is the point of obfuscating single-purpose API keys at all?

~~~
corresation
Doesn't exactly the same concerns arise? A single purpose may be a major
purpose, such as "transfer monies between accounts", and aren't exactly the
same concerns relevant between passwords and keys?

If someone gets a list of unencrypted (or poorly encrypted) passwords, they
have the rights of the user. If someone gets a list of unencrypted (or poorly
encrypted) keys, they have the rights of the API caller. The concerns seem
identical.

~~~
mechanical_fish
I will state the argument as I understand it:

The difference is that you can, and should, rotate your API keys automatically
and fairly frequently (I will leave it to experts to tell us _how_ frequently
is prudent.)

Moreover, when you think your DB has been compromised you can flush all the
API keys and reissue them. Depending on the application this may be more or
less of a pain for the customers, but at least it is possible, because the
keys are random and generated by you and not shared across services.

These facts mean that API keys, properly implemented, have a much smaller
attack surface. You need not worry, for example, that a three-year-old backup
file that someone harvested out of the trash at your ISP has valid API keys on
it. The window for attack is, in fact, limited to "someone has stolen a very
fresh copy of my live DB, but I have not yet realized it, and there is still
something valuable left to compromise other than _the data in my app's live
DB_." And this window often isn't very important. Often, closing it is akin to
reinforcing the barn door after the horse has bolted and the barn has burned
to the ground.

Passwords, on the other hand, get reused. You are using bcrypt to hash
passwords not just to protect your app, but to protect your customer Gmail
accounts that share the same password.

~~~
poutine
In common usage the user will take an server generated API key and embed it
within their application that makes API requests. Take a very typical example
of a merchant selling snowboards and using Stripe to process the payments as
an example.

Since this API key is embedded within their app it'll require a programmer to
change (and customers often may be non technical with sites built on
contract). These are things you dont want to force customers to change with
any frequency as it can cause pain and expense. You dont want to ever be
forced to flush all your API keys, it could be a serious disaster.

Now there's protocols that rollover access keys hourly or the like such as
OAuth a but that's a complex and often unnecessary use case that's beyond most
API implementors. See how Google does OAuth 2.0 with their APIs for an
example.

Since it's secure, simple and performant to hash API keys stored in your DB
and just compared hashed values for authentication why would you ever not want
to do it?

~~~
tptacek
If you lose the database containing either your API keys or hashes of your API
keys, you need to revoke the keys. Not doing so is negligent.

The correct next step after discovering that you may have lost custody of API
key information is to ensure that the keys are worthless, not to scramble to
try to protect the keys.

This is another reason you want to be clear about the difference between a
"key" and a "password", because passwords are sticky. A benefit of working
with keys is that they are not; you can zorch a key with minimal provocation.

~~~
poutine
If you lose your DB you're in trouble regardless. We're talking about the
level of trouble here. I'd rather be faced with a 30 day key rollover of all
my users than a forced immediate change.

I dont see any reason to continue the argument. It's clear to me that you
should hash your API keys in your DB.

------
scjody
There's a very good reason for using HTTP basic auth: if you want to store
password hashes on your server using a modern scheme like bcrypt or PBKDF2,
you can't use digest authentication. The author suggests rolling your own
authentication scheme based on HMAC-SHA, but then all the clients need to
implement this scheme whereas HTTP basic auth is already part of most HTTP
libraries. And do you really trust yourself to get the crypto right?

HTTP basic auth over SSL seems like the way to go - and you need to use SSL on
your API anyway to prevent hijacking. The points about not allowing HTTP
access to the API make sense, but avoiding basic auth entirely isn't a good
security tradeoff.

~~~
sjtgraham
I did not suggest "rolling your own crypto". HMAC is detailed in an RFC
(<http://tools.ietf.org/html/rfc2104>), is widely used, e.g. Amazon AWS, and
is part of OpenSSL. At no point do you have to "roll your own". If you don't
implement this correctly the request will simply fail, the credentials won't
be exposed at any point. Please spare me the FUD.

~~~
mdellabitta
You are suggesting 'roll your own auth,' though. Which is more difficult to
get right than most people think.

------
bengotow
HTTP Basic Auth is actually a great solution as long as you've blocked non-SSL
traffic, so I half-agree with you. Absolutely close port 80 so it's not
possible to accidentally attempt basic auth with the server in the clear.

The bit I disagree with is this:

As well as being tremendously simple, HTTP Basic by itself is also
tremendously insecure, i.e. it is implemented by simply Base64 encoding the
username and password concatenated with a colon “:” character. It then follows
that HTTP Basic should only be used, if at all, over securely encrypted
connections.

I agree - HTTP Basic is…well, basic. But you imply that even over SSL, HTTP
Basic Auth is only marginally acceptable, and that's not the case. Everything
you do securely online is transmitted in plaintext behind SSL. If a vanilla
API key behind SSL is barely secure, you're pretty much hosed.

~~~
sjtgraham
I don't imply or perhaps did not mean to imply this.

------
acqq
What's always needed is simply properly used TLS (https). Even wording in the
article is misleading. It's not about "closing port 80" but about "using only
TLS."

Once you use TLS is the "HTTP basic" often the optimal solution. After reading
the whole article, I still don't understand why would anybody try to make HTTP
"secure" instead of simply using TLS. So my question to the author,
paraphrasing the article title:

Why the hell simply not using TLS and thereby avoiding the "basic auth is bad"
misdirection?

~~~
noselasd
It's pretty much like forms based auth which is used by virtually every user
facing web site with a login, wherein the data you send over is plaintext.

And as we know, that needs to be done over TLS.

------
lucaspiller
Isn't this is a problem with the client, curl in this case? According to the
spec:

> HTTP provides a simple challenge-response authentication mechanism which may
> be used by a server to challenge a client request and by a client to provide
> authentication information.

The client should make two requests. The first with no credentials to see if
the resource is protected (the challenge part). The server will then respond
with a 401 Unauthorised status and a WWW-Authenticate header indicating what
authentication to use. The client will then make another request with the
given authentication.

The insecurity is caused by curl not doing this challenge response, it is just
sending the credentials straight away.

~~~
rapala
By my reading, the spec is not that clear about it. It does say that

 _A user agent that wishes to authenticate itself with an origin server--
usually, but not necessarily, after receiving a 401 (Unauthorized) --_

implying, imo, that no prior 401 response is needed. On the other hand, the
spec also says

 _A client SHOULD assume that all paths at or deeper than the depth of the
last symbolic element in the path field of the Request-URI also are within the
protection space specified by the Basic realm value of the current challenge.
A client MAY preemptively send the corresponding Authorization header with
requests for resources in that space without receipt of another challenge from
the server._

which would imply that at least one 401 response should be received before
sending credentials.

Of course the most important part of the spec is this:

 _The Basic authentication scheme is not a secure method of user
authentication, nor does it in any way protect the entity, which is
transmitted in cleartext across the physical network used as the carrier._

~~~
mnarayan01
I don't think there's any ambiguity here...the first quote indicated that a
client is absolutely allowed to send auth headers without receiving a 401
response. I read the second quote as giving client implementers a suggestion
on when they should automatically send the auth headers, without actually
requiring them to do so.

~~~
cobralibre
I agree, and the practice of sending an Authorization header without first
receiving a challenge is common enough that there's a phrase for it:
preemptive authentication.

See, for example, the Apache HttpClient documentation:
[http://hc.apache.org/httpclient-
legacy/authentication.html#P...](http://hc.apache.org/httpclient-
legacy/authentication.html#Preemptive_Authentication)

------
fiorix
Why the hell would you over complicate your API with things like s3 auth or
other bs like oauth?

HTTP Basic Auth works pretty well with SSL and should be enough for most
cases. Also, it's dead simple for the API to return a token that can be used
after authentication in non-SSL endpoints of the API.

~~~
laumars
The title is a little misleading as the author is talking about HTTP vs HTTPS
rather than the HTTP auth specification vs oauth (et al). Essentially his
whole blog post could be reduced to this: _servers shouldn't open port 80 on
auth API sub-domains._

While he does have a point, I do think part of the blame lies with the client
side as well. If you're dumb enough to transmit user details over clear text
protocols then you really shouldn't be allowed near any sub-systems which
require authentication.

~~~
fiorix
hmm, not really... the post ends with: P.S. Don’t use HTTP Basic. Thanks.

That just don't make any sense to me and implicitly suggests using other
authentication methods.

------
rb2k_
I like HTTP APIs that use basic auth over SSL. Why? Because as the blogpost
demonstrates nicely, curl is a wonderful tool to test, demo and debug things.

As soon as you introduce e.g. MACs to the mix, you can forget about most
unix-y commandline tools.

I think we can all agree that there are better options when it comes to
authentication, but I'd rather have something I can work with easily than
worry about that tiny amount of possible "plain http pre redirect" mistakes.

What about using http digest auth as a middle ground? It's still curl
compatible and a tiny bit more secure.

~~~
hrrsn
I agree, things like Oauth are also massively overkill for what should be
simple jobs. The other day I was writing a script for my own personal use that
needed to get some metadata from Imgur. Their API /requires/ OAuth, when even
a json snippet for a public picture would have been just fine. Ended up just
scraping the page as it was a one off script and was much faster than signing
up, creating an application, implementing a library, etc.

~~~
sgt
You can use a subset of OAuth - I tend to use the so called "0-leg" version of
OAuth, which is pretty much the same as a username/password (consumer key +
secret), but with added benefits such as protection against replay attacks.

It's also pretty simple to implement on client side and server side. I usually
give our clients a little library to get started with requests.

~~~
pifflesnort
I've implemented OAuth client-side a few times in a few languages. The signing
process itself may not be that difficult to understand, but there are a lot of
fiddly moving pieces, the specs are painful to read, and everyone has their
own unique take on the spec.

I wouldn't call it simple. It's complex to get right, and outright damaging to
non-web clients except in the case where xAuth or similar is available.

------
crazydoggers
I get the feeling that most people commenting here haven't actually
implemented an API that is under heavy use and has strict security
requirements.

One of the main problems with Basic Auth that the author fails to mention is
that if your passing passwords with every request, you're also hashing that
password with EVERY request (assuming your doing REST, ie no client state on
the server). And if you're properly hashing passwords in your DB, you should
be using a slow hash like bcrypt. That means a single request that might take
30ms now takes perhaps 500ms. And many workloads are going to require multiple
hits to the API to accomplish simple tasks, so your talking about both a
strain on the system, and a horrible experience from the client's perspective.

~~~
wickedshimmy
This is a very good point, and is the sort of situation where API tokens can
come into play and be useful. A client can make a single request to "open a
session" and receive a short-lived key that is used as the password
credentials for subsequent requests. Store active keys - since they are short-
lived, offline attacks are less of a concern and you can probably choose to
not slow-hash them. When the token expires and a request fails authentication,
the client simply requests a new one and retries. The token lifetime is a much
easier adjustment for which to weigh security versus performance/load
considerations, compared to against broader password storage security.

~~~
poutine
You've described OAuth in part with its refresh and access tokens.

------
rlpb
This article highlights an important issue. But closing port 80 is sufficient
to address this problem. Having considered this article, I think I would still
design an API to use HTTPS only, with port 80 closed, with Basic Auth. There's
no security problem then, and it's a whole lot easier to manage with existing
tools.

(eg, as rb2k_ points out, it makes it easy to use curl to debug things).

~~~
sjtgraham
I agree with you and rb2k_ as it says in the post. HMAC-SHA is suggested for
vendors adamant (Stripe) about listening on port 80 on their API host.

------
felixclack
Agree that the practice of just redirecting http requests to https is a bad
idea.

Hope this can help raise awareness why it's bad.

------
anuraj
Basic Auth should be used only with HTTPS/SSL - who does otherwise? Do not
think HTTP Basic is a bad design choice with SSL for securing your service.
Any security is brittle if you don't understand what you are upto. That said
key based authentication is more apt for APIs.

~~~
bobwaycott
People who can.

------
emtunc
I was playing about with Fiddler with some mobile apps on my iPhone a while
ago and noticed one app was using HTTP basic auth with HTTPS _but_ the
application was ignoring SSL errors (I was using a self signed cert on my PC
to perform MITM and decrypt HTTPS traffic). This is almost as bad as using
HTTP and basic auth because you're basically ignoring the fact that the
certificate should not be trusted (at least give the user a choice?). You
would be surprised to see how many apps ignore SSL errors and allow you to use
any old self signed cert.

~~~
kalleboo
We had to (begrudgingly) disable cert validation when we still supported older
iOS versions, as it was impossible to find an affordingly-priced CA that
issued compatible certificates.

------
bgentry
A great alternative if you can't (or don't want to) close port 80 is to return
a 401 for non-HTTPS requests to your API, rather than redirecting with a 301
from HTTP->HTTPS.

This has the side effect of making sure that HTTP clients can never silently
redirect, and it's impossible for a developer to ever get their code working
without explicitly using SSL. If it never works in development, they'll never
ship such code to production.

------
film42
I tend to use an api_key, because it's easier to manage. I'll setup a route to
authenticate, where I'll use basic auth to return an api_key, and the
remainder of the api either requires an api_key or no authentication at all.

For Rails developers, Ryan Bates does a great job of explaining a few ways to
secure your api.

<http://railscasts.com/episodes/352-securing-an-api>

------
URSpider94
I agree that HTTP Basic over SSL is probably fine for requests from a server,
in order to prevent sniffing of the connection.

However, I've recently been thinking about how to use a third-party API
directly from client-side Javascript, or even from a resident application. If
you're doing that, then you really need some way to use keys with validity
that is limited by time or scope. In that case, HMAC offers some real
advantages.

------
tszming
If people can accidentally send plain text password to Stripe for a 403
response and don't care about it, I can't see why people can't accidentally
send plain text password to the HMAC-SHA protected port 80.

They are the same thing, both will not work.

(Unless you close the port 80, using HMAC-SHA can't solve the issue.)

------
pbreit
The problem it seems to me with Stripe and others is that they stuff the API
key in as the Basic Auth username. Wouldn't is be safer to use, say, a
merchant ID as the username and then the API key as the password (since the
password is not transmitted on the errant HTTP)?

------
tomjen3
This may be decent advice for security purposes but unless I can test your API
directly from the commandline using CURL I am unlikely to ever get as far as
trying out your service.

In other words, use HTTP BASIC (or similar) if you want new users.

------
awj
Closing port 80, great suggestion.

Until you can point me to an alternative authentication scheme that I can
expect api consumers to generally have ready-made support for, it's pretty
well the only good suggestion in this article.

------
kenneth_reitz
I am a firm believer that all APIs should be available over Basic Auth, even
if it's only a small subset to access your own data.

Slinging OAuth shouldn't be necessary to hack your own fun scripts and get
your own data.

foauth.org

------
perlgeek
Offer a test bed for your API, where people can test their clients. That way
developers will start to use SSL before they they go in production, and no
production passwords should leak that way.

------
sergeykish
Obviously it is user agent failure. Why would you want transmit private
information clear text?

Edit: File bug to browser makers. Personally use http proxy to remove auth and
cookies from insecure traffic.

~~~
geon
Sending the password more or less in plain text is defined by the http
standard. It's not a bug per see...

And I doubt you can convince any browser maker to drop basic auth support.

------
zobzu
http basic auth is implemented in the server, not in the webapp, that's one
fine reason. redirecting from http to https is ALWAYS an issue, http basic
auth or not. now then again it'd be nice to have a "better auth" than basic
auth that is still not part of the web app.. but yeah.

------
rplnt
Because I need the user's password in plaintext for example.

~~~
Millennium
If you need the user's password in plaintext (or something easily derived from
it), then your authentication scheme shouldn't send it over the network at
all: there are better ways to handle that scenario.

Also keep in mind that a machine storing plaintext passwords has the same
security requirements as a Kerberos KDC, and those requirements are very, very
high. Don't do this unless you know what you're doing, and even if you do, you
should seriously consider a different scheme (or just using Kerberos itself:
they've already gotten things right, so you don't have to risk getting things
wrong).

------
barredo
So if you offer a https only API and anyone makes the mistake of using http
instead, what should be the response of your system? A simple error message
with 404 code and without special/identifying headers?

~~~
rb2k_
The main problem isn't the response, the problem is that on the initial
request, the insecure password will be sent in plaintext.

~~~
barredo
But that's not the problem of the API provider. If you explain that you only
allow HTTPS and someone makes an HTTP on an unsecured connection, well...

~~~
smtddr
Oh but it IS the problem with the provider. Or rather, it will be when some
crazy PR storm hits the interwebz with "$YOURCOMPANYNAME leaked passwords!"
when someone comes up with some clever way to hack/manipulate traffic with XSS
or something. I was able to fetch private authtokens of a Wii game because
port 80 was open on one of nintendo's servers(I assume it's there to test in
plain text and just didn't close it later) and I was able to fool the software
into using port 80 instead of port 443. That wouldn't have worked if port 80
was closed.

~~~
barredo
Makes total sense. Thanks

------
xyproto
Too much focus on closing port 80. They could just host something else on port
80.

~~~
zikzikzik
No, the whole problem is a http server (ANY http server, serving ANY content)
listening on port 80.

Once the tcp connection is accepted on port 80, "dumb" clients (like curl) can
just come barging through the door shouting plaintext auth credentials without
knocking first, and no http server can stop them from doing that (because that
is how the http protocol works).

The only way to stop them from doing that is rejecting connections on port 80.
(Dropping packets looks even more like service outage, which was mentioned.)

~~~
eddieroger
The author made this seem outlandish, but really it's a reasonable and easily
done way to go about things. Just have a special subdomain for your API (I
don't know, api.*.com) and only listen on 443 with it. Done.

