I am designing a POST Restful API, where I have a situation that I have to authorize a user based upon one of the element provided in the request body.
For eg.
{
division : "1",
name : "MyName",
address:{
no : 123,
street : "abc",
pincode : 222111
}
....
}
So the user making POST request should be authorized to work on division 1. I cannot authorize the user without getting request body.
Also to validate some of the attributes I have to make heavy DB calls in the DB , for eg, to check the above address has a valid value of pincode.
So My question is how should I return the error codes to the user -
[EDIT]If division is not valid(something that doesnt exist in system) in the request - 400 or 403 ?
If division is provided, but user is not authorized and pincode is invalid - 400 for invalid pincode or 403 ?
What should be the error code if pincode is mandatory attribute and is not provided in the request. Should I first check 403 and then 400 or reverse ?
Basically which error code to proceed the other ?
Also is it okay to do something like :
400 – request is bad, syntactically (division/pincode or other mandatory values not provided)
403 – authorize user
400 – request is bad, data specific validation (heavier operation, requiring to hit DB)
[EDIT] we preferred not to use 422 error code
When in doubt, just take a look at the RFC
400 Bad Request
The request could not be understood by the server due to malformed
syntax. The client SHOULD NOT repeat the request without
modifications.
403 Forbidden
The server understood the request, but is refusing to fulfill it.
Authorization will not help and the request SHOULD NOT be repeated. If
the request method was not HEAD and the server wishes to make public
why the request has not been fulfilled, it SHOULD describe the reason
for the refusal in the entity. If the server does not wish to make
this information available to the client, the status code 404 (Not
Found) can be used instead.
If division is not provided in the request - 400 or 403?
I don't think either apply. The syntax -although it's missing some data- is not malformed.
Also 403 seems incorrect because of reasons mentioned above in the quote: authorization will not help etc.
How about 422 Unprocessable Entity?
422 Unprocessable Entity (WebDAV; RFC 4918)
The request was well-formed but was unable to be followed due to
semantic errors.
That is what I usually use in situations like this.
If division is provided, but user is not authorized and pincode is invalid - 400 for invalid pincode or 403?
Again, I don't think either 400 or 403 make a good case here. Specifically for this situation, 401 exists
401 Unauthorized
Similar to 403 Forbidden, but specifically for use when authentication
is required and has failed or has not yet been provided. The response
must include a WWW-Authenticate header field containing a challenge
applicable to the requested resource. See Basic access authentication
and Digest access authentication.
I think you're in the right track. Assuming that every request is being authenticated via (http authorization header)
Returning 400, on missing data is OK, and furthermore you can add error response body explaining what was the reason for the Client request not being accepted (in this case the missing division).
Returning 403, is OK if the client making the request is not authorized to interact with the resource (in this case the division).
You must validate first if the Client is authorized to interact with the resource, so 403 must be sent first, and if a required field is missing you can treat it as a 400 (with a proper explanation).
In case the Client is not authenticated, the correct response should be 401, but like I said before, 1) and 2) in my response are assuming that the Clients are authenticated against the server.
Hope it helps,
Jose Luis
Related
We use DRF + SimpleJWT and we're finding that when our servers get overloaded or timed out, we're passing a 401 on the token refresh endpoint and causing users to be thrown back to the login screen (because a 401 indicates that the user is no longer authorized to view anything).
Does anyone know why this might be? It only happens under really bad network conditions – we've ruled out the client and do believe it's the server returning a 401 somewhere now. When the user kills the app after being thrown back home, they are authenticated on next launch again, so it seems like we're issuing a 401 on timeout or something like that.
I have setup my API at Amazon API Gateway and the Gateway Responses part seems to be a bit confusing.
There are a lot of default responses defined here along with the HTTP Return Code:
Access Denied (403)
Invalid API Key (403)
Invalid Signature (403)
Missing Authentication Token (403)
Unauthorized (401)
Is there any logic of which response is returned upon which condition? I have done my tests and I wasn't able to find a pattern.
No API Key + Valid URL: Invalid API Key
No API Key + Invalid URL: Missing Authentication Token
Good API Key + Invalid URL: Missing Authentication Token
Is there any specific pattern here?
Thanks,
Guven.
As noted in comments, for security reasons, API Gateway can give you the impression that it is really pretty obsessive about these mysterious authentication token thingies, whatever exactly they may be.
But this was apparently done because it should be difficult for a malicious user to determine a specific reason why the request is forbidden... and, as you have discovered, this message is as potentially uninformative as it is potentially misleading. (Not necessarily a criticism, here... that's what it's for.)
What you'll probably find helpful is to go in and customize your error responses and change the default wording of each message to match its actual meaning. There are several where you'll find Missing Authentication Token in the text of the template.
I'm giving flask-security a go...it has a lot of nice pieces to it. I ran into some quirky behavior though that I don't really understand. From the code I looked at it looks very intentional that the code works the way it does, but I can't understand the rationale.
If you protect a view using #auth_token_required and the criteria is not met a 401 is returned. Makes perfect sense.
However, if you protect a view using #roles_required and the criteria is not met, the server redirects (302) to an unauthorized view.
This makes no sense to me why they both would not behave consistently. Indeed in both cases I want and expect a 401.
Can anyone explain the reasoning and why I might want this? Or can someone explain the best way to customize the #roles_required behavior?
Thanks!
I believe this has something to do with the different levels of unauthorized responses. The first one being a 401 error and the second one for a 403 error.
Here's difference between the two:
In summary, a 401 Unauthorized response should be used for missing or
bad authentication, and a 403 Forbidden response should be used
afterwards, when the user is authenticated but isn’t authorized to
perform the requested operation on the given resource.
Source: 403 Forbidden vs 401 Unauthorized HTTP responses
What response should I send back when a Cross-Site Request Forgery (CSRF) is detected?
There is a scanning tool which I cannot get a hold of that is saying one of my pages is not protected against CSRF. But it is. The response I send back is a normal 202 with the sentence "REQUEST CANNOT BE PROCESSED". That's it, nothing informative is sent back to the attacker, and I log the attempt. But this software says it is still susceptible to CSRF. I could easily run tests myself and figure it out but it's a long time in between scans and tests and I can't get the same software, that's why I'm asking stackoverflow, so I can hopefully knock it out on the next scheduled scan. I'm thinking of sending back a statusCode of 404 or 410 instead of a 202. http://www.cfgears.com/index.cfm/2009/8/11/cfheader-404-status-codes-and-why-you-shouldnt-use-them
What do you recommend sending back when a CSRF is detected?
403 Forbidden as the user is technically authorized to access the site, it is just the specific action that is forbidden (HTTP POST without correct CSRF token).
A web server may return a 403 Forbidden HTTP status code in response to a request from a client for a web page or resource to indicate that the server can be reached and understood the request, but refuses to take any further action. Status code 403 responses are the result of the web server being configured to deny access, for some reason, to the requested resource by the client.
Bear in mind that the attacker will not be able to read this response, and for the most part the user will not see the message or HTTP response because a CSRF attack is not designed to be obvious to the victim that it is happening. If you have an effective CSRF mechanism, your site is not likely to be attacked in this manner anyway - the defense is also the deterrent.
How about:
401 Unauthorized
or
403 Forbidden
When creating a web service (RESTful), what status code should I use when session token is invalid?
Currently the one in my company sends me a 404, not found, but I think this is not correct, because the resource exists.
Maybe I should use 401 Unauthorized.
What do you think? What status code do you recommend me to use in this scenario? Thanks.
401 Unauthorized.
Your existing session token doesn't authorize you any more, so you are unauthorized.
Don't forget that a session token is just a short-cut to avoid having to provide credentials for every request.
Sending 404 is incorrect because, as you observe, the resource does exist. You just don't currently have authorization to see it.
NB Don't use 403 Forbidden; the HTTP specification defines it as follows: "The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated." That doesn't apply in this case as authorization WILL help.
Looking through the HttpStatusCode enum, I think Unauthorized is probably the closest to what you're looking for.
Take a look at the list there, and read the descriptions for each one.