8 ms·
Is Your Site Leaking Password Reset Links?
- deleted 10y ago[deleted]
- r1ch 10y agoYou can also use the meta referrer tag on modern browsers. https://moz.com/blog/meta-referrer-tag https://moz.com/blog/meta-referrer-tag
- derekprior 10y agoIt's covered in the article, but this is not supported by IE11. That's pretty modern...
- kelvin0 10y agoI've read the article twice, and I'm not totally clear as to what the problem is, and how it's being addressed (web n00b here). Also, this bit: "Browsers will not send the Referer for resources fetched via HTTP from a document loaded via HTTPS" So using HTTPS resolves the issue? But breaks analytics? Any further clarification would be nice, thanks!
- impostervt 10y agoIf you're site uses a password reset token email as the article describes, and your Reset Password page loads 3rd party scripts or css, those 3rd parties (and any servers en route to them) may be able to see the password reset token as part of the HTTP Referer header.
- mankyd 10y agoThe basic observation is that the reset url is sent as the referrer to any 3rd party content that gets loaded on the page. So if you have a facebook link, ads, analytics, cdn, or other random content on the page, they get to see what the reset url is. This is a valid concern, though it's worth noting that you shouldn't be including 3rd party content you don't trust on any potentially sensitive page in the first place. This includes not only password pages, but potentially ANY logged in page on the site. Otherwise, you should consider the 3rd party content trusted and move on.
- msimpson 10y agoThe article is simply pointing out that services which record referrers can inadvertently store live password reset tokens if you're not careful. For instance, someone places Google Analytics in the head of the default layout for a given site. Now traffic to and from the password reset page, which uses that layout, is being recorded. This means an attacker would only need to gain access to that account, which is probably much less guarded, and gather referrers containing password reset tokens. From there they could quickly try the last few--which might still be active--and easily gain access to one or more accounts within the site.
- kelvin0 10y ago>>...would only need to gain access to that account, which is probably much less guarded.. So "that account" you mention, is it the Google analytics account or the web application (leaking urls) account? Why is it much less guarded?
- msimpson 10y agoI mean the analytics account; and in my experience it is less guarded due to clients handing out access as it's "just reporting" in their eyes.
- jordanlev 10y agoThe thing about https only applies when an https page is loading assets from a non-http address. But if your site uses https and so does your CDN, then the referer headers are still sent.
- moloch 10y agoThis is bad but not horrible, especially in the example given leaking the reset token to Cloudfront. The application is loading JavaScript from the Cloudfront origin, so that origin by definition could already read the tokens by modifying the JavaScript (assuming no SRI). The request is sent over SSL/TLS so the token cannot be viewed by a MITM, and referers aren't sent across HTTP<->HTTPS transitions. Again this is far from ideal, but also not readily exploitable by attackers that couldn't already access the data.
- derekprior 10y agoAuthor here. I completely agree that it's unlikely to be exploited but also think fixes are mostly simple enough that it should be addressed.
- pacifika 10y agoThe problem is that your password reset token shouldn't be reusable. The token is only leaked after the person visited the reset page, which should invalidate the token on load. Without a valid token, the reset form shouldn't load. Problem solved.
- nileshtrivedi 10y agoHow to implement this if the token is not stored in database at all (eg. JWT)? As far as I know, enforcing one-time-use only requires storing a bit in backend.
- anton_gogolev 10y agoIf you could somehow encode the value of "PasswordLastUpdatedAt" in your token, you will then could have truly "stateless" tokens.
- derekprior 10y agoThis requires non-idempotent get requests as you must invalidate the token on get. I did consider this approach for Clearance and intended to go with it, but was discouraged from doing so after hearing reports that some enterprise email AV does things like open some links in emails. There is also the user experience concern that a click the link in my email, do something else, then click the link again, having forgotten I already clicked the link. Now I'd have to re-request again. Also, this approach is impossible if you use HMAC tokens. I don't think anyone who opts for this approach is wrong but like most things, it's a tradeoff.
- anton_gogolev 10y ago> This requires non-idempotent get requests as you must invalidate the token on get. I think you should invalidate a token whenever a user enters a new password and submits a form (hence POST).
- oneeyedpigeon 10y ago
- jpalomaki 10y agoOne option is to avoid putting the token to the link and at least provide user a simple way of copy-pasting the token to the password reset form. Sometimes this is actually something I as user want to have, since it might be that I'm receiving the email on device A, but want to reset the password on device B. And please keep the password reset tokens sane. If you are not encoding some data into the token, you don't really need that 80 character random string for security.
- derekprior 10y agoI'd certainly consider this for some applications. It depends on the value of what you are protecting. For some sites and users, the error rate introduced by this method would be unacceptable. Tradeoffs...
- tinus_hn 10y agoMany people do not understand copy and paste at all.
- zokier 10y agoWould putting the token to url fragment id resolve the issue? I suppose the downside would be that then js is required on the reset page. But that is fairly minor imho.
- andrenarchy 10y agoIf you use javascript to extract the token from the URL then you can simply pass it via the hash ("fragment") part of the URL. The hash portion is only interpreted by the user agent and never sent to a server (see https://tools.ietf.org/html/rfc3986#section-3.5 https://tools.ietf.org/html/rfc3986#section-3.5). This is how we solved it at paperhive.org.
- oneeyedpigeon 10y agoObviously, the drawback is that you've introduced a javascript dependency to a core function which definitely doesn't require it. Having said that, I notice that paperhive.org renders an entirely blank page if javascript is unavailable, so I guess the password reset is the least of your concerns in that scenario.
- angry-hacker 10y agoAnd what percentage of the users have javascript disabled? Objectively you have bigger concerns when you run a site than 10 people who have js disabled.
- oneeyedpigeon 10y agoDefinitely more than zero. It's not just a case of javascript being disabled, either - there are many other reasons why it might be "unavailable", which is why I used that word. Of course I'm not suggesting you're not allowed to use any javascript on your site, or even that you should only use it when it's strictly necessary, but if it's entirely unnecessary and you don't engage in best practise by, for example, using progressive enhancement, then that's something that could be improved.
- tomjen3 10y agoI used to think so, but information sites probably needs to work without javascript, if only for google bot.
- VertexRed 10y agoIt's 2016, everyone has JS enabled. The ones that don't are most likely bots (now even that's changing thanks to projects like phantomjs).
- agotterer 10y agoWhy not have a URL that identifies the reset request uniquely but also requires a code that is entered manually?
- sbjustin 10y agoUsers are finicky (I am) :) That adds more work to it.
- agotterer 10y agoYet plenty of successful companies do the equivalent with SMS codes during registration or account verification. It's not unreasonable that during a password reset you have to put in a few characters of extra work. If you're too lazy to type a few extra characters the account clearly isn't all that valuable to you.
- deleted 10y ago[deleted]
- oneeyedpigeon 10y agoIn my experience, that really confuses users. Some just do not understand or read the email too quickly; they click the link, then they get stuck. If everything just works as a result of clicking a link, users are satisfied. BTW, why would the URL that identifies the reset request need to be unique if the tokens have enough entropy?
- agotterer 10y agoGoing to need a whole lot of characters to prevent someone being malicious and just resetting passwords randomly. Long characters are also more annoying to type for the end user. If the link is unique you can keep the passcode a little shorter and it requires two pieces of information to complete a reset.
- eterm 10y agoFor analytics this isn't a big problem. Once a reset link has been clicked, it should be immediately invalidated. So unless the server was able to respond to the link and provide the analytics stuff but not somehow invalidate the token, I can't see how this is a problem. Another related problem is that some third party mailers move all their links via URL redirectors. In that case there's a chance the host application fails and the link is left valid.
- fahrradflucht 10y ago>Once a reset link has been clicked, it should be immediately invalidated. I'm not sure about this... Couldn't this produce some unexpected reset failures in cases of browsers preloading links in webmail clients?
- mgbmtl 10y agoDrupal (and WordPress, if I recall correctly) invalidate immediately. Considering reset links are sent in plain text by email, it's a good way to test whether the link has been used by someone else. Besides, it would be an odd security hazard if browsers/webmails preloaded links in emails (malicious URLs in spam/scams). edit: in Drupal, the reset link loads a page with a button that the user must click on. This avoids issues with potential preload or anti-virus scans.
- zaroth 10y agoWhat if they click the link but don't click the button? Do they need another password reset token at that point? If not, is there still an attack window there that needs to be plugged?
- mgbmtl 10y agoThe links usually expire after 24 hours (attack window), if unused. Loading the page without clicking does not invalidate the link. I agree this is not highly secure. It's basically one notch above sending cleartext passwords by email (which many websites unfortunately still do).
- tvelichkov 10y agoIf you steal someones else password-reset link, change the password, then at the end of the day, won't you end up with a password, but missing email/username in order to log in? I mean the reset password link shouldn't reveal any other credentials about the account. (I know at some sites after reseting a password you may end up automatically logged in, but i think this is a bad practice).
- derekprior 10y agoDepends on how the reset behaves. Some resets log you in immediately after providing a new password. Some require you to log in after resetting the password. I feel like I've seen more of the former than the latter.
- nchelluri 10y agoI don't think it's so simple. Before generating the PW reset link, someone might try to login first. So they'd enter bob@example.com into the login form and then when that failed, it's not uncommon to redirect with error-msg-in-session to /login?email=bob@example.com . So you'd leak the email first.
- milankragujevic 10y agoGiven how many (more than 90% imo) reset links are something like /reset?email=test@test.com&token=0123456789, that's not quite an issue as it may seem...
- Normal_gaussian 10y agoSo the fragment solution requires JS, invalidate on request can be upset by email scanning antivirus, manual token entry is inconvenient. So my first thought is returning a page with no external requests (render on the srrver) which isn't very dev friendly. My other thought is returning a redirect to a page with a token derived from the original token and the clients IP or some other fingerprinting information.
- richardwhiuk 10y agoRedirect to a page setting a cookie with the token in, which is then scoped to the domain via Site Origin policies.
- kijin 10y agoRedirect is the cleanest solution. Most frameworks provide some form of storage (whether server-side or client-side) that is tied to a specific session, so you can use that to remember the fact that the current session recently used a valid password-reset token for user ID 123. Or you could use a similar mechanism to put the token in a hidden <input> after redirection, so that it gets submitted again when the user types in their new password.
- bahjoite 10y ago>Redirect is the cleanest solution. Exactly. Submitting tokens via GET requests (as is necessary for an emailed token) should be handled in the same way as POST (POST-redirect-GET): the resource which validates the token should not be the one that presents the "password reset" form.
- garglgarbl 10y agoI'm a bit of a web noob as well, so I have a related question: If I have an https url with a token will the token only be sent through the https connection or is it contained in any lookups or connection metadata or such?
- briHass 10y agoQuery parameters are encrypted if you are using HTTPS. The domain/host name (e.g. news.ycombinator.com) obviously is not protected, since the DNS lookup is required and the server (resolved IP) may host multiple sites. Seeing the hostname plaintext in the request is required for the server to disambiguate. So, for single-use tokens, you're probably OK for passing it in the URL (e.g. myhost.test/resetpw?token=abcdef), but it is usually considered a bad idea to use the URL for non-single-use secret info. Once it hits the server, the full URL may be stored in log files unsecured or if you use SSL termination before the server, it could be logged in other places as well. Additionally, the user's browser itself may store your secret URL in the history.
- derekprior 10y agoIn my experience, password reset tokens are not single use. They are good for both loading the form and submitting the form. They are not invalidated until the form is submitted with the new password. They are good for 1 password reset, not 1 page load. It's possible to make them good for 1 page load, but most I've encountered are not due to the tradeoffs that would involve (see other discussions).
- jccc 10y agoAnyone here happen to know how Basecamp works? They seem to be comfortable with emailed login links, no username or password.
- mmanulis 10y agoWhy not pass the token as an HTTP header? e.g. X-RESET-TOKEN=foo and then read that via JS
- deleted 10y ago[deleted]
- derekprior 10y agoYou can't set an HTTP Header with an HTML link. Would be nice to set a body though, wouldn't it? Also, not allowed by HTML.
- dom0 10y agoHow exactly do you encode a HTTP header into an URL?
- homakov 10y agoThere's absolutely no situation when it's a risky behavior. It is not a problem at all.
- HoyaSaxa 10y agoJust to illustrate a potential scenario: You use a piece of open source software that has a javascript file which the author has hosted on a CDN. In order to mitigate an attack where someone changes the content of the javascript file you use a hash[1] to ensure the file does not change. You think you are safe, but a malicious actor gets access to the CDN and instead of changing the file, instead builds a quick scripts that looks for password reset referrer patterns and races the human to reset the password first. A computer is probably going to win that game that majority of the time. [1] https://github.com/twitter/secureheaders#hash https://github.com/twitter/secureheaders#hash
- CGamesPlay 10y agoOr the attack just skips the secure hash check on the server... This example doesn't seem to hold water either.
- derekprior 10y agoI think people are looking to closely at the first degree attack -- a trusted partner is pwned. If this is the case, there's far more interesting things an attacker could do. It's not too hard to envision a scenario where an attacker does not have access to embeded assets, but does have access to logs. 1. You include a script such a TypeKit. The typekit deliverable itself is not owned, but bad actors have access to typekit.com logs. 2. You use a smaller third party add on service that itself uses a logging service such as PaperTrail. PaperTrail is hacked, providing attackers access to logs. 3. You reference no external assets, but your site contains external links in the footer. Users click the navigation links rather than completing the form. You have leaked the token to whatever site that is. You are at the mercy of their log storage. YES, this does actually happen. User's click crazy things. As I mention in the article and in other comments here: this is not likely to be exploited. Fixes, however, are not too difficult. Even adding the not-quiet-fully-supported `meta` tag to your head is a good start. If I read this article today, I'd think, "That's interesting. let me make a note to check that out." It's not a hair-on-fire security situation, but it's not "not a problem at all" either.
- zeveb 10y agoHe should have also considered the option of not loading third-party assets and analytics on password reset pages. I'm grumpy enough to suggest not loading them period, but I'm a curmudgeon.
- zaroth 10y agoReferrer leaks are such a foot-shoot. There should have been a piece of the URL which never touched the Referrer but also was submitted to the server from the get-go. But obviously an easy edge case to miss in 1991 - 1996 [1] [2]. But this is sad: http://caniuse.com/#feat=referrer-policy http://caniuse.com/#feat=referrer-policy [1] - http://www.w3.org/pub/WWW/Protocols/HTTP/AsImplemented.html http://www.w3.org/pub/WWW/Protocols/HTTP/AsImplemented.html [2] - https://tools.ietf.org/html/rfc1945 https://tools.ietf.org/html/rfc1945
- darkhorn 10y agoWhat I do is I start a session on password reset page. I send an email with the reset link. User visits the link. The web page checks wheter the requester is same with the session identifier. Only then the user has a right to create a new password. So, in other words, if the user tries to visit the link with a different browser a warning says "use your browser that you used to reset your password".
- initram 10y agoSo if I'm in a private session and clicking the link in my email opens a new page in a different session, then I can't reset my password? That's lame. I've even had a situation where I was on my desktop machine and clicked a reset link on the web site. I realized I didn't have my email set up on that machine yet, so I went to my phone and did it from there. In your scenario, this wouldn't work. That seems problematic.
- darkhorn 10y agoIf you are on a private session you can copy the link to a new private tab and it will work. My web site's visitors are only from my universty. Only to those who have METU email addresses. It is easy to log in to a web mail from the browser. Password reset is not a something done on daily bases. It is okay for my situation. Not very user friendly but it is a bit more secure. In fact the idea come from this; what if a student fills registration form and sends the validation email to his teavher. And the teachet, without reading click, in other words validates the registration process mistekenly. Now, I have a criminal case (I shouldn't allow Professor Naughty Elizabeth to be registeted for example) against me! I wanted to protect my ass. And I used it too in password resets.
- Lord_Zero 10y agoCan anyone check if https://stormpath.com/ https://stormpath.com/ has this issue?
- milankragujevic 10y agoDoes anyone have a list of common vulnerabilities that you should check your app against, maybe excluding the obvious ones like SQL Injection, XSS, etc... ? Because I can't keep track of all the vulnerabilities that exist in the world :(
- Kalium 10y agohttps://www.owasp.org/index.php/Top10#OWASP_Top_10_for_2013 https://www.owasp.org/index.php/Top10#OWASP_Top_10_for_2013 This is a good one in specific. In general, be very careful of what information you share with who. Information is dangerous, and it leaks all over.
- marichards 10y agoBritish regulators have highlighted this problem too. https://iconewsblog.wordpress.com/2015/09/16/does-your-website-have-a-leak/ https://iconewsblog.wordpress.com/2015/09/16/does-your-websi... I wish someone would sue Mozilla, Google, Microsoft and Apple for data protection violations for supporting referer