Currently PostgreSQL error code 42501 (insufficient privilege) is mapped to a 404 http response.
https://github.com/begriffs/postgrest/blob/master/src/PostgREST/Error.hs#L91
This was designed to hide endpoints from potential attackers. However unexpected 404s can be confusing when debugging, and perhaps security by obscurity is not very robust anyway.
Suggestion: add a --reveal-forbidden command line flag. When the flag is present and the database raises an access denied, have postgrest return
In addition to my criticism of "404 as a mask for privileges error" approach.
I found that in some cases (lack of privileges on schema/view/etc) now we have a weird combination of 404 http code and error message revealing the real reason of failure:
HTTP/1.1 404 Not Found
Server: nginx
Date: Mon, 09 May 2016 23:29:03 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
{"hint":null,"details":null,"code":"42501","message":"permission denied for schema v1"}
and
HTTP/1.1 404 Not Found
Server: nginx
Date: Mon, 09 May 2016 23:29:47 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
{"hint":null,"details":null,"code":"42501","message":"permission denied for relation post"}
My opinion is that replying with 404 is not a good solution for errors because it leads to confusion.
And for security reasons it's better to mask detailed error message keeping proper (i.e. 400 Bad Request or even some of 5xx) error code in the HTTP response.
Since (in my view) you always have to have a proxy in front, it makes sense to output errors as they are (in this case with 403) and have the proxy make a decision if to forward the error or "hide it" with 404
I like your thinking. I'll update it to output an accurate error. In fact the 401/403 could be a signal to the proxy to remove the payload too, so it kills two birds.
Sounds good to me too. I always run postgrest behind a proxy. I don't think this needs a flag.
Most helpful comment
Since (in my view) you always have to have a proxy in front, it makes sense to output errors as they are (in this case with 403) and have the proxy make a decision if to forward the error or "hide it" with 404