BartOtten
This code assumes that
get_organization_by_slug!/2raises anEcto.NoResultsErrorwhich would be automatically converted to404, but you could also handle the error explicitly and, for example, set an error flash and redirect to another page, like a dashboard.The
get_organization_by_slug!/2function should also rely on the current scope to filter the organizations to those the user has access to.
Would love for Phoenix to ship with “Login to gain access” screen. This is quite common and a far better UX than throwing a 404.
Also having no result due to scope should throw a
401 Unauthorized imho.
Although the HTTP standard specifies “unauthorized”, semantically this response means “unauthenticated”. That is, the client must authenticate itself to get the requested response
Or (when a user or org is known but no access)
403 Forbidden
The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike
401 Unauthorized, the client’s identity is known to the server
Having these available and correct would help developers doing “the right thing”.
Trending in Discussions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixir-ls
- #ai
- #elixirconf-us
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
LostKobrakai
There’s a security aspect to this between 404 and 401. 401 does acknowledge the existance of a record with the provided id, which might already be interesting information to a bad actor.
BartOtten
I am aware of it. But we have these status codes for a reason and the app should be secure enough for it not to matter.
Security by obscurity has it’s place but should not be the default.
Also: hackers do not really care about what you provide them. They are every well aware of appa faking it. Source: I work with security specialists (hackers)
LostKobrakai
This is not security by obscurity. A 401 does return real information (a record exists). That’s different to returning no information (404 not found). If that information is something you want to expose is a decision you can make, but phoenix imo should start with the conservative choice.
BartOtten
Not found is also information. It informs that the resource does not exists and there is no way to get it. Authenticated, authorized or any other way. Which is not true. The resource might exist, you just don’t have access to it if it does (which is afaik nog explicitly a requirement. A 401 can be followed by 404 once authenticated)
josevalim
You call it “security by obscurity”, I call it principle of least privilege.
I typically return 401 when it applies to all users equally. For example, a /dashboard page is available to all users but they must be logged in before, that’s a 401. 403 when the user is logged in and the access is something that can be changed within an organization, such as “ask your manager to give you permission”.
Scopes are mostly about cross-user/cross-organization access, which do not fall in the categories above IMO. To give an example, imagine someone heard that a company is working on a new product called “foo-bar”. If their CMS returned 403 for a marketing page in progress or if their GitHub returned 403 for github.com/company/foo-bar, you could potentially be confirming rumors.
The trade-offs between security and user experience are often debated, some will argue for one or others will argue for the other. Phoenix most often goes on the side of security.
BartOtten
It does not afaik. 403 does though.
BartOtten
I see your point but it really makes me think of: xkcd: Security
Also: all the reasons not to put such info in your prod-systems upfront at the correct URL as most leaks are by ‘accidental publishing’
In most companies is see a CMS folder ‘hidden’ or ‘pre-publish’ which are not accessible from outside the company network. In a lesser segmented network configuration they should (inho) throw a 401 (for the whole folder needs being authenticated) or 403 (when junior-editor instead of marketing-manager tries to access a post which he/she’s not cleared for).
So there are layers…
401 → 404 valid
403 → 404 valid
404 → 200 invalid
401 → 403 valid
401 → 403 → 404 invalid
401 → 403 → 200 valid
Mods: split thread?
BartOtten
Anecdote:
Once I battled security scanners by sending the wrong server-header, seeing them taking (a very old) Apache branch of tests instead of the actual up to date (and custom hardened) Nginx.
The pentest team did not like it as it caused much more manual work, so the dev team has a good laugh for a couple of years. After all: it was a friendly “us vs them”. External scanners failed miserably.
After 4 years a customer noticed and complained “you run a very outdated webserver and it is inexcusable for a IT security company.”
Auch….
Removed the fake server header. Result: Less fun. More customer trust.
——
Edit:
This kinda does proof my points though:
wrong headers or status codes cause confusion also for good actors. Developers for instance who don’t understand the resource does not exists (404) while they just POST-ed it. 401 and 403 explain themselves and guide in debug process.
Pentesters and non-junior hackers can be fooled for a short time but not for long. These are the types of hackers that invest more time to find vulnerabilities as your data is an asset of interest for them.
—-
Also also: 404 when a source is checked? We notice the difference in timing so timing-attacks breaks your fake surface. So unless we buildin a realistic load-simulation. You get the idea….
Back to the proposal: follow the standard. Let devs needing extra’s do it themselves as it is a lot of work anyways and changing 401/403 tot 404 is a micro adjustment in comparison.
To quote a certain dev (slightly adapted, with a wink)
josevalim
We don’t plan to change it on the Phoenix side but uou can opt-out and define your own. It will be 5 LOC in your app:
https://github.com/phoenixframework/phoenix_ecto/blob/main/lib/phoenix_ecto/plug.ex
The timing difference for a non-existing page and a page that exists but failed because of a database WHERE condition is very tiny. They both fail because the same query returns nothing. This is different from enumeration attacks from say, email+pass auth, where there is a large proof of work after you read from the database.
BartOtten
Status codes aside…guess this won’t happen either?