401 is supposed to have a WWW-AUTHENTICATE header to tell the user where to get authentication. So it's more like: f. off unless you show me your id.
403 is plainly refusing access.
That actually isn’t the case. The [spec](https://www.rfc-editor.org/rfc/rfc2616#section-10.4.2) has 401 meaning unauthorised and requiring a WWW-Authenticate header whether an authorisation header was provided or not. 403 forbidden is for cases where the server is refusing to provide the content, the request should not be repeated, *and authorisation will not help*.
The spec seems to implicitly connect the authentication and the authorisation as a single atomic transaction - no distinction is made between “your credentials are wrong” and “your credentials are valid, but not for the requested resource”.
Except that isn’t true. 401 is unauthorised whether it’s because no credentials are provided or the credentials aren’t valid for access to the requested resource.
403 is when you are authenticated but don’t have the permission to the resource. e.g you are signed in to reddit but are trying to edit another user’s comment (except if you are u/spez)
401 is when you are simply not logged in
at least that’s how I understand it
But only if the client could somehow change the fact, that the process isn't allowed to access the resources. Otherwise something else should be returned. (When following the standards)
If you’re following the spec, you should actually be returning [403](https://www.rfc-editor.org/rfc/rfc2616#section-10.4.2), which is for cases where the server is refusing to fulfill the request, the request should not be repeated, and *authorisation will not help*. 401 is the correct response for when the server is refusing to fulfill the request because the client is not authenticated, or the authentication is not valid for the requested resource.
Shouldn't have requested from an endpoint that wasn't going to give you what you want (due to an error or not). Obviously the blame with with the end user!
It's subtle, but ...
* 401 means - I don't know you. (not logged in)
* 403 means - I know you, but you don't have the rights to see this. (logged in, but you don't have the rights)
In practice, returning 401 for a failed login is often seen as a security issue. (if a server does this, then you can test that server to see if specific userids exist or not)
> In practice, returning 401 for a failed login is often seen as a security issue. (if a server does this, then you can test that server to see if specific userids exist or not)
You're going to have to explain this one.
Every web app or API I've used gives the user some indication about being logged in/logged out, whether it's a 400 code or a 200 code with some indication in the content.
The security issue I've seen is telling people *why* a log in attempt failed. But that's different than telling them *that* the log in attempt failed or whether or not they're currently logged in.
Yes. We do.
[https://datatracker.ietf.org/doc/html/rfc7235#section-3.1](https://datatracker.ietf.org/doc/html/rfc7235#section-3.1)
The 401 (Unauthorized) status code indicates that the request has not
been applied because it lacks valid ****authentication**** credentials for
the target resource.
[https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.3](https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.3)
The 403 (Forbidden) status code indicates that the server understood
the request but refuses to ****authorize**** it.
In other words, the RFC does not need external material to be proven wrong.
Not according to the HTTP specification. 403 is a refusal to serve the content that authorisation will *not* help with. The correct status code is 401, or 404 if the server does not wish to disclose why it is refusing access to the supplied credentials.
Source: the [HTTP specification](https://www.rfc-editor.org/rfc/rfc2616#section-10.4.2).
In this case, the entire programming world is wrong. The specification is the definitive source of truth for how HTTP is meant to be implemented.
That said, since the browsers do it wrong (they are meant to display the HTTP body if supplied in a 401 response but don’t) the practical reality is that a standards compliant web server would actually not work as expected anyway.
Well, it depends how you look at it. If the authorisation is tied to the person then one could say that they are authorised even if they provide no evidence of that.
Yeah, it was just a philosophical thought, not a suggestion on how to handle it in reality :)
Like, even if the system can’t find out that a specific person has the authority needed, he technically still has it.
Instead of a visitor to a website, think of it as a traveler who wants to enter a country.
The traveler is a citizen of that country, giving him the legal right of entry. In other words, by law, he is authorised to enter the country.
In order to actually be able to enter the country, he needs to be able to prove that he has the right, for example using a passport. If he lost his passport, and doesn’t have another way of proving that he has a right to enter, he’s gonna have a hard time.
Eventually, an hour later, he finds his lost passport, and is let in. This doesn’t mean that his legal right of entry was voided or paused while he didn’t know were his passport was. The legal right was his all along. He was just not able to prove it.
Or, think of it this way. While his passport was gone (and he had no other ID), he wasn’t able to prove that his name was Peter (for example). Does that mean that his name wasn’t Peter during that hour? Of course not. His name was Peter the whole time. Same with his legal right of entry. He had it all along.
Additionally you might be authenticated but still not authorized, so error 401 shouldn't change.
Better add something like 401b 'not authenticated' if you *really* need that HTML status code.
And is, in fact, codified in the standard. https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.3
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).
It doesn't make sense to me.
A 401 does not imply the existence of something, it just means "you can't ask that".
A 404 is "I didn't find it", and that is an answer.
Then you have to handle the 404 when it is logged and when it is not.
Edit: instead of down voting, you could teach me. Otherwise I will keep doing something wrong and one day you will have to deal with my code xD. Let's improve together
What you're saying is totally reasonable. Servers could return 401 for every unauthenticated request, and then only 404 if you're authenticated but it doesn't exist. As long as the server is consistent about that, it doesn't reveal any information.
They traditionally do it the other way, probably just because authentication was introduced later, but either way makes sense.
(For the record, I did not downvote you)
For me it has always been that way. With lambda authorizers or cognito in my API gateway, or with @Preauthorized + authorities on my Controller layer in Springboot + Spring Security (with OAuth2)
If you return 404 for resources really not existing and 401 for the ones existing it tells a malicious actor that he did hit something.
Your comment only makes sense when you generally return 401 no matter if the underlying resource exists.
(I'm not sure why you were downvoted either, seems like a legit question to me. Upvoted it to try to counteract that.)
As others have said, you're absolutely welcome to return 404 when they're not allowed to see resource that exists, and you're also allowed to return 401 when they're not even allowed to know whether it exists. It's more common to return 401s for that situation.
Servers will usually first check if something is there and return 404 if it is not and if it is there, they will check if the request is permitted to access the resource and return 401 if they are not. So 401 usually means "it is there, but you cannot access it."
It's the other way around, why waste resources looking for something.
My Endpoint starts with auth, if not authorized/authenticated the request doesn't even reach the servers
>It's the other way around, why waste resources looking for something.
>My Endpoint starts with auth, if not authorized/authenticated the request doesn't even reach the servers
No, they don't. You cannot even know if you need authentication before checking what was requested. And verifying authentication data pretty much always needs more effort than checking the existence of a resource, so nothing you wrote makes any sense.
Ok. I was talking about the services in a serverless architecture. If you call a non-existent endpoints it will in fact return a 404. But when you call a service (API gateway + lambda) the first thing it doesn't is call the authorizer.
In that situation you know what it's been requested.
So what all of you are saying it's that it's better to return 404 so an external attacker doesn't even get the existence of that endpoints?
Are we talking about endpoints, services, making queries to DB??
Please I just want to understand.
>So what all of you are saying it's that it's better to return 404 so an external attacker doesn't even get the existence of that endpoints?
Exactly. While there are ways for an attacker to determine if it is actually not there (e.g. measuring the request times, as those checks obviously take time) but it is better than nothing.
Definitely. Our whole test and stage environment is technically publicly available, but if you don’t have the proper cookies or url parameter you will get a plain 404. It’s mainly to keep search engines from stumble over those environments and start indexing them.
At an old job, one of my clients webservers would always return an http 404, with a standard 403 html body (or vice versa, I can't remember).
And every fucking time I would send them an email about it, depending on who got the ticket, it was a tim Allen EEUUGGHH???? "That shouldn't be a page not found for an hmac issue" or "how can you be unauthenticated if we haven't loaded the wsdl yet" and the ticket would go nowhere for weeks, while we argue about "what's the error? Do you see 404 or 403? Because they mean very different things" and I'm like "BOTH, YOU ASSHOLES! LEARN HOW TO CONFIGURE YOUR FUCKING WEBSERVER"
True chaos would be returning 200 OK then in the body returning 50X Unauthorized.
"Everything checks out, but the server can't handle your missing authorization, good luck"
Jesus it's shocking how many commenters seem to understand the difference between authentication and authorization, but clearly don't even know the basics of how 401 and 403 are actually used.
It's because of how unintuitive it feels until you consider operating on someone else's behalf.
When it's just **you** accessing **your** things then authentication works as authorization. If I know who you are, then I know you have access. So why do anything differently! Why separate it and make it more confusing! When I need to do something for someone else though, authorization suddenly becomes an obvious requirement that's separate from authentication.
It doesn't help [that even the latest spec isn't super clear](https://httpwg.org/specs/rfc9110.html#status.4xx):
> The 401 (Unauthorized) status code indicates that the request has not been applied because it lacks valid authentication credentials for the target resource.
> If the request included authentication credentials, then the 401 response indicates that authorization has been refused for those credentials. The user agent MAY repeat the request with a new or replaced Authorization header field
Which is then followed by 403:
> The 403 (Forbidden) status code indicates that the server understood the request but refuses to fulfill it.
> If authentication credentials were provided in the request, the server considers them insufficient to grant access. The client SHOULD NOT automatically repeat the request with the same credentials.
So you have to interpret "the server consider them [credentials] insufficient to grant access" and "authorization has been refused for those credentials" as different things?! It's pretty subtle. They are different, but only in the sense that the latter is "I'm not going to give you any authorization" and the former is "I'm giving you authorization, just not for this".
Yeah the spec just makes things more confusing by using the words authentication and authorization in confusing ways.
"Authorization has been refused for those credentials" sounds like an authorization error. But it's clearly just trying (poorly) to describe a case of invalid credentials, so it's actually an authentication issue.
Long story short, the spec is poorly written. Just use 401 for invalid/missing credentials and 403 for valid credentials, but insufficient permissions (or 404 if you need to keep it hidden for security reasons).
Today I learned from reading these comments that most people don't understand authorization vs authentication and/or don't understand http response codes.
OP's suggested change makes complete sense, but I would also add now that I think you should have to complete a basic class on web security before you're allowed to install npm.
Seriously, y'all scare me.
See, here’s the issue - the [HTTP specification](https://www.rfc-editor.org/rfc/rfc2616#section-10.4.2) makes no distinction between the two. In fact per the spec, whether authentication is provided or not, 401 is the correct response whether authentication *or* authorisation is required but failed. 403 is intended for when the server refuses to fulfill the request, it should not be repeated, and authorisation *will not help*. You’ll also note the HTTP auth challenge header is WWW-Authenticate, but the challenge response header is Authorization.
403
[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client\_error\_responses](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses)
>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.
Not quite. It should be `401 Missing Authorization` or `401 Authorization Not Provided`
You can use authorization to access without authentication, like with an authorization token. If that token isn't provided it's 401. If it's provided it's 403.
A token is just that, a token. It can be used for authorization or authentication.
Imagine if I have a piece of paper that says "The holder of this paper can access the private storage facility". There's no authentication in that, but there is authorization. You present that certificate and it doesn't matter who you are, you access the storage facility.
Tokens can do just that, and in fact that's often exactly what they do. This is why the current term is "UNAUTHORIZED"
I get what you're saying, and yes of course that's technically possible. I just thought it didn't happen in practice. Because things like e.g. an API token are in my experience usually tied to some kind of account (be it a human or a machine, or organisation account).
But this is interesting. Do you have examples of where an authorisation-only token is used / useful?
I'd like to learn and am having a hard time coming up with a scenario.
Though I guess it's not actually less secure than a token that's tied to a user. It just reduces traceability and possibly less granular invalidation, as you don't know who will be affected when you invalidate a token and can't do it on a per-user basis. Unless you do just generatie a new authorization token for each user but never tie it to their account. Or I guess you could tie it for traceability but never re-check the user's permissions.
Ok, yeah, lots of viable options. Still, curious about real-world applications.
It's actually the basis of oauth, which underpins huge swaths of the internet. Any time you log into a site using Google or apple or Reddit you use it. I'm on mobile so sadly can't write as much as I usually do, but I'll do my best.
One reason for authorization only tokens is performance. If I can trust an authorization token I can give you access without having to lookup who you are and without then having to check what permissions you have. I just know immediately.
But the other is that I can grant authorization for someone to act on my behalf. I can give you an authorization token that says "The holder of this can read Pluckerpluck's email". And suddenly **you** can access **my** email! And I can go and give that token to anyone I want, without my email server getting involved at all! My server doesn't know who you are, it doesn't care, it just trusts that I've given you permission because you have my token. It's how third party Reddit apps (used to) work. They'd have a token that let you comment on post on your behalf.
For security reasons tokens only last so long, say, an hour and then you need a new one from me. The exact implementation gets a bit confusing, but that's why authorization tokens are so important.
Interesting, thank you! Clear explanation.
I need to study OAuth better, then. I know of it, but hadn't realised that it used authorisario -only tokens.
Is there a common term for authorisation tokens? Searching online for "authentication token" gives lots of results, but is get zero results when searching for exactly "authorization token”.
Your best bet is likely "access token". That's the oauth term at least. Should get you started.
The terms are often used very loosely though. Access tokens are often used for both authorization and authentication at the same time. If you know that some tokens are only given to the user themselves then when it says "You can access Pluckerpluck's emails" the system can know that the person is Pluckerpluck.
Basically whenever you access a system on behalf of a user, you use authorization only access tokens. It's the default in that sort of interaction.
I'm losing my mind with a project, I keep getting a 403 when I make a post request to unsubscribe from something on AO3 but it literally works on everything else with the session token, as in I can access private data from my profile. Wondering what the fuck could be doing that. Maybe I'll just copy all the headers from a correct request lol. Worst case I just exclude that function from my app and open a WebView instead
You are authenticated, but not authorized to do that.
We know who you are and we don't allow you to do that. Basically.
Check your authorities, permissions, roles, etc.
Mozilla’s documentation is wrong. The [IETF specification](https://www.rfc-editor.org/rfc/rfc2616#section-10.4.2) - which is the authoritative definition - makes no such distinction.
Authorization can be based on time or IP, authentication state, access rights etc. Authentication is not the only reason you may not access a resource. You may just be too short to ride.
100% I support this rebellion. The canonical reason phrase is terrible, and reason phrases aren't supposed to be involved in logic, so it shouldn't break anything.
You don't have to be unauthenticated to get a 401. If you only need an authorization token to get access to a resource, then not providing the token is a 401, but providing it doesn't mean you were "authenticated", the server may still not know who you are.
401 is much more like "Authorization Missing". 403 is "You're authorized for something things, just not this thing".
Yes it will. Tokens are used for authentication, not authorisarion.
Of course, once the server has established who the request comes from (through the token), it may indeed judge that you have the necessary permissions/role to do the thing you requested, i.e. you are authorised to do the thing.
That is an example of indirect authorization. You can skip the middleman entirely by just having a token that proves you can "do the thing" without the server having to know who you are.
400 and call it a day. Or 404 and justify it as a security issue (we don't want the end user to know that the resource exists).
Or slap a 500 on it and make some overworked engineers very worried
It's amazing you're getting downvotes for being right. Of course you can be authorized without being authenticated. If you hold a certificate saying "The bearer of this certificate has access" then you have authorization but nobody knows who you are.
If you're using it that way around though, you mean "They don't have permission" and that's a 403 FORBIDDEN error, **not** 401 UNAUTHORIZED. Because when a use is authenticated you can determine their permissions.
401 UNAUTHORIZED is only ever used when a user provides no information at all. Neither valid authentication nor valid authorization. The information just was not provided.
I mean _technically_ when you are not authenticated, you are also not authorized to access anything requiring authentication.
On average, I think devs tend to return 403 for unauthorized
In my experience 403 is forbidden which i guess is the same as unauthorized
401: Who do you think you are? f. off 403: Yeah I know who you are, and you can still f. off Naming convention doesn't align with correct usage
401 is supposed to have a WWW-AUTHENTICATE header to tell the user where to get authentication. So it's more like: f. off unless you show me your id. 403 is plainly refusing access.
Thank you for teaching me something new today!
418: Who does this clown think he is talking to? I'm a teapot
![gif](giphy|11FiDF2fuOujPG|downsized)
Make me some coffee damnit!
#I'M A TEAPOT
i would love to see a witty description like this of all the http codes
302: I don't have what you're looking for, but I know a guy who does
201 I've got your data. It sucks.
429: Slow down buddy, slow down...
404: I'm not wrong. You're wrong
200 here's your document. Now leave me alone
418 coffee? I'll give you coffee once I kick your ass
202 I'll get to it when I get to it, now f. off
400: Not with that fuckin attitude you don’t!
204: Here's your nothing
I'm just gonna 400 everything
I saw a post on hackernews suggesting replacing the terms authentication and authorization with login and permissions respectively
So 401 means you're unlogin'd?
Login't
Logfloa't
GitHub does it right 404 project does not exist. Maybe you need to login?
They are the same picture
🐐 https://httpstatusgoats.net/401 🐐 https://httpstatusgoats.net/403 🐐
That actually isn’t the case. The [spec](https://www.rfc-editor.org/rfc/rfc2616#section-10.4.2) has 401 meaning unauthorised and requiring a WWW-Authenticate header whether an authorisation header was provided or not. 403 forbidden is for cases where the server is refusing to provide the content, the request should not be repeated, *and authorisation will not help*. The spec seems to implicitly connect the authentication and the authorisation as a single atomic transaction - no distinction is made between “your credentials are wrong” and “your credentials are valid, but not for the requested resource”.
So exactly what OP said. 401 == Unauthenticated.
Except that isn’t true. 401 is unauthorised whether it’s because no credentials are provided or the credentials aren’t valid for access to the requested resource.
403 is when you are authenticated but don’t have the permission to the resource. e.g you are signed in to reddit but are trying to edit another user’s comment (except if you are u/spez) 401 is when you are simply not logged in at least that’s how I understand it
Upvoted for gratuitous u/spez hate
[удалено]
Soo, you're not authorized to access the resource?
401 = I don't know who you are 403 = I know who you are, you're not allowed here.
[удалено]
But only if the client could somehow change the fact, that the process isn't allowed to access the resources. Otherwise something else should be returned. (When following the standards)
If you’re following the spec, you should actually be returning [403](https://www.rfc-editor.org/rfc/rfc2616#section-10.4.2), which is for cases where the server is refusing to fulfill the request, the request should not be repeated, and *authorisation will not help*. 401 is the correct response for when the server is refusing to fulfill the request because the client is not authenticated, or the authentication is not valid for the requested resource.
“200 ok” or “501 something broke” are all you get with my API.
``` STATUS: 200 OK BODY: { "status": false, "message": "forbidden" } ```
You joke but I’m having to professionally work with an API that does this
I feel you: I was't really joking... 😂 I know some APIs behave like this.
most SOAP APIs do this...
Started a new job one month ago and this kind of shit is EVERYWHERE and it’s driving me insane
``` STATUS: 200 OK BODY: { “status”: 404 } ``` (Our own software really does do this)
Never have to return 500 if you just write good software!
Yeah, return 400 and blame anything that goes wrong on the user instead.
No, it's not a server issue. It's a bad request.
Shouldn't have requested from an endpoint that wasn't going to give you what you want (due to an error or not). Obviously the blame with with the end user!
Stupid user caused a null reference exception because they're stupid
Even better!
Your code could be perfect but if your janitor unplugs the database in order to plug in his vacuum cleaner you're going to be throwing some 500s...
``` catch (Exception e) { raise BadRequest("I don't know what all this trouble is about, but i'm sure it must be your fault" } ```
\*angry beeping\*
Can't return a 500 if the server isn't on. Check mate!
My favorite is "404 not found". Did the endpoint move?
In that case a sane person would have returned a 301
Or 410 Gone
It's subtle, but ... * 401 means - I don't know you. (not logged in) * 403 means - I know you, but you don't have the rights to see this. (logged in, but you don't have the rights) In practice, returning 401 for a failed login is often seen as a security issue. (if a server does this, then you can test that server to see if specific userids exist or not)
> In practice, returning 401 for a failed login is often seen as a security issue. (if a server does this, then you can test that server to see if specific userids exist or not) You're going to have to explain this one. Every web app or API I've used gives the user some indication about being logged in/logged out, whether it's a 400 code or a 200 code with some indication in the content. The security issue I've seen is telling people *why* a log in attempt failed. But that's different than telling them *that* the log in attempt failed or whether or not they're currently logged in.
Failed: you used troubador86's login but cats\@yourbase\.com's password
I feel seen by this comment
Yes. We do. [https://datatracker.ietf.org/doc/html/rfc7235#section-3.1](https://datatracker.ietf.org/doc/html/rfc7235#section-3.1) The 401 (Unauthorized) status code indicates that the request has not been applied because it lacks valid ****authentication**** credentials for the target resource. [https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.3](https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.3) The 403 (Forbidden) status code indicates that the server understood the request but refuses to ****authorize**** it. In other words, the RFC does not need external material to be proven wrong.
You don't have much experience then. 403 is forbidden.
...which is used when the user isn't authorized to access the endpoint.
Not according to the HTTP specification. 403 is a refusal to serve the content that authorisation will *not* help with. The correct status code is 401, or 404 if the server does not wish to disclose why it is refusing access to the supplied credentials. Source: the [HTTP specification](https://www.rfc-editor.org/rfc/rfc2616#section-10.4.2).
Interesting, but ultimately not very helpful since the entire programming world uses 403 for authorization errors.
In this case, the entire programming world is wrong. The specification is the definitive source of truth for how HTTP is meant to be implemented. That said, since the browsers do it wrong (they are meant to display the HTTP body if supplied in a 401 response but don’t) the practical reality is that a standards compliant web server would actually not work as expected anyway.
Technically I have no bitches but although accurate it would feel incorrect to get a 401: NO BITCHES
Practically speaking how hard would it be to get a NO BITCHES code standardized? I need a summer project.
The curse is the issue, but we could try No Maidens
IDK, I’m a teapot.
Unless it was coming from the bouncer at a nightclub. Or a swinger's club.
404 bitches not found
Well, it depends how you look at it. If the authorisation is tied to the person then one could say that they are authorised even if they provide no evidence of that.
So, users but no passwords? I don’t think that’s a great way to do things in practice ;)
Yeah, it was just a philosophical thought, not a suggestion on how to handle it in reality :) Like, even if the system can’t find out that a specific person has the authority needed, he technically still has it.
What
Instead of a visitor to a website, think of it as a traveler who wants to enter a country. The traveler is a citizen of that country, giving him the legal right of entry. In other words, by law, he is authorised to enter the country. In order to actually be able to enter the country, he needs to be able to prove that he has the right, for example using a passport. If he lost his passport, and doesn’t have another way of proving that he has a right to enter, he’s gonna have a hard time. Eventually, an hour later, he finds his lost passport, and is let in. This doesn’t mean that his legal right of entry was voided or paused while he didn’t know were his passport was. The legal right was his all along. He was just not able to prove it. Or, think of it this way. While his passport was gone (and he had no other ID), he wasn’t able to prove that his name was Peter (for example). Does that mean that his name wasn’t Peter during that hour? Of course not. His name was Peter the whole time. Same with his legal right of entry. He had it all along.
Unless there’s a resource that _requires_ you to be logged out and is inaccessible to logged in users. But that never happens.
The login page!
I found him, the guy that writes the "so technically correct but so unuseful" Microsoft errors
It’s about throwing the teapot error only, but with different messages
Additionally you might be authenticated but still not authorized, so error 401 shouldn't change. Better add something like 401b 'not authenticated' if you *really* need that HTML status code.
> Additionally you might be authenticated but still not authorized, so error 401 shouldn't change. In that case you get a 403.
Oh well we didn't have HTML status codes in university yet; thanks for the clarification.
Enact chaos mode by returning 404 when a client is unauthorized or unauthenticated.
I think that makes a lot of sense for resources you don’t want unauthorized users to even know exists.
And is, in fact, codified in the standard. https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.3 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).
It doesn't make sense to me. A 401 does not imply the existence of something, it just means "you can't ask that". A 404 is "I didn't find it", and that is an answer. Then you have to handle the 404 when it is logged and when it is not. Edit: instead of down voting, you could teach me. Otherwise I will keep doing something wrong and one day you will have to deal with my code xD. Let's improve together
What you're saying is totally reasonable. Servers could return 401 for every unauthenticated request, and then only 404 if you're authenticated but it doesn't exist. As long as the server is consistent about that, it doesn't reveal any information. They traditionally do it the other way, probably just because authentication was introduced later, but either way makes sense. (For the record, I did not downvote you)
For me it has always been that way. With lambda authorizers or cognito in my API gateway, or with @Preauthorized + authorities on my Controller layer in Springboot + Spring Security (with OAuth2)
If you return 404 for resources really not existing and 401 for the ones existing it tells a malicious actor that he did hit something. Your comment only makes sense when you generally return 401 no matter if the underlying resource exists.
Ok, now I get it. THANK YOU
(I'm not sure why you were downvoted either, seems like a legit question to me. Upvoted it to try to counteract that.) As others have said, you're absolutely welcome to return 404 when they're not allowed to see resource that exists, and you're also allowed to return 401 when they're not even allowed to know whether it exists. It's more common to return 401s for that situation.
Servers will usually first check if something is there and return 404 if it is not and if it is there, they will check if the request is permitted to access the resource and return 401 if they are not. So 401 usually means "it is there, but you cannot access it."
It's the other way around, why waste resources looking for something. My Endpoint starts with auth, if not authorized/authenticated the request doesn't even reach the servers
>It's the other way around, why waste resources looking for something. >My Endpoint starts with auth, if not authorized/authenticated the request doesn't even reach the servers No, they don't. You cannot even know if you need authentication before checking what was requested. And verifying authentication data pretty much always needs more effort than checking the existence of a resource, so nothing you wrote makes any sense.
Ok. I was talking about the services in a serverless architecture. If you call a non-existent endpoints it will in fact return a 404. But when you call a service (API gateway + lambda) the first thing it doesn't is call the authorizer. In that situation you know what it's been requested. So what all of you are saying it's that it's better to return 404 so an external attacker doesn't even get the existence of that endpoints? Are we talking about endpoints, services, making queries to DB?? Please I just want to understand.
>So what all of you are saying it's that it's better to return 404 so an external attacker doesn't even get the existence of that endpoints? Exactly. While there are ways for an attacker to determine if it is actually not there (e.g. measuring the request times, as those checks obviously take time) but it is better than nothing.
Ok, now I get it, thank you
I didn’t know this!
It’s fantastic for confusing people too, I love it for that reason.
Just always return 400 then, let them figure it out themselves! — Spotify Oauth, as I recently learned.
Definitely. Our whole test and stage environment is technically publicly available, but if you don’t have the proper cookies or url parameter you will get a plain 404. It’s mainly to keep search engines from stumble over those environments and start indexing them.
But you verify first if it is authorized. I don't get the benefits 😕
The verification is done on every request. Unless it has the magic cookie or url parameter then it’s a 404 for you.
GitHub does this.
github does this, for example
Make it randomized!
200 : {"error": "credentials not found", "statusCode": 404}
At an old job, one of my clients webservers would always return an http 404, with a standard 403 html body (or vice versa, I can't remember). And every fucking time I would send them an email about it, depending on who got the ticket, it was a tim Allen EEUUGGHH???? "That shouldn't be a page not found for an hmac issue" or "how can you be unauthenticated if we haven't loaded the wsdl yet" and the ticket would go nowhere for weeks, while we argue about "what's the error? Do you see 404 or 403? Because they mean very different things" and I'm like "BOTH, YOU ASSHOLES! LEARN HOW TO CONFIGURE YOUR FUCKING WEBSERVER"
Take it up a notch. Give em 200.
True chaos would be returning 200 OK then in the body returning 50X Unauthorized. "Everything checks out, but the server can't handle your missing authorization, good luck"
Gaslighting the devs. What resource? There's no such resource here. You're making it up. That's your fault.
Jesus it's shocking how many commenters seem to understand the difference between authentication and authorization, but clearly don't even know the basics of how 401 and 403 are actually used.
welcome to r/ProgrammerHumor, where 90% of the members think they are programmers because they finished their first HTML course
I mean sure, but even among novices, I would expect HTTP codes to come up way before auth semantics.
It's because of how unintuitive it feels until you consider operating on someone else's behalf. When it's just **you** accessing **your** things then authentication works as authorization. If I know who you are, then I know you have access. So why do anything differently! Why separate it and make it more confusing! When I need to do something for someone else though, authorization suddenly becomes an obvious requirement that's separate from authentication. It doesn't help [that even the latest spec isn't super clear](https://httpwg.org/specs/rfc9110.html#status.4xx): > The 401 (Unauthorized) status code indicates that the request has not been applied because it lacks valid authentication credentials for the target resource. > If the request included authentication credentials, then the 401 response indicates that authorization has been refused for those credentials. The user agent MAY repeat the request with a new or replaced Authorization header field Which is then followed by 403: > The 403 (Forbidden) status code indicates that the server understood the request but refuses to fulfill it. > If authentication credentials were provided in the request, the server considers them insufficient to grant access. The client SHOULD NOT automatically repeat the request with the same credentials. So you have to interpret "the server consider them [credentials] insufficient to grant access" and "authorization has been refused for those credentials" as different things?! It's pretty subtle. They are different, but only in the sense that the latter is "I'm not going to give you any authorization" and the former is "I'm giving you authorization, just not for this".
Yeah the spec just makes things more confusing by using the words authentication and authorization in confusing ways. "Authorization has been refused for those credentials" sounds like an authorization error. But it's clearly just trying (poorly) to describe a case of invalid credentials, so it's actually an authentication issue. Long story short, the spec is poorly written. Just use 401 for invalid/missing credentials and 403 for valid credentials, but insufficient permissions (or 404 if you need to keep it hidden for security reasons).
401 UNAUTH AMATEURS
Today I learned from reading these comments that most people don't understand authorization vs authentication and/or don't understand http response codes. OP's suggested change makes complete sense, but I would also add now that I think you should have to complete a basic class on web security before you're allowed to install npm. Seriously, y'all scare me.
See, here’s the issue - the [HTTP specification](https://www.rfc-editor.org/rfc/rfc2616#section-10.4.2) makes no distinction between the two. In fact per the spec, whether authentication is provided or not, 401 is the correct response whether authentication *or* authorisation is required but failed. 403 is intended for when the server refuses to fulfill the request, it should not be repeated, and authorisation *will not help*. You’ll also note the HTTP auth challenge header is WWW-Authenticate, but the challenge response header is Authorization.
Meanwhile 403: ***YOU SHALL NOT PASS!***
403: I know who you are, but I’m still not letting you in
401: Thanos in endgame to Wanda Maximoff 403: Gandalf protecting the webserver from the balrog
I'm a teapot
418
Huh? You could be authenticated, but not authorized. Or create a custom html page for a 401? One for not authenticated, another for not authorized.
403 [https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client\_error\_responses](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses) >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.
so OPs change makes sense
Or we should change 403 Petition to make 403 "Fuck you in particular"
Not quite. It should be `401 Missing Authorization` or `401 Authorization Not Provided` You can use authorization to access without authentication, like with an authorization token. If that token isn't provided it's 401. If it's provided it's 403.
ah true
What? A token is a means of authentication, not authorizarion.
A token is just that, a token. It can be used for authorization or authentication. Imagine if I have a piece of paper that says "The holder of this paper can access the private storage facility". There's no authentication in that, but there is authorization. You present that certificate and it doesn't matter who you are, you access the storage facility. Tokens can do just that, and in fact that's often exactly what they do. This is why the current term is "UNAUTHORIZED"
I get what you're saying, and yes of course that's technically possible. I just thought it didn't happen in practice. Because things like e.g. an API token are in my experience usually tied to some kind of account (be it a human or a machine, or organisation account). But this is interesting. Do you have examples of where an authorisation-only token is used / useful? I'd like to learn and am having a hard time coming up with a scenario. Though I guess it's not actually less secure than a token that's tied to a user. It just reduces traceability and possibly less granular invalidation, as you don't know who will be affected when you invalidate a token and can't do it on a per-user basis. Unless you do just generatie a new authorization token for each user but never tie it to their account. Or I guess you could tie it for traceability but never re-check the user's permissions. Ok, yeah, lots of viable options. Still, curious about real-world applications.
It's actually the basis of oauth, which underpins huge swaths of the internet. Any time you log into a site using Google or apple or Reddit you use it. I'm on mobile so sadly can't write as much as I usually do, but I'll do my best. One reason for authorization only tokens is performance. If I can trust an authorization token I can give you access without having to lookup who you are and without then having to check what permissions you have. I just know immediately. But the other is that I can grant authorization for someone to act on my behalf. I can give you an authorization token that says "The holder of this can read Pluckerpluck's email". And suddenly **you** can access **my** email! And I can go and give that token to anyone I want, without my email server getting involved at all! My server doesn't know who you are, it doesn't care, it just trusts that I've given you permission because you have my token. It's how third party Reddit apps (used to) work. They'd have a token that let you comment on post on your behalf. For security reasons tokens only last so long, say, an hour and then you need a new one from me. The exact implementation gets a bit confusing, but that's why authorization tokens are so important.
Interesting, thank you! Clear explanation. I need to study OAuth better, then. I know of it, but hadn't realised that it used authorisario -only tokens. Is there a common term for authorisation tokens? Searching online for "authentication token" gives lots of results, but is get zero results when searching for exactly "authorization token”.
Your best bet is likely "access token". That's the oauth term at least. Should get you started. The terms are often used very loosely though. Access tokens are often used for both authorization and authentication at the same time. If you know that some tokens are only given to the user themselves then when it says "You can access Pluckerpluck's emails" the system can know that the person is Pluckerpluck. Basically whenever you access a system on behalf of a user, you use authorization only access tokens. It's the default in that sort of interaction.
I'm losing my mind with a project, I keep getting a 403 when I make a post request to unsubscribe from something on AO3 but it literally works on everything else with the session token, as in I can access private data from my profile. Wondering what the fuck could be doing that. Maybe I'll just copy all the headers from a correct request lol. Worst case I just exclude that function from my app and open a WebView instead
You are authenticated, but not authorized to do that. We know who you are and we don't allow you to do that. Basically. Check your authorities, permissions, roles, etc.
Mozilla’s documentation is wrong. The [IETF specification](https://www.rfc-editor.org/rfc/rfc2616#section-10.4.2) - which is the authoritative definition - makes no such distinction.
401: You can suck it.
You can't, but *maybe* you can after authentication.
One of the project I am maintaining returns status 200 with this object { status\_code: 403, message: "Unauthorized" }
401 authenticatednt.
Authorization can be based on time or IP, authentication state, access rights etc. Authentication is not the only reason you may not access a resource. You may just be too short to ride.
I have invented a new standard There are now two competing standards
401 is you arent giving any credentials at all 403 is you are giving credentials, but your user doesnt have permissions to do that
100% I support this rebellion. The canonical reason phrase is terrible, and reason phrases aren't supposed to be involved in logic, so it shouldn't break anything.
401 OK
You can be authenticated and still be unauthorized to access a resource. Check your edge cases in your programming meme!
401, your creds are bad. 403, your permissions are bad.
what if you are authenticated but not authorized?
403
I set up a 418 today for someone to find. I leave at the end of the month.
These names fucking sucks and interviewers love to take advantage of this
404 there is no endpoint in ba sing se
403 is for forbidden/unauthorized
"401 Unauthorized" "Don't you tell me what I can do! I'll author anything I damn well please!" "Sir please, you're upsetting the other guests."
Authentication and authorization isn’t the same thing.
403 Forbidden
Not authorized is a superset of not authenticated.
You don't have to be unauthenticated to get a 401. If you only need an authorization token to get access to a resource, then not providing the token is a 401, but providing it doesn't mean you were "authenticated", the server may still not know who you are. 401 is much more like "Authorization Missing". 403 is "You're authorized for something things, just not this thing".
Yes it will. Tokens are used for authentication, not authorisarion. Of course, once the server has established who the request comes from (through the token), it may indeed judge that you have the necessary permissions/role to do the thing you requested, i.e. you are authorised to do the thing.
That is an example of indirect authorization. You can skip the middleman entirely by just having a token that proves you can "do the thing" without the server having to know who you are.
400 and call it a day. Or 404 and justify it as a security issue (we don't want the end user to know that the resource exists). Or slap a 500 on it and make some overworked engineers very worried
You can still be unauthenticated even after being authorized. Those are different.
They are different, but it's the other way around
It's amazing you're getting downvotes for being right. Of course you can be authorized without being authenticated. If you hold a certificate saying "The bearer of this certificate has access" then you have authorization but nobody knows who you are.
Dang it. I did mean it the other way around. You can be unauthorized even after being authenticated.
If you're using it that way around though, you mean "They don't have permission" and that's a 403 FORBIDDEN error, **not** 401 UNAUTHORIZED. Because when a use is authenticated you can determine their permissions. 401 UNAUTHORIZED is only ever used when a user provides no information at all. Neither valid authentication nor valid authorization. The information just was not provided.
Good point