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.

  • 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 Aug 18, 2011 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, 2011 at 21:42

4 Answers 4


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.

  • What if the GET request can reveal sensitive information?
    – Sunny
    Aug 18, 2011 at 21:08
  • @Sunny: What are you considering sensitive data?
    – Chris
    Aug 18, 2011 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, 2011 at 21:21
  • pls, review the changes in the question I added.
    – Sunny
    Aug 18, 2011 at 21:24
  • 1
    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, 2011 at 22:54

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.

  • 4
    YAY for paranoia! You do have enemies! (And +1 for Every request is an attack)
    – Treb
    Aug 18, 2011 at 19:48

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


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.

  • 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, 2011 at 18:58
  • 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, 2011 at 19:14
  • 1
    @Jeff: The reason I'm bringing up telnet (or curl, wget, or a good old-fashioned sniffer) is that it allows you to see the full data stream. Yes, HTTPS hides this information from eavesdroppers, but anyone on either end of the SSL connection can see exactly what telnet sees.
    – tdammers
    Aug 18, 2011 at 19:20
  • 1
    @Jeremy: POST doesn't show the parameters in the address bar, but since the data is just as visible in the actual HTTP stream, you are right on the whole.
    – tdammers
    Aug 18, 2011 at 19:21
  • 7
    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, 2011 at 19:31

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.

  • 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, 2011 at 12:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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