RFC 2616, the document that defines HTTP/1.1, lays out the definitions of all the HTTP status codes, including 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.
That's not how Drupal uses it: Depending on the case, it either uses it for the default condition in callbacks (e.g. shortcut_link_add_inline()
), essentially making it equivalent to Drupal doesn't understand the request, or it is used to inform the client it doesn't have access to the page.
In the case of the former (the request isn't understood), the more appropriate status code should be 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.
In the latter case (the client does not have access to the page due to permissions), it should either be 401 Unauthorized, if Drupal wants to give away it's just a permission problem.
The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8). If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials.
Drupal could also use 404 File Not Found, if it doesn't want to make public it's a permission problem.
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 realize it's been like this for many years, but what was the original rationale for making 403 Forbidden the only response Drupal sends when it gets a request it doesn't like?