Is status code 404 appropriate when a user isn't authenticated? - http

I've been working in web development (mainly as a backend developer) for nearly 10 years, and most services I have worked with return status 401 Unauthorized when the user is not authenticated. During a recent discussion with a colleague, they suggested that we return status 404 Not Found when a user isn't authenticated so that we don't even disclose an endpoint even exists at that URL.
I understand where they coming from, but to me it just felt wrong. This way you can't easily tell whether the failure is because the user isn't authenticated, or the URL is incorrect.
I looked at RFC7235, and it states the following:
The 404 (Not Found) status code indicates that the origin server did
not find a current representation for the target resource or is not
willing to disclose that one exists.
This follows the same argument as my colleague suggested, so should I be returning 404 Not Found for requests when a user isn't authenticated?

You can find a similar statement about 403 Forbidden status code in RFC 7231:
An origin server that wishes to "hide" the current existence of a
forbidden target resource MAY instead respond with a status code of
404 (Not Found)
So generally it is up to you and your team to decide whether to use 404 or 401 status code.
P.S.: some web security apps and tools are analyzing 404 pages to skip similar pages later. And URL structure is sometimes get analyzed as well.
So if you have some sensitive data or don't want to disclose the structure of your project to anybody - 404 Not Found is a good idea for security reasons. And you app/API becomes more difficult to reverse engineer.
The downside of this approach is that it's a bit unobvious on the client side - it will be more difficult for your clients to figure out what went wrong when it receives 404 Not Found.

Related

HTTP Error 403.0 - ModSecurity Action

I m creating a code in which based on query string the URL is changing when no values are supplied in URL everything is working fine but as i supply values to URL it shows Error HTTP Error 403.0 - ModSecurity Action
Kindly suggest some solution
also the same is working fine in local problem occurs when i upload my webpage to server
I know this is an old thread, but posting the answer so that it can be helpful for others. ModSecurity is an open source, cross-platform web application firewall (WAF) module.
https://modsecurity.org/about.html
So whenever you see the 403 (ModSecurity Action), this means that the mod security firewall has blocked the request. The probable cause could be vulnerable data present in the posted data, or the it could be because of the URL posted as parameter or it could be JavaScript.
In above case, the ModSecurity might have deemed the input as SQL Injection attack and hence may have blocked it. If you look into the logs of the firewall it may give you the detailed explanation.
In my case, I was passing URL as query parameter in the request hence it was returning 403.

Is there any reason to use the HTTP 410 GONE status code?

When permanently removing a page from your website, are there any practical benefits to setting up a "410 GONE" HTTP response for the URL (vs. letting it 404)?
Yes, the 410 Gone HTTP status code conveys that the resource requested was once available in the past, but it has now been retired or made obsolete.
The 404 Not Found HTTP status code could imply that the website has been incorrectly updated so as to be missing a file that would normally be defined there. It could also mean that the requesting client referenced a resource that never did exist and probably never will.
The 410 Gone status can have more immediate SEO implications because it tells search engines that the missing resource was intentionally removed. That should hasten the reduction of future search references to that page more so than the 404 Not Found status.
I could imagine if you have a public API, and you finally disable your long deprecated v1 after publishing like v4 or something, you could use this statuscode to make it obvious to consumers of that API. But then again one could argue that a 301 is also valid for this type of situation. It also depends on how different it is, and whether there is an actual replacement, or is it just actually gone.
From RFC 9110:
The 410 response is primarily intended to assist the task of web maintenance by notifying the recipient that the resource is intentionally unavailable and that the server owners desire that remote links to that resource be removed. Such an event is common for limited-time, promotional services and for resources belonging to individuals no longer working at the server's site. It is not necessary to mark all permanently unavailable resources as "gone" or to keep the mark for any length of time -- that is left to the discretion of the server owner.

HTTP Status Code for Resource not yet available

I have a REST endpoint accepting a POST request to mark a code as redeemed. The code can only be redeemed between certain dates.
How should I respond if someone attempts to redeem the code early?
I suspect HTTP 403, Forbidden, is the right choice but then the w3c states that "the request SHOULD NOT be repeated" whereas in this case I would anticipate the request being repeated, just at a later date.
409 Conflict
The request could not be completed due to a conflict with the current
state of the resource. This code is only allowed in situations where
it is expected that the user might be able to resolve the conflict and
resubmit the request. The response body SHOULD include enough
information for the user to recognize the source of the conflict.
Ideally, the response entity would include enough information for the
user or user agent to fix the problem; however, that might not be
possible and is not required.
403 Forbidden makes more sense if they are trying to redeem a coupon that has already been redeemed, though 410 Gone seams elegant in this situation as well.
404 Not Found isn't ideal because the resource does in fact exist, however you can use it if you don't want to specify a reason with the 403 or if you want to hide the existence of the resource for security reasons.
If you are using HATEOAS, then you can also head you clients off at the pass (so to speak) by only including a redeem hypermedia control in the coupon resource (retrieved via a GET) when the coupon can be redeemed; though this won't stop overly bound clients from trying to redeem it anyway.
EDIT: Thanks to some good critiques (see below), I want to caveat this answer. It is based on Richardson & Ruby's writeup, which arguably doesn't mesh well with the httpbis writing on 403 Forbidden. (Personally, now I'm learning towards 409 as explained by Tom in a separate answer.)
403 Forbidden is the best choice. I will cite RESTful Web Services by Richardson & Ruby line by line. As you will see, 403 is a great fit:
The client's request is formed correctly, but the server doesn't want to carry it out.
Check!
This is not merely the case of insufficient credentials: that would be a 401 ("Unauthorized"). This is more like a resource that is only accessible at certain times, or from certain IP addresses.
Check!
A response of 403 implies that the client requested a resource that really exists. As with with 401 ("Unauthorized"), if the server doesn't want to give out even this information, it can lie and send a 404 ("Not Found") instead.
You wrote above: "The Code representation is available to be GETted before it goes live." So, you aren't trying to hide anything. So, stick with the 403. Check!
If the client's request is well-formed, why is this status code in the 4xx series (client-side error) instead of the 5xx series (server-side error)? Because the serve made it decision based on some aspect of the request other than its form; say, the time of day the request was made.
Check! The client's request was formed corrected, but it was inappropriate for the particular time.
We went four for four. The 403 code is a winner. No other codes match as well.
All of this said, a plain, non-specific 400 wouldn't be wrong, but would not be as specific or useful.
Another answer suggested the 409 Conflict code. Although worth considering, it isn't as good a fit. Here is why. According to Richardson & Ruby again:
Getting this [409] response response means that you tried to put the server's resources into an impossible or inconsistent state. Amazon S3 gives this response code when you try to delete a bucket that is not empty.
Claiming a promotion before it is 'active' wouldn't "put a server resource into an inconsistent state." It would break some business rules -- and result in cheating -- but it wouldn't cause a logical contradiction that I see.
So, whether you realized it at the onset of asking your question or not, 403 is a great choice. :)
Since Rest URLs should represent resources I would reply with 404 - Not Found
The resource is only available between certain dates, so on any other date it is not found.
When it says the request "SHOULD NOT be repeated", it is referring to the message that you should send to the viewer.
It has nothing to do with whether an actual request is repeated. (The user will get the same 403 message over and over again if s/he so desires.)
That said, a 404 is not appropriate for this because the resource is available - just that the code is not redeemable/forbidden to redeem. It is actually harmful because it tells the user that you probably made a mistake in your URL link or server configuration.
Of course, this assumes that on the appropriate date you return a 200 instead.

Is it bad practise to serve an error 403 page for an application-level policy?

Say I have a website that allows anyone to log in through oauth or similar, but only allows certain uses to create or modify content. Should they somehow make a request for page for creating a new post, I'll do a check and redirect them if they don't have the appropriate permissions.
It is considered acceptable to redirect to the "403 Error" page in this situation? There was no actual HTTP response with a 403 status code, there was no database- or server- level query that was failed - just my business logic. Am I misappropriating the idea of HTTP status codes if I serve an error 403 page with a specific explanatory message?
You are free to do so, but I think if you want to expose an API you would use an actual 403 response because they carry meaning that will be nicely handled by the client.
If you want to display a page to the client and will be using redirect, you will lose this meaning of the "403".
Isn't it better to just redirect them to an explanation page without including the "403" code. Or better yet, redirect them to a more helpful place, like the sign up page if that is what they have to do to make a post, or back to the original page with a floating message.
We want to help the user get closer to their goals instead of confusing them with technical error codes.
There is often a lot of discussion about this very topic and it comes down to the following choices:
a 5xx? Of course not. This is not a server error.
a 400? Not really, it wasn't a malformed request.
a 401? Probably not, 401 is generally for authorization in general, not application-level permissions. If your user has already logged in but has the wrong role, and you want to let the user know, then use something else.
a 404? Perhaps, as the server can't find the resource for this particular user, but if you want to tell the user "well such a resource is available but you can't have it because you lack permissions" then go with something else.
a 403? Actually, this one makes a lot of sense. Here is the definition from the RFC
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.
In your question you mention your intention to redirect the user. If you are making a RESTFUL web service then just return the 403. If you are doing an entire web app, you can control the 403 and redirect....

Correct HTTP status code when resource is available but not accessible because of permissions

I am building a RESTful protocol for Dynamic Carpooling applications, for my Computer Science thesis.
In the Protocol I also have to formally specify the HTTP status code for each operation. I've got this "privacy related" problem. Suppose the following:
GET /api/persons/angela/location
Retrieves the current position of user "angela".
It is obvious that not everybody should be able to obtain a result. Only angela itself and a possible driver that is going to pick her should be able to know it.
I can not decide whether to return a 404 Not Found or a 401 Forbidden here.
Any hints? What would be the best one and why?
According to Wikipedia (and RFC 2616), a 401 code is used when a page exists but requires authentication; 403 is for a page where authenticating won't change anything. (In the wild, 403 usually means the permissions on something are wrong, whereas a 401 will prompt the user for a username/password). 404 is for where the document simply doesn't exist.
In your case, it seems like 401 is the most appropriate code, since there is some way of authenticating the users who DO have access to the page.
If authorization credentials are provided in the request and the requester does not have permissions to access this resource then you should return 403.
If no authorization credentials are provided in the request then you should return 401.
Definitely NOT 404. 404 is just Not Found.
401 is access denied.
403 is forbidden.
I would go with 401
To me I will use 400 Bad request.
Because my application will not go unaccessable resources in programmatically.
Filtering users permission and hide unaccessable resources is good user experience in my opinion.
If my server got unaccessable request which means some person trying to do something.
That is why I choose 400 - Bad request in my applications.

Resources