Live data from Hacker News

How not to write an API

ghost.teario.com

101–110 of 172 posts

Re: How not to write an API

#101

It's a felony in the US to do what the author did here, right? Not that there's any indication where they're from, I'm just curious.

I'm going to say FU to the industry and buy a horse ranch if it is! These were all public documented endpoints and 'worked as intended'. criticker is next-level incompetence, that's pretty much the point.

Re: How not to write an API

#102
post #98

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…

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

You could just run fiddler on windows and trust the fiddler certificate. This would allow it to MITM the https session.

Re: How not to write an API

#103

Earlier quoted context omitted.

I don't care if this comes off as trolling, but here it is: as I read through this, I thought to myself, much like the author, "how appaling!" - then I saw the word "PHP" - and went "oh, well that means there's gonna be a bunch of people hating on a language because one developer doesn't know what he's doing and happens to be using that language".

All the php hate I've seen over the years is because of one guy who doesn't know what he's doing? ;)

Oh yeah, I forgot, because of the low barrier of entry, PHP is the only language in the history of all programming languages where there are people who don't know what they are doing. Forgot that all Python, Ruby, etc devs are gods gift to programming and don't make mistakes. My good, your bad.

Re: How not to write an API

#104
post #30
post #3

Short version: http://criticker.com sells access to their API for apps. Any API account can retrieve a list of all users it registered on the site, then retrieve the cleartext password for each user it created. There are so many WTFs in this whole situation that it's a wonder criticker has managed to keep the website online. Which is a shame, as it looks like a really useful website.

I dont think you realize how common the WTFs in this situation are. If you are dealing with a reputable company, this is super super WTF. When you are looking at a small website/API someone made for fun or something....It can normally be badly broken in less than 2-3 minutes....and I'm not even that talented like some of the guys out there.

Rails + Devise = answer to all these problems.

Re: How not to write an API

#106
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…

Sorry for being harsh, but your "solutions" are mostly useless in the context of providing an API for phone apps.

Use OAuth or similar and make sure every user has their own account. That's the only answer. Don't roll your own! Especially don't roll your own when you don't have a solid security background. You have obviously heard some of the right terms, but how and where you can apply them is at least as important as using them at all.

1. Doesn't protect anything at all. Hash functions don't do anything when people have access to the program code. No matter how fancy you go with time limited hashes (and there are smarter ways to create those). At most it adds a few minutes to the reverse engineering.

2. Again, this doesn't protect against anything. HTTPS stops intercepts on the wire, not someone who has access to your app, people can still lift the secret keys and the hashing scheme from the app binary.

3.& 4. Both true, and would protect against mass stealing of the passwords like happened here, but it wouldn't prevent abuse of the API.

There are very many people who use techniques like the ones you suggest in 1. and 2. and the same very many people have vulnerable apps that usually expose all users' data to the world. There are a lot of apps that store e.g. user files or some sort of configuration not on a per user OAuth protected storage like OneDrive, DropBox or Google Drive, but either there but on just the account of the developer, or on another storage that is only authenticated with the developer's credentials. People who do that allow anyone to read and modify the data of all users, exactly the same as people are allowed to do to their own data, or more if the credentials aren't properly limited, even if it's blocked in the app.

Re: How not to write an API

#108

It's a felony in the US to do what the author did here, right? Not that there's any indication where they're from, I'm just curious.

I'm going to say FU to the industry and buy a horse ranch if it is! These were all public documented endpoints and 'worked as intended'. criticker is next-level incompetence, that's pretty much the point.

Well saddle-up, my friend ;-)

In seriousness, recall the weev/AT&T case[1]. As I understand it, the attack was roughly of the sophistication of making a totally unauthenticated request to:

get_user_email_address.php?id=N

(where N was from a series of sequential integers)... and apparently the feds had a colorable argument that N constituted an "access control system", and therefore the act of iterating the entire series of possible N values (and downloading the resulting data) constituted "unauthorized access to a protected system".

Not quite in the same realm as coughing up plain-text passwords, I'll admit. But clearly some relevant authorities would set the bar for "access control system" fairly low. And apparently rank incompetence on the part of the site developer/owner appears not to come into things.

[1] https://news.ycombinator.com/item?id=4808676

Re: How not to write an API

#109
post #85

Earlier quoted context omitted.

> Who the hell thinks it's OK to store non-encrypted passwords in this day and age? The post gave no indication how Cricketer was storing the passwords. They may very well be stored encrypted. You can send plain text passwords back if you've encrypted them, you just have to decrypt them first. There's no point at all in returning the results of encrypting a password if the clients don't know how to decrypt those resu…

> You can send plain text passwords back if you've encrypted them, you just have to decrypt them first. Yes, and security-wise that's just a slightly obfuscated version of plain text.

That's not true at all. If you use secure encryption to store plain text, and proper use of HTTPs to transfer said text, that's secure. It's not as bad as obfuscated text. What you've said is just plain untrue.

One problem with storing passwords is that there is no good reason to. The other security issue is that people reuse passwords. So everyone should be creating hashes instead of encrypting passwords, but encrypting text, and transmitting it securely is still secure. This API didn't do that, it did a lot of things wrong, but these comments are all pretty ignorant as well.

It's just one inane comment after another in this thread.

Re: How not to write an API

#110

Earlier quoted context omitted.

#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?

You're correct - you shouldn't ship an app with a secret key embedded. That would be a flawed implementation.

It's hard to be specific without knowing what you're doing. If you have an app that connects to a third party API like Twitter, that's one situation. If you have an API that other app developers will connect to - that's a second scenario. And third is if you have an API and you write your own app to connect to it.

OAuth handles all three of these scenarios but in #1 you are a consumer, in #2 you are a provider and #3 you are both.

Check out 3-legged oAuth for an example of how to allow apps to talk to your API on behalf of a user, without that user having to give their password to the app. It's actually pretty interesting, clever and simple all at once!

HTTPS encrypts the traffic - making it difficult to sniff. It doesn't actually provide authentication though.

Post reply on HN