Live data from Hacker News

How not to write an API

ghost.teario.com

91–100 of 172 posts

Re: How not to write an API

#91
post #59

Could someone with a solid security background provide a example of how to properly handle the issues that this API fails so badly at? While some developers may be able to clearly identify bad practices, best practices may not always be so clear. I'd love to know what a best practice would be for things like authentication to an API and some of the other issues brought up here.

I wouldn't say I have a solid security background, but there are four best-practices I can think of that would have prevented the security vulnerabilities outlined by this post: 1. Hash the secret API token/key given to each client that is sent to the server with each API request. This will prevent attackers from being able to find out your secret token. If you only hash the secret token though, this still won't help…

I think your efforts on #1 are moot because I don't think there's a way to include the API key in a mobile app such that it can be used by the app but not extracted by an attacker.

Re: How not to write an API

#92
post #29

Earlier quoted context omitted.

" Who the hell thinks it's OK to store non-encrypted passwords in this day and age?" You'd be surprised: http://plaintextoffenders.com/ ...and an amazing number of finance organisations who can't handle non alpha-numeric characters in passwords, indicating failure to hash.

Or they want to avoid the problems that can arise with multiple systems having to authenticate at the system - some of which might use non-exchangeable ways of encoding stuff like Umlauts. Or they want to avoid the customer service calls "I am in Russia and use a Euro sign in my password, how do I login?!?!?!"/"Help, I have a Macbook from my brother, where is the vertical pipe (|) symbol?" so they restrict the keyspa…

Self-reply, as the edit window is out of order: don't forget mobile devices (the support of software IMEs for anything outside the alphanumeric range is spotty to say the best), and as you're talking about financial institutions, also think about ATMs and PoS terminals where the only thing you have worldwide available is a 0-9 keyboard.

Re: How not to write an API

#94
post #59

Could someone with a solid security background provide a example of how to properly handle the issues that this API fails so badly at? While some developers may be able to clearly identify bad practices, best practices may not always be so clear. I'd love to know what a best practice would be for things like authentication to an API and some of the other issues brought up here.

Using a standard library for authentication like oAuth or similar is generally a better idea than creating your own. It's also usually easier since you don't have to re-invent the wheel.

Aside from that, I don't see a reason for an API to be able to retrieve passwords. If passwords need to be reset then the API could maybe issue a pass reset request that would email a confirmation link.

The plain text password is something that's beyond the API design, but a one way hash is generally better with an algorithm that is recognized as being secure (not MD5).

Basically, to repeat, simply not designing your own security but using recognized libraries will typically be a better idea.

Re: How not to write an API

#95
post #84

Earlier quoted context omitted.

I wouldn't say I have a solid security background, but there are four best-practices I can think of that would have prevented the security vulnerabilities outlined by this post: 1. Hash the secret API token/key given to each client that is sent to the server with each API request. This will prevent attackers from being able to find out your secret token. If you only hash the secret token though, this still won't help…

You can also include an extra random number in the hash, and require that within the window of acceptable timestamps the random numbers have to be unique. By the way, be aware than hash(string1 + string2) constructions are often vulnerable. hash(hash(string1) + string2) is better for most hashes, I believe. But you shouldn't roll these primitives yourself, either. Just use a proper library.

You're absolutely right about the hash constructors. I was trying to make it clear what's happening conceptually, but that's why I included the note to choose a cryptographically secure hashing function. HMAC is generally a good hash constructor pattern to use.

EDIT: Just realized it'd probably be clearer to replace the pluses with commas in my examples, to avoid implying the relation between the parameters of the hash_function.

   hash_function( secret_key, api_function_name, datetime )

Re: How not to write an API

#96
post #66

Earlier quoted context omitted.

It is sent to the server, instead of the clear-text password. This isn't really necessary if you're using HTTPS, however.

Sending a straight hash of the password is no more secure than sending the password in cleartext - an attacker can just replay the hash they sniffed off the network. As skyebook said, use HTTPS . There's no excuse.

I agree there's no excuse not to use (and force) HTTPS, but the parent did say:

> hash your secret key together along with other data unique to your HTTP request, in particular the headers and the datetime

So that isn't a straight hash and you can't just trivially replay. It does require you store the secret in the clear (or at least reversibly) on the server, but I see a lot of APIs do that...

Re: How not to write an API

#97

Earlier quoted context omitted.

I wouldn't say I have a solid security background, but there are four best-practices I can think of that would have prevented the security vulnerabilities outlined by this post: 1. Hash the secret API token/key given to each client that is sent to the server with each API request. This will prevent attackers from being able to find out your secret token. If you only hash the secret token though, this still won't help…

I think your efforts on #1 are moot because I don't think there's a way to include the API key in a mobile app such that it can be used by the app but not extracted by an attacker.

#1 is a fairly standard security concept used by protocols like oAuth or JWT. It requires an API key pair (public and secret key).

The secret key is only used for signing and is never passed in the request. Used in combination with nonces and time stamps you can make a secure API that isn't susceptible to replay attacks.

Re: How not to write an API

#98
post #59

Could someone with a solid security background provide a example of how to properly handle the issues that this API fails so badly at? While some developers may be able to clearly identify bad practices, best practices may not always be so clear. I'd love to know what a best practice would be for things like authentication to an API and some of the other issues brought up here.

I wouldn't say I have a solid security background, but there are four best-practices I can think of that would have prevented the security vulnerabilities outlined by this post: 1. Hash the secret API token/key given to each client that is sent to the server with each API request. This will prevent attackers from being able to find out your secret token. If you only hash the secret token though, this still won't help…

What's the advantage of using your hand-rolled hashing scheme instead of just https?

Re: How not to write an API

#99
post #80
post #42

Earlier quoted context omitted.

Given the prevalence of password reuse, exposing user passwords is never a good idea.

Just to drive this home a little more: a lot of your users will use the exact same e-mail address and password on your site that they use for their bank. And while they shouldn't do that, they will, and that's why you should use best practices to protect your users' credentials even if their account on your site is completely unimportant.

Ah, yes, I missed the "I would bet the majority of those registered reuse the passwords." from parent.

Re: How not to write an API

#100

Earlier quoted context omitted.

I think your efforts on #1 are moot because I don't think there's a way to include the API key in a mobile app such that it can be used by the app but not extracted by an attacker.

#1 is a fairly standard security concept used by protocols like oAuth or JWT. It requires an API key pair (public and secret key). The secret key is only used for signing and is never passed in the request. Used in combination with nonces and time stamps you can make a secure API that isn't susceptible to replay attacks.

Doesn't https take care of the same issue, though? And it doesn't solve the problem that if you're shipping an app the secret key can be found. So what does it solve?
Post reply on HN