views:

374

answers:

9

OK, probably best to give an example here of what I mean.

Imagine a web based forum system, where the user authentication is done by some external method, which the system is aware of.

Now, say for example, a user enters the URL for a thread that they do not have access to. For this should I return a 403 (Forbidden), letting the user know that they should try another authentication method, or a 404, not letting them know that there is something there to access.

Assuming I return a 403, should I also return a 403 when they access a URL for a topic that doesn't exist yet?

Edit: the example above was more of an example that something IRL.

Another Example, say I expose something like

/adminnotes/user

if there are Administrator notes about the user. Now, returning a 403 would let the user know that there is something there being said about them. A 404 would say nothing.

But, if I were to return a 403 - I could return it for adminnotes/* - which would resolve that issue.

Edit 2: Another example. Soft deleted Questions here return a 404. Yet, with the right authentication and access, you can still see them (I'd presume)

+1  A: 

No website in the world does what you are suggesting, so by this example we see that it is probably best to follow the standard and return 404 when the resource does not exist and 403 when it is forbidden.

1800 INFORMATION
This website does. See edit 2
Mez
Since they are deleted, I would expect them to return a 404, which you say they do. How do you know what you have to do to see them via an admin interface? maybe the URL is different
1800 INFORMATION
+2  A: 

What "privacy" is protected by hiding from users the existence of a particular thread?

I'd say that returning either 403 or 404 on a thread they cannot access is OK. Returning 403 on a thread that does not exist is a bad idea.

John Millikin
For forums, if a staff thread has a username in the title, the administrators would not wish that particular user to know that they are discussing them. So, that privacy, for one.
MetroidFan2002
+5  A: 

Above everything else, comply with HTTP spec. Returning 403 in place of 404 is not a good thing. Returning 404 in place of 403 probably is ok (or not a big blunder), but I would just let the software tell the truth. If user only knows the ID of a topic, it's not much anyway. And he could try timing attacks to determine whether this topic exists.

phjr
@Martin: Depending on how the system is structured, it's possible to time how long until a response was generated. If not much time, the topic was not found. If longer time until error, then the topic existed but the error was generated later.
John Millikin
A: 

Lets say you did return a "page not found" error when you detect that the user does not have the correct access rights. A malicious person with the intent of hacking will soon figure out that you would return this in place of the access denied.

But the real users who mistype a url or use a wrong login etc would be confused and it would take no end of explanations and release notes to explain your position to the customers, TAC etc. In exchange for what ?

The intention is good, but i'm afraid this policy you propose might not work out the way you wanted it to.

A: 

My suggestion is to:

  1. If Not Exists_Thread then return 404
  2. If Not User_Can_Access_to_this_Thread then return 403
Gravstar
+1  A: 

I don't see why you worry about privacy issue from the URL. In the case of stackoverflow, you can put any text after the QuestionID number. For example, http://stackoverflow.com/questions/147747/how-is-babby-formed still comes back to this question.

eed3si9n
But, for soft deleted questions, SO returns a 404... yet certain people can still access...
Mez
How is babby formed, that's great. Hehe.
Abyss Knight
+3  A: 

I think you should send 307 (Temporary Redirect) for requests for "/adminnotes/user" to redirect unprivileged clients to "/adminnotes/". So the client makes a request for "/adminnotes/", therefore you can send back 403, because it is forbidden.

This way your application stays HTTP compliant, and unprivileged users won't learn much about protected data.

KovBal
this. Rather than messing around with 403 vs. 404, why not just do something useful and redirect the user to the appropriate authentication method?
Nathan Strong
+3  A: 

I would go for a 307 redirect to NoSuchPageOrNoPermissions.html where you nicely tell the user they either mistyped the url or don't have permissions.

This will not break compliance and not send out the incorrect message.

If you are very paranoid you could put in a random wait before returning the redirect so time analysis would be harder.

As for all the people here asking why protect directories try these examples

1. User Name

Imagine we are an ISP we give each user a webpage at www.isp.example/home/USERNAME and email address of [email protected]. If an attacker does a dictionary attack sending requests to www.isp.example/home/[Random] and can tell if that is a valid user name we now can generate a list of valid email address to sell to bad people.

2. What Folder

Bob is running for office he has an account with the poster and uses his site to store personal information. But he has secured it by making it private folder his public pages are at: www.example.com/Bob and his secret folder is www.example.com/Bob/IceCream he has marked this as private so any one requesting gets 403. however www.example.com/Bob/Cake returns a 404 as Bobs secret is icecream not cake.

Alice the reporter does a dictionary attack on Bobs site trying

  • www.example.com/Bob/Cake - 404
  • www.example.com/Bob/Donuts - 404
  • www.example.com/Bob/Lollies - 404
  • www.example.com/Bob/IceCream - 403

Now Alice knows Bobs secrets and can discredit him as an ice cream eater.

David Waters
HTTP errors are meant to include the error message, not redirect to it. It might not matter a lot for users, but it will for machines (such as search engines).
Bart van Heukelom
+1  A: 

Don't forget that a 404 can also technically be revealing information. For example, you could tell who didn't have adminnotes. Depending on the circumstances, this could be just as bad as indicating that the resource did exist.

In my opinion, errors should not lie. If you give a 404, it should always be the case that the resource does not exist.

If you're dealing with sensitive information, then you can always say that the user doesn't have permission for the resource. This doesn't necessarily require that the resource exists. A client may not have permission to even know if the resource exists. Therefore you would need to provide a permission denied error for any combination of /adminnotes/.

That said, the official spec seems to disagree, here's what the official rfc says about the errors at http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html:

10.4.4 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.

10.4.5 404 Not Found The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.

I'm no expert, but I think it's crappy to give a "not found", when a resource may exist. I'd prefer a "forbidden", without a guarantee that the resource exists, implying that you would need to authenticate somehow in order to find out.