[HN Gopher] Using www-authenticate for user authentication
___________________________________________________________________
Using www-authenticate for user authentication
Author : blmayer
Score : 54 points
Date : 2022-02-18 13:55 UTC (9 hours ago)
(HTM) web link (saucecode.bar)
(TXT) w3m dump (saucecode.bar)
| foreigner wrote:
| Why is this preferable to authentication using cookies?
| mrtesthah wrote:
| The web server can directly handle your authentication and
| accounting system rather than needing to include more huge
| middleware frameworks.
| munk-a wrote:
| Just to clarify - are you calling cookie support a huge
| middleware framework?
|
| Both BasicAuth and Cookie reception are features included in
| nearly every browser offering - it's generally how you
| actually check resource authorization that's the hard part of
| Auth - the actual technical "Get a cookie from a browser" and
| "Check the BasicAuth headers" portions are pretty simple - in
| fact getting a cookie is arguably easier in most cases.
| Especially since a popular serverside programming language
| (PHP) has streamlined session handling to the point that most
| programmers going from it to other serverside languages get
| confused when there isn't a $_SESSION equivalent that you
| just inspect with the tap of a button.
| n0w wrote:
| Why would `Authentication` be any different to `Cookie` in
| this regard? They're both HTTP headers. They both require
| server side support/implementation. Neither explicitly
| requires JavaScript.
|
| The only difference I can see is that the browser has a
| native control for one of them, though that control cannot be
| customised by the site.
| 0xbadcafebee wrote:
| I see an authentication pop-up and groan. If I leave it there
| it'll time out, if I hit 'escape' or my login fails I'll get some
| generic HTTP server error screen. No password reset box, no
| contact form, no OAuth/SSO login button.
| lil_dispaches wrote:
| Hm, why have browser vendors neglected the UX for this
| standard, no-cookie auth method? Why is there no corresponding
| markup in HTML5?
| thesuitonym wrote:
| It happens in HTTP, before any HTML5 is rendered or even
| sent. Why have browser vendors neglected it? I suppose it's a
| chicken/egg problem. Nobody really uses it, so why spend
| effort on it? No effort is spent on it, so it's stuck in the
| 90s, why would anyone use it?
| munk-a wrote:
| There isn't anything in the standard to support a "Go here to
| reset your password" link or a "Go over here to create an
| account" - I really appreciate HTTP auth for somethings - but
| it's not great if you don't have a user base that is
| registered for your site through some non-web based
| interaction. It's certainly possible to have a user creation
| flow that ends up auth'ing with Basic Auth but it's not
| particularly user friendly.
| jeroenhd wrote:
| The browser could redirect the user to a form after
| cancellation or a certain amount of failures (say, 3 or 5)
| with recovery options. Add a nice retry button on there and
| you've got yourself a very simple login flow.
|
| Stock nginx/apache configurations will basically let the
| user retry infinitely or show a plain error page after user
| authentication fails too often, but these pages are
| configurable and don't need to be handled by the web server
| itself.
|
| One thing this mechanism doesn't provide is brute force
| protection through systems like CAPTCHAs.
| munk-a wrote:
| Logging in and password recovery are two tasks that
| usually happen to extremely fatigued users. I'd like to
| briefly state that I absolutely loathe a lot of modern
| design decisions when it comes to authentication flow -
| the two page challenge system (first U/N then password)
| in particular provides an overly opaque login process
| that breaks a lot of password managers. _That said_ -
| forcing the user to fail to auth before they can land on
| a page that lets them recover their password is a bad
| design. A lot of users know they 've forgotten their
| password before they even try typing it. If it takes 3-5
| failures to actually get the information on how to
| recover an account you'll lose a few users before the
| first failed attempt (they'll just walk away from your
| site) and most users by the time they've failed twice.
| Users have been trained that three failed login attempts
| can lock you out of an account - most will not just spam
| "blakdnasfnasnjsaja" into the password box three times in
| the hope that it gives them a forgot your password
| prompt... nearly none will do that five times.
|
| On every page or widget you ask for authentication for
| you should have a clear nearby link that says "Forgot
| your Password?" this link shouldn't be in the standard
| information display text color (i.e. maybe black or a
| soft grey) and un-underlined because "it looks slick" -
| it should be obvious as hell, it's probably one of the
| best places to make sure of the old "color: blue; text-
| decoration: underline" styles[1] just so that users that
| are unfamiliar with your standard link coloration have
| absolutely no confusion.
|
| I consider myself to generally not be a design oriented
| person, but I've seen this particular mistake cost so
| much business over my career that it is a hill I'm
| willing to die on. "Forgot your password" links need to
| be clear and constantly accessible - you should push back
| aggressively against anyone who wants to pop a little
| paper clip in there with a speech bubble of "It looks
| like you may be having trouble logging in" or anything
| else that deviates from those three words. When we're
| frustrated with a site we all just want to see "Forgot
| your password?" in blue and know immediately what we need
| to do - we never want to need to endure your design
| decisions or technical limitations to get there.
|
| This component needs to be easy.
|
| 1. Ubisoft is a great example of this - they've got an
| extremely javascript laden login page for UPlay and yet
| "Forgot your password?" is written using that precise
| three word spell and is in "I'm a link from the 90s" blue
| - they decided to remove the underlining which is a
| frequent design decision these days (one I disagree with)
| but otherwise they're making it as blatant as possible
| https://account.ubisoft.com/en-US/login There's a bunch
| of stuff I'd complain about on this page (including the
| fact that on my browser on a 1080p screen I somehow end
| up with two different scroll bars) but it knows what's
| important.
| jeroenhd wrote:
| > If it takes 3-5 failures to actually get the
| information on how to recover an account you'll lose a
| few users before the first failed attempt
|
| That's why you should also show the information when they
| cancel the prompt. Users will click the login link
| (because that's where password recovery is normally
| located), see a login popup, click close or cancel, and
| be greeted by a recovery page. No need to fill in fake
| info that way.
|
| There's also no reason not to link to the recovery page!
| You could just as easily add a link underneath or next to
| the big green buttons that say "login" and "register". It
| all depends on how barren ("clean") you want your front
| page to be.
|
| I abhor modern authentication systems (Google and
| Microsoft don't even show the password field next to the
| username field anymore for fuck's sake, you have to pass
| some kind of AJAX/Javascript validation logic), that's
| why I want authentication to return to the browser
| itself. There's a lot to be fixed regarding browser auth
| UI, most importantly better password manager integration,
| but taking auth flow control away from over-eager web
| designers can solve a lot of usability issues.
|
| Browser auth is actually quite successfully implemented
| on mobile through U2F. I can click login, tap my thumb on
| the fingerprint sensor, get directed to a recovery/signup
| page if my device has no keys for that website or get
| authenticated automatically. On the desktop side TPMs
| should become available more often now that Windows 11
| requires them (macs already have their own TPM
| implementation, of course). The quicker websites adopt
| this flow, the easier auth will become. That said, I've
| seen webauthn sites that don't ask you to validate your
| email after signing up, and that's a recipe for disaster,
| so the system isn't 100% perfect.
| qbasic_forever wrote:
| I've read it's partly for security. If browsers started to
| let you style and change the login UI then nothing is
| stopping bad-website.com from making it look like your bank's
| login site and fooling you. Yes you should be checking the
| URL, the SSL certs, etc. and not entering your password
| blindly... but real people don't do that even though they
| should. So the thinking is the browser will completely
| control the login form and make it super generic and obvious
| exactly what website you are logging into.
| jeroenhd wrote:
| There's something to be said to only allow limited
| customisability when it comes to native browser controls. The
| window is native to the browser, so there shouldn't be any
| way for the website to make it appear as if the browser
| itself is stating something that the website is stating.
|
| As a developer, the browser login popup follows your users'
| preferences rather than yours. That's also a net positive in
| my book.
| ezekiel68 wrote:
| Nothing prevents serving this style of login from a front page
| that offers everything you just mentioned as an alternative.
| Groaning may express dismay but -- this is mere inconvenience
| we're dealing with here.
| lil_dispaches wrote:
| How do you get the browser to send the Authentication header
| for every request thereafter? Typically you Auth once, and
| set cookies which the browser sends automatically with each
| HTTP request, even if the user is not on your domain.
|
| You would have to rewrite HTML5 and handle all HTTP traffic
| manually to set the Authentication header for every request.
| OP's trick of HTTP + ancient browser spec for handling basic
| auth triggers automatic sending of the Auth header for all
| requests.
| jeroenhd wrote:
| As the article states:
|
| > the nice thing about this is that the browser will keep
| sending the credentials to subsequent requests of the same
| domain until it receives a 401 status as response.
|
| You don't need to set anything, just send a 401 if you want
| the browser to stop sending credentials. You don't even
| need cookies.
| toast0 wrote:
| You can serve this style of login from a front page, but then
| the user gets the unstyled, limited context browser prompt
| before they see your site.
|
| There's no button to create a new account or find a forgotten
| password. There's no reasonable way to logout. It's usable
| for a site with a trainable user base, like a small club or
| employees, but I wouldn't expect anything intended for public
| use to do it. I've experienced one public site that used it
| for its members only (subscription) content, but I think
| they've switched to forms and cookies.
| jeroenhd wrote:
| From the article:
|
| > the nice thing about this is that the browser will keep
| sending the credentials to subsequent requests of the same
| domain until it receives a 401 status as response.
|
| The logout button can simply redirect to a static page that
| returns a 401.
| jeroenhd wrote:
| A website that needs fallback support (for whatever reason) can
| always redirect to a web form login page that does little more
| than let you fill in your username/password and then navigate
| to https://user:password@website.com/. I don't know how well
| that works with authentication systems other than basic auth,
| but it's generally well-supported across the board.
|
| The generic HTTP server error screen is merely an
| implementation detail. It's a result of people using HTTP Basic
| auth for a quick & dirty login mechanism rather than actually
| putting effort in.
|
| This protocol combined with modern alternatives (like WebAuthn)
| should make for excellent accessible authentication mechanisms.
| It's a shame browser support is so mediocre (for example,
| password managers + HTTP auth can only work without user
| interaction) because the browser is perfectly capable of doing
| everything your usual boilerplate login page does.
|
| As for SSO, the system supports Kerberos authentication, so
| using this rather than a custom HTTP login flow might actually
| make your users' lives a lot easier in some cases!
| citrin_ru wrote:
| Responses for HTTP errors can be customized to include things
| like password reset and contacts. See e. g.
| https://nginx.org/r/error_page
| thesuitonym wrote:
| You could have a custom 403 page that allows a user to reset
| their password and has a contact form. You are right about the
| lack of SSO, but not everything needs to support SSO.
| EvanAnderson wrote:
| The poor UX for HTTP authentication in browsers makes it a non-
| starter. I really like APIs that use HTTP authentication,
| however.
| cjm42 wrote:
| The big problem with this is that mobile Safari on iOS won't
| autofill passwords for sites using WWW-Authenticate. It used to,
| but that feature got dropped years ago, which really ticks me
| off, as I regularly use a couple of sites that use it.
| irq-1 wrote:
| If this is new to you, you can also include the username and
| password in the url:
|
| https://user@example.com/page
|
| https://user:pass@example.com/page
| gwbas1c wrote:
| The problem is that many proxies will log passwords sent this
| way.
| caylus wrote:
| Over HTTPS? I don't see how that's possible unless they are
| TLS-MITM proxies, in which case you've completely lost
| regardless of your authentication method.
|
| Placing the username and password in the URL results in the
| same TLS-protected HTTP header as normal basic
| authentication: $ curl -v
| https://user:pass@example.com/page [...] >
| GET /page HTTP/2 > Host: example.com >
| authorization: Basic dXNlcjpwYXNz > user-agent:
| curl/7.77.0 > accept: */* >
|
| Even over HTTP, a proxy that intentionally logs the URL
| accessed would not see the username and password in the
| initial "GET" line. It would have to go out of its way to
| extract it from the Authorization header, which is still
| present regardless of how the basic authentication was
| initiated.
|
| If you meant user agents logging the username and password as
| part of the history, I suppose you could consider that a bug
| but it could also be considered a feature. Presumably if
| you're using a URL of that form your intent is in fact to be
| able to link or bookmark the URL including the credentials.
| djbusby wrote:
| I've noticed many times the browser won't send those from the
| link. I was trying that with services where I owned both sides
| and my pre-authenticated links weren't sending the credentials.
| But using the same URL via curl was authenticated.
| jjice wrote:
| I believe the major browsers deprecated this a little while
| ago. You can still use basic auth and everything, just not
| via a URL like this.
| remram wrote:
| On Firefox, I just get a warning: "You are about to log in to
| the site "news.ycombinator.com" with the username "test""
|
| I'm not entirely sure what the concern is to be honest. If
| it's tracking, this doesn't provide anything on top of query
| parameters e.g. ?utm_campaign=
| jeroenhd wrote:
| Looking at the MDN page [1], I noticed that SHA2-256 digest
| authentication was added relatively recently to Firefox (and
| Firefox for Android). I wonder why they added it, as no other
| browser manufacturer seems to care and the added benefit of using
| digest rather than basic auth is only minimal now that every
| decent website has TLS.
|
| Also, interestingly, the support matrix suggests that Firefox for
| Android supports Kerberos and NTLM authentication. I guess I
| never expected Kerberos for websites to show up outside of
| desktop browsers.
|
| [1]: https://developer.mozilla.org/en-
| US/docs/Web/HTTP/Headers/WW...
| jonahbenton wrote:
| Having to do an authentication check on every request is
| suboptimal, but ok in many cases. It's just very unfortunate that
| more protocol explicitly directing secure interactions between
| the user and the _user-agent_ in managing identity and
| authentication never really emerged.
| password4321 wrote:
| There's also NTLM and Negotiate (Kerberos).
|
| https://caniuse.com/?search=www-authenticate
| ale42 wrote:
| Funny that old things like basic HTTP auth are regularly
| rediscovered by developers.
|
| There are also other flavours of authentication that can be used
| in this context, like Digest, supported by all major browsers and
| only sending hashed passwords (even on plain http connections).
| boondaburrah wrote:
| I looked it up and the apache manual apparently recommends HTTP
| basic over SSL instead of Digest these days since apparently
| the extra protection isn't considered as worth it relative to
| just HTTPS-ing the connection.
| [deleted]
| bullen wrote:
| A long time ago we had to work around disabled cookies by
| appending the session to every request URL... that was a fun
| time adding the session to all those <a href>...
|
| But for the simple hashing it's an old RFC that I like to quote
| to HTTPS fools: https://datatracker.ietf.org/doc/html/rfc2289
|
| Way better login than moving your whole site, including cat
| pictures, to encryption.
| jamespwilliams wrote:
| Digest auth itself isn't very good though really, even ignoring
| the obvious problems of not using HTTPS.
|
| In the most secure configuration of digest auth, the server
| stores MD5(username:realm:password), and to authenticate, the
| server sends server_nonce, and the client sends back
| client_nonce and
| MD5(MD5(username:realm:password):server_nonce:client_nonce).
| The nonces are used to avoid a replay attack. The server MD5s
| its stored hash with server_nonce:client_nonce and checks if it
| matches against what the client sent.
|
| But if those stored hashes get leaked, an attacker can use them
| to authenticate. You're in a better position than storing
| plaintext passwords, because the underlying cleartext probably
| won't be leaked (they're hashed with MD5, so it's not certain),
| so your users' credentials can't be used in future credential
| stuffing attacks, etc. But the attacker still has their
| credentials on your site.
|
| In the other configurations of digest auth, the server ends up
| storing plaintext passwords (or reversably-encrypted passwords,
| which is just as bad).
|
| See also
| https://en.wikipedia.org/wiki/Digest_access_authentication#D...
|
| Using HTTPS + Basic Auth is far more secure, and (arguably)
| easier at this point.
| bullen wrote:
| I don't understand your point, if the database is leaked the
| security is compromised... well yes red is red, and green is
| green and HTTPS improves NOTHING of that.
|
| HTTPS is a huge waste of electricity.
|
| A more frugal way of securing logins is to use this RFC:
| https://datatracker.ietf.org/doc/html/rfc2289
|
| Registrations would need additional security but HTTPS with
| centralized root certificates is NOT one of them.
| thayne wrote:
| You shouldn't store a password in plaintext in your
| database. So if your database is leaked, they don't have
| the user's actual passwords. But with the digest scheme,
| you can't store a hash of the digest, because if all you
| have is Hash2(Hash1(username:realm:password)) and the
| nonces, then you can't compute Hash1(Hash1(username:realm:p
| assword):server_nonce:client_nonce), assuming that Hash2 is
| irreversible, which you want it to be.
| bullen wrote:
| > Hash1(Hash1(username:realm:password):server_nonce:clien
| t_nonce)
|
| client_nonce?
|
| This is how the RFC works:
| Hash(Hash(username:password):server_nonce)
|
| What is the difference between Hash1 and Hash2?
|
| Hash(username:password) is what you store in the database
| != plain text.
|
| Also what is realm?
| thayne wrote:
| > client_nonce?
|
| Yes, the client also generates a nonce that is included
| in the digest. The full digest (according to RFC 2617) is
| (assuming qop is used):
|
| request-digest = <"> < KD ( H(A1), unq(nonce-value) ":"
| nc-value ":" unq(cnonce-value) ":" unq(qop-value) ":"
| H(A2) ) <">
|
| > What is the difference between Hash1 and Hash2?
|
| Hash1 is the hash algorithm for the authorization digest,
| so MD5 or maybe SHA256 (although only firefox currently
| supports that). Hash2 is the hash algorithm (including
| salting) used on the server to hash the hash of the
| username password before storing in the database.
|
| > Hash(username:password) is what you store in the
| database != plain text.
|
| The password isn't plaintext, but if the
| Hash(username:password) is compromised that gives an
| attacker enough information to impersonate that user. The
| attacker can just use that `Hash(username:password)` to
| compute the digest, they don't need to know the original
| password.
| bullen wrote:
| Yes, again if the database is compromised, it's
| compromised... I don't understand why so many people keep
| mentioning that when HTTPS does not solve that either?!
| thayne wrote:
| If a database of passwords is compromised, but the
| passwords are properly hashed and salted (server-side,
| not client-side), then you would need a rainbow table for
| each salt in order to actually get something usable from
| the compromised data.
| catlifeonmars wrote:
| This is vulnerable to 2nd preimage attacks. As a rule of
| thumb, you should use HMAC whenever you are concatenating
| values.
| bullen wrote:
| Can you exaplin what a "2nd preimage attack" is and how
| HMAC solves it?
|
| If it's an attack you can do after the database is
| compromised it's not very interesting, and if it's an
| attack you can do over the wire then you can just limit
| the number of login attempts per some duration no?
| thayne wrote:
| which is itself a problem with using the Digest method
| from RFC 2617
| SahAssar wrote:
| If the site isn't served over https why would you trust
| anything on it with sensetive info like passwords, personal
| info or payment details? if "HTTPS is a huge waste of
| electricity" can you please explain to me how to currently
| secure (in transit) user information entered on my site
| without it?
| bullen wrote:
| 1st you shouldn't trust any site with anything.
|
| BUT if you trust it with anything it's a password so that
| only you can prove that you are you. And then you use
| server side nonce hashing to ONLY compute that part
| securely wasting only the required cycles one each end to
| proove you are you period!
|
| Then, if for some reason you need additional security on
| some ulterior action, say a payment, you just do the same
| trick again. That way you save your servers and the
| electricity grid from encrypting every meaningless cat
| picture in the world just because you are paranoid.
|
| Electricity is not an energy source, we are going to pay
| a very high price for it soon. It's the most liquid
| energy form we have and therefor when oil becomes
| illiquid (both litteraly and economically because the
| quality of oil is degrading at a rapid pace) prices in
| electrons (which have no quality properties that differ)
| will explode!
|
| Again read the RFC
| https://datatracker.ietf.org/doc/html/rfc2289, and think
| about where you want to spend you energy, more customers
| or less energy for your own kids.
| jamespwilliams wrote:
| Do you agree that storing passwords in plain text is a
| problem?
|
| My point is that storing passwords in a way compatible with
| using Digest authentication is essentially equivalent to
| storing your passwords in plain text, at least with respect
| to your own site's authentication.
| bullen wrote:
| You don't store them as plain text, you store them as
| hashes.
|
| And then you send a server salt/nonce and the browser
| hashes the plain text password with the salted hash in
| your database and then with the server salt/nonce.
|
| Still HTTPS solves nothing of that.
|
| I don't even know what Digest is... I'm talking this RFC:
|
| https://datatracker.ietf.org/doc/html/rfc2289
| remram wrote:
| I don't understand why "no cookies" is listed under "pros". This
| works exactly like a session cookie (a header attached to every
| request to the domain), the only difference is that the header
| contains your actual plain-text credentials instead of a token.
| It is at most as secure/safe/non-invasive as a cookie, and in a
| lot of situation, a lot less.
|
| The obvious way to improve it would be to offer a way for the
| browser to load a custom form to authenticate and get the
| (hashed) credentials to present to the original website in the
| header. And then you have recreated session cookies in full.
| simonw wrote:
| I always thought you couldn't implement logout with HTTP basic
| auth, but according to this:
|
| > logging out is done by simply returning a 401 without www-
| authenticate header
|
| I did not know that worked!
| TonyTrapp wrote:
| I won't get tired of mentioning this - the basic authentication
| dialog should show a message from the server that is supposed to
| inform you what kind of credentials to enter. This is super
| useful for intranets, spam prevention systems and other stuff.
| Chrome removed this message years ago because of a dubious
| security report, and Firefox appears to have finally given in and
| removed it as well. All because someone could MITM your
| connection and present a login prompt a la "please enter your
| YouTube credentials" (completely ignoring that if they MITM you,
| they could serve you a page that really looks like a login page).
| This change completely ruined the usability of basic
| authentication.
| [deleted]
| Kwpolska wrote:
| I found the bug you're talking about:
| https://bugs.chromium.org/p/chromium/issues/detail?id=544244
|
| The MITM part is, in my opinion, an unimportant invention of
| the original reporter. The change was made because the basic
| auth dialog is part of the browser chrome (i.e. UI not part of
| web pages). This UI often looks like part of the browser/OS
| (especially in legacy IE, but modern browsers also show it
| differently, with the dialog partially obscuring the bookmarks
| toolbar. You don't need a MITM attack for this to go wrong, all
| you need is a rogue ad or something redirecting you to the
| attacker's site. Users might think "the dialog is asking me for
| my Google password, and it's presented by the Google Chrome
| browser, so it's got to be legitimate."
| TonyTrapp wrote:
| That is true, but let's also not forget that the bug title is
| "HTTP basic auth credentials prompt should make the origin
| stand out more" and nothing has been done about this in the
| last 7 years. Instead of making it stand out that the text is
| coming from the server, they just removed it completely. I
| found the original prompt to be pretty clear already ("the
| server asks for a username and password, it says: ...") but
| I'm sure in all these years they could have brought it back
| and made it more obvious that it's not Chrome asking for
| these things.
| encryptluks2 wrote:
| It is because the only "native" login they want you doing
| is to their sync services.
| jrockway wrote:
| That can't be true. Every browser vendor has happily
| implemented WebAuthn, which is easier to use than basic
| auth, and is actually secure. With a few lines of
| Javascript, you get native auth (FaceID, Windows Hello,
| etc.) and hardware tokens (YubiKey over USB or NFC), and
| you don't involve any external services; just you and the
| browser. Implementing this was a ton of work that
| detracts from things like "Log in with Apple" or "Log in
| with Google", but they did it anyway, which kind of goes
| against your premise.
|
| Basic Auth just sucks. It's hard for users to understand,
| and everyone stopped using it as soon as cookies became a
| thing.
| encryptluks2 wrote:
| Tell me this, can a user still use an external password
| manager with WebAuth or maintain the password themselves,
| or does it require the user to have their OS generate and
| store the key? From what I can tell, this looks more like
| an industry effort to have users integrate their
| passwords into various major-players sync services which
| is far from ideal for many users who actually want some
| control over where their passwords are stored and how
| they are generated.
| encryptluks2 wrote:
| Browsers should have standardized a lot more interfaces IMO.
| We now let developers run wild, which is a lot more insecure.
| The reasoning behind removing this feature is asinine
| considering Google does permit this, but they only want you
| to use it to login to your browser for Google accounts.
| Another shortcoming of browsers is that their integrated
| bookmark and password managers are pretty terrible, but if
| you want to integrate your own they want you to use your own
| extension interface while not being able to replace the ones
| that they provide.
| asadawadia wrote:
| what a coincidence I just wrote about this last night on my blog
| - https://blog.aawadia.dev/2022/02/17/basic-auth-with-javalin/
___________________________________________________________________
(page generated 2022-02-18 23:01 UTC)