Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Is it over-engineering if I add protection against a user's intentional wrongdoing (to put it mildly), if the harm the user can incur is not related to my code?

To clarify, I'm exposing a simple JSON RESTful service like this:

GET /items - to retrieve list of user's items
PUT /items/id - to modify an item
POST /items - to add a new item

The service itself is not meant to be used trough a browser, but only from third party applications, controlled by the user (like phone apps, desktop app, etc.). Also, the service itself should be stateless (i.e. session-less).

The authentication is done with Basic Authentication over SSL.

I'm talking about one possible "harmful" behavior like this:

The user enters the GET url in a browser (no reason but...). The browser asks for Basic Auth, process it, and stores the auth for the current browsing session. Without closing the browser, the user visits malicious web site, which has a malicious CSRF/XSRF javascript which makes a POST to our service.

The above scenario is highly unlikely, and I know that from a business perspective I should not worry too much. But for the sake of improving the situation, do you think that if the username/password are required in the JSON POST data as well, will help?

Or should I drop Basic Auth altogether, get rid of the GET, and use only POST/PUT with authorization information in them? As the information retrieved trough GET can be also sensitive.

On the other side, does using custom headers considered pure REST implementation? I can drop the Basic Auth, and use custom headers. That way, at least CSRF attack from a browser can be avoided, and the applications which use the service will set the username/password in custom heather. Bad for this approach is, that now the service can not be consumed from a browser.

share|improve this question
3  
As well as with my answer, I would also like to leave this statement, I think this would probably be better answered on SO or Security –  Jeff Langemeier Aug 18 '11 at 18:58
1  
I think that you have switched PUT and POST as defined by RFC 2616 (tools.ietf.org/html/rfc2616#section-9.5). –  Svante Aug 18 '11 at 21:42
add comment

4 Answers

up vote 4 down vote accepted

Over-engineering? Not at all. Anti-XSRF measures are a necessary part of any secure web application or service. It may or may not be “highly unlikely” that someone will choose to attack you, but that doesn't make your software less insecure.

Systems have commonly been attacked using XSRF, and though the results are less immediately-obviously bad than SQL-injection or XSS, they're quite bad enough to compromise all user-interactable features.

That does mean you can't have a “pure” RESTful interface where the only parameters are the properties of the call itself. You must include something in the request that an attacker couldn't guess. That could be the username-password pair, but that's far from the only possible choice. You could have username together with token generated from a salted hash of the password. You could have tokens issued by the service itself at authentication time (which could be remembered in the session, or verified cryptographically).

should I get rid of the GET

No, GET requests are used for read-requests that have no active writing operation (they are “idempotent”). It's only write operations that require XSRF protection.

share|improve this answer
    
What if the GET request can reveal sensitive information? –  Sunny Aug 18 '11 at 21:08
    
@Sunny: What are you considering sensitive data? –  Chris Aug 18 '11 at 21:15
2  
Chris, if I go paranoid, every data is sensitive, if it's received by the "wrong" user :). Its theoretical. –  Sunny Aug 18 '11 at 21:21
    
pls, review the changes in the question I added. –  Sunny Aug 18 '11 at 21:24
    
It's fine for the response (whether GET or other method) to contain data only the user should see. A XSRF attack only allows the attacker to have the user make a particular request, it doesn't allow them to read the response that comes back from that request. Unless the target script is constructed in a special way to allow third-party pages to read it from a <script> tag, either deliberately (“JSONP”) or accidentally (unprotected JSON). –  bobince Aug 18 '11 at 22:54
add comment

You should consider all plausible eventualities, including the user being actively malicious and (successfully) reverse engineering any "security by obscurity" barriers.

But at the same time, you should be assessing the impact of a success hack, and the likelihood of an attempt taking place. For instance:

  • An internal service protected by a solid firewall is less likely to be subject to attack than a service on the public internet.

  • The impact of someone taking down a customer discussion forum is less than the impact of them stealing customer credit cards.


My point is that "total security" is "infinitely expensive" ... and practically unachievable. Ideally you should to make your decisions about where to draw the line based on a thorough cost-benefit analysis.

share|improve this answer
    
Thanks. The question was not about protecting "from" the user, but protecting the user herself if they act irresponsibly. But your answer makes few good points. –  Sunny Aug 19 '11 at 12:33
add comment

If the code is established and maintained, edge cases should be looked at and dealt with on a case-by-case basis.

FIXING DUE TO SOME ERRORS ON MY PART:

GET should still be used as part of a proper RESTful service, the authentication needs to still be there in any case. What I was trying to surmise was that for security purposes GET is much the same as POST but post does its work without putting the information in an address bar, which tends to be the big security difference (and why I dislike GET), but as posted by @Lee,

GET requests are used to retrieve resources, and PUT/POST are used to add/update 
resources so it would be completely against expectations for a RESTful API to use
PUT/POST to get data. 

Since this will be used by third-party applications one should follow good practices for a RESTful service so that the end implementer won't be confused on this part.

share|improve this answer
3  
How does GET differ from POST in terms of security? Both are sent in plain over the transport (HTTP or HTTPS), the only difference is that GET query strings are visible in the address bar. –  tdammers Aug 18 '11 at 18:58
    
@tdammers That's the main difference in my eyes is that the string is visible in the address bar, and for what it's being used for in this case, there's really no reason to use GET (or in most cases imho). Further, the big reason for GET is so that the user can repeat their actions from something like a bookmark, in which case, he is really probably looking against anyway (being not used through browser). –  Jeff Langemeier Aug 18 '11 at 19:00
    
@tdammers: I specifically asked about prevention of CSRF. Get is exposed, as the auth data can be provided by the browser behind the scenes (its a header). With post, the attacker need to find out the auth information to craft the message. And if someone else knows that, there's no way stop any atack. –  Sunny Aug 18 '11 at 19:11
1  
@Sunny: POST is just as exposed as GET in this regard. Fire up telnet and talk to a web server if you don't believe me. –  tdammers Aug 18 '11 at 19:14
6  
GET requests are used to retrieve resources, and PUT/POST are used to add/update resources so it would be completely against expectations for a RESTful API to use PUT/POST to get data. –  Lee Aug 18 '11 at 19:31
show 7 more comments

Never trust anything. Every request is an attack. Every user is a hacker. If you develop with this mindset, your application will be much more secure, stable, and less likely to be hijacked by a malicious user. All it takes is one clever person to find a way around your security for you to be in serious trouble with your data (one of your most valuable resources).

If you've identified a security hole in your application, do everything you think you need to do to plug the gap. Your API, especially, should be the most untrusting piece of software in existence. I would require the credentials and go with Post requests.

share|improve this answer
6  
+1 for "never trust anything" –  Wyatt Barnett Aug 18 '11 at 19:20
4  
YAY for paranoia! You do have enemies! (And +1 for Every request is an attack) –  Treb Aug 18 '11 at 19:48
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.