Live data from Hacker News

How Not to write a "REST" API

api.sharefile.com

101–110 of 117 posts

Re: How Not to write a "REST" API

#101

Earlier quoted context omitted.

Would you care to point out where in the HTTP RFCs it requires the use of certain methods for certain operations? The reality is, you can do whatever you like as far as HTTP is concerned. In fact, only GET and HEAD are required to be implemented, all the other methods are optional. HTTP does not have "verbs". That is REST. Just because they aren't using a REST API, doesn't mean they are not HTTP compliant.

I'm not sure that it actually violates the letter of the law of the spec, but I think it definitely violates the spirit, based on this section: http://tools.ietf.org/html/rfc2616#page-51 . I thought that GET (along with a few other methods) were supposed to be "safe" and not result in any action on the server except possibly logging and stuff like that? Is this required to be HTTP compliant or is this more of a recom…

Unfortunately, very little is required to be HTTP compliant. It is almost all SHOULDs and SHOULD NOTs, and is full of vagueness. Here's a quick discussion of how bad the HTTP spec is for being strict and easy to implement: http://www.and.org/texts/server-http

Re: How Not to write a "REST" API

#102

Yeesh. According to this chart: http://nordsc.com/ext/classification_of_http_based_apis.html Sharefile is not even a HTTP API (since it doesn't use HTTP methods correctly). For security purposes, authentication can be further increased by a POST of the "username" and "password" through the HTTP Headers as individual headers instead of the query string. POST https://subdomain.sharefile.com/rest/getAuthID.aspx HTTP/1.1…

I once worked with a major product from a large company that hilariously used these two HTTP headers:

  passwd: yourpassword
  quoted-passwd: "yourpassword"

Re: How Not to write a "REST" API

#103
post #91

Earlier quoted context omitted.

Actually, we ding you for putting sensitive information in URLs that are used in a browser. The reason is that it will then be sent to other sites in the referrer header. When it is used for an API it doesn't matter. A security audit will check that logs are not logging sensitive information or that they are properly secured and encrypted if they do contain such information. The combination of telling users to put th…

No, SomeOtherGuy. This is an HTTPS site. The referer header does not behave the way you're implying it does on HTTPS sites. And having read and written this particular audit line item about 29074894389734897 times in the last 15 years, let me assure you that logging is clearly an issue. The bit about how "if someone can see your logs you're already boned" is also message-board-logic more than reality. Logs are shippe…

>And having read and written this particular audit line item about 29074894389734897 times in the last 15 years, let me assure you that logging is clearly an issue.

Which is what I said. Logging sensitive info is an issue. Not requesting info that could be logged if you were using default settings. You will get dinged for logging sensitive info, you can either not have the info in the query, or not log the query. Either is fine.

>The bit about how "if someone can see your logs you're already boned" is also message-board-logic more than reality.

No it isn't. If you can read the logs, you are already either the httpd user or root. Hence you don't need application usernames and passwords anymore, you can just go right ahead and do whatever you like.

>Logs are shipped all over the place.

Wait, I thought we weren't doing things that a security audit will catch? Why did you change your mind now that is convenient? Rather than considering theoretical "what if they are absolutely retarded and send my username and password in the logs in plain text to internet accessible log storage servers?", why not consider the reality that if they are that stupid, they will be compromised anyways. So what is the concern here? As a user of their system, I know they are either doing things right and I am fine, or doing things wrong I and I am boned. So, exactly what we knew before the whole GET vs POST debate. Very helpful. If they are idiots, then there is nothing I can do to secure my account with them, this is why we don't use the same password for multiple services.

>If you have more questions about this stuff, my contact info is in my profile --- just click my username above this comment

I would suggest that you read the posting guidelines.

Re: How Not to write a "REST" API

#104
post #29

Earlier quoted context omitted.

Yes, I can see how they got where they did, too... When all you have is a hammer, everything looks like a nail...

Engineers like us can be such snots sometimes. If as a culture we want people to build great RESTful apis and a company attempts to do so, public shaming isn't the answer. But. Their homegrown text serialization format is pretty wack. They couldn't just use CSV?

I don't think they attempted to build a REST API. They just built a weird API and said "oh hey we'll call this REST, that's cool right?"

Re: How Not to write a "REST" API

#105
post #9

Earlier quoted context omitted.

As someone just starting to learn about secure restful web services: what is wrong with this security implementation of theirs?

If you're learning about REST, do it right and make this book your bible - it's brilliant: http://www.amazon.com/Restful-Web-Services-Leonard-Richardso...

Why should that particular book be the bible? I haven't read it, but I've flicked through it and seeing things like the suggestion that clients should "construct" URLs made me doubt its worth.

Shouldn't Fielding's original thesis be the bible?

Re: How Not to write a "REST" API

#106
post #48

As @artanis0 (kind of) mentioned, it'd be great to see a HN post sometime soon called "How to write a good 'REST' API". Or even just some links to good tutorials that could get me (and others) started? I've recently built a DB driven site that could possibly be extended with an API, and it's a good chance to learn something with a purpose behind it!

It's pretty straight forward, just do the following: - Use HTTP verbs: GET to retrieve one or more objects, POST to create a new object, PUT to update an existing object, DELETE to remove an object. - Address objects by collection and by individual object: /users/#{user_id} is a specific user you can PUT, GET or DELETE. /users is where you POST to in order to create a new user. - Use HTTP codes to return the result b…

> Use HTTP verbs: GET to retrieve one or more objects, POST to create a new object, PUT to update an existing object, DELETE to remove an object.

You forgot PUT to create a new object and POST to update an existing object.

> Address objects by collection and by individual object: /users/#{user_id} is a specific user

As far as REST is concerned, that doesn't really matter. The important thing is that the client doesn't generate the "/users/#{user_id}" URLs itself, but rather selects a URL from those it has been told about.

> I find it good form to return objects in JSON with the type of object at the top of the data structure, ie {:users => [ #array of users here ]} or {:user => { #single user }}

Apart from the fact that doing this allows for gracefully adding extra information, there's also an important security reason for doing this rather than having an array at the root: http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-js...

> Use OAuth or some sort of token system for authenticating the calls, don't use HTTP Auth

Why not do both? http://oauth.net/core/1.0/#auth_header

Re: How Not to write a "REST" API

#107
post #95

Seeing their API just reminds me something. What is a good way to deal with methods that don't fit in the usual HTTP verbs (GET/POST/PUT/DELETE), like Rename, Grant, Revoke in their case? In the past I've simply extended the uri to indicate additional methods like, POST /user/foobar/grant. I wonder whether putting those methods as additional HTTP verbs would be better. Edit: extending HTTP verbs might not work too we…

Defining additional verbs is certainly allowed, bit it's worth looking to see if your operations would be more easily mapped to a different resource model. For instance, a "rename" operation might work well as a PUT to a foo/name endpoint.

Re: How Not to write a "REST" API

#108

Earlier quoted context omitted.

> - Doesn't use a restful url path to action on (ie. GET /users/#{user_id} to get a specific user by id, POST /users to create a new user). That is specifically one thing which does not apply and is completely irrelevant. Good-looking URLs have nothing to do with REST. The rest, yes.

Isn't it more "cache friendly" to use urls that address objects by path, instead of addressing them by query parameters? Like http://foo.com/rest/suite/foo/bar is more likely to be cached than http://foo.com/rest/suite?dir=foo&file=bar or http://foo.com/rest/suite?file=bar&dir=foo

That is possible (for stupid caches anyway, on purely technical grounds there should be no difference), it also looks much better to developers/users and is much, much easier to map/dispatch in most frameworks.

I was just talking about the restful part of the thing, your urls can look like this:

    http://example.org/?wubwub=9cec6c6faef8f7ccefe1bbf409368f1e3d0fa626
and still be part of a completely and perfectly restful service.

Re: How Not to write a "REST" API

#109
post #48

Earlier quoted context omitted.

It's pretty straight forward, just do the following: - Use HTTP verbs: GET to retrieve one or more objects, POST to create a new object, PUT to update an existing object, DELETE to remove an object. - Address objects by collection and by individual object: /users/#{user_id} is a specific user you can PUT, GET or DELETE. /users is where you POST to in order to create a new user. - Use HTTP codes to return the result b…

A big dumb mistake this api makes is sending commands and object ids via query parameters, instead of making them part of the url. The url should look like a file path that addresses an object -- the path of the objects shouldn't be in a query parameter. Especially when the object you're addressing is a file that has a logical location specified by a path.

REST is not about pretty URLs. In fact, you could build a great RESTful API with pretty hideous looking URLs.

Re: How Not to write a "REST" API

#110

Earlier quoted context omitted.

I agree with your concerns. But my comment was talking about "typical server logs" and HTTPS-POST vs HTTP-GET, while yours is addressing different issues.

I addressed why what gets in logs doesn't matter: if their server is compromised you have to assume you are boned anyways. And I don't understand why is your comment would be talking about "HTTP-GET"? The API in question is dealing with HTTPS for both GET and POST requests.

I don't understand why your comments pointing out details of the http spec and common-sense security considerations are being downvoted. I guess they are coming across as overly 'stident'? Anyway, I've found them helpful. Thanks.
Post reply on HN