Ask HN: How safe are unique URLs as an authentication method?
I recently built a webapp for my company to track the progress of a certain process we were engaging. According to the logs, the google robot came in, followed all our delete links and erased the whole database of information. I have no idea how it figured out our unique url... Luckily this was neither critical or hard to recover from backup, but this begs the question:
How safe are unique URLs as an authentication method? Can you really replace a username/password prompt safely with a url like www.myservice.com/go/HDSFF98XC6Y219G23KJBVXC986R23/ without concern?
10 comments
[ 2.9 ms ] story [ 38.4 ms ] threadThat made me thing though... can you trust your users not to expose their private URL addresses? Aren't you trusting it to them, and if you have a user without internet experience signing up, what happens if he submits his private URL to google and makes it public? Doesn't that create a security hole?
Putting any sensitive information into a url is bound to be exploited sooner or later. Liberally, you can hold the info in urls for the duration of user session but anything beyond that is totally unwise. For the reasons you already mentioned.
Other possibilities for unintentional exposing of your personal ulr include: - Users who have google/alexa/amazon/etc. toolbars installed on their browsers, they browse to their personal page, or maybe bookmark it, and alexa/google immediately realize that it is not indexed so they start crawling it.
- Other phenomenons like Google Desktop Search crawls and caches all user bookmarks.
You should not use http GET method to perform unrelated operations. If you want to offer a delete option to your users, use http POST method. For authentication purposes, i absolutely recommend using HTTPS with POST method.
Dynamic URLs? Maybe.
[Edit: When I say "dynamic", I mean dynamic to the current session, as you would see in a continuation based framework. I do not mean dynamic as it relates to a piece of data.]
Here are my thoughts on making these URIs secure:
First, always have such a URI on a 72-hour dead clock. You send the URI to the user and it's good until used or 72-hours later. Then they need to generate a new one.
Second, make it two factor. Rather than having something.com/reset_pass/12345, have it be something.com/reset_pass/{user_id}/12345. Just another level of protection.
Third, use base 62 numbers (0-9, a-z, A-Z). It's something any browser can handle with no special chars. Remember, base is more important than length. A 6-digit, base 62 number will go to greater than 56 billion different combinations. If someone guesses from one of 56 billion numbers, holy sh*t do they deserve to break in. If you're paranoid, make it 10 digits and get over 800 quadrillion combinations. No one is going to brute force that and 10 digits is still small to display.
Fourth, you can rate limit by IP address. Set it high - like, 100 attempts per hour limit. Why so high? You don't want to piss off users who are, well, stupid. And to get to 800 quadrillion making 100 attempts per hour would take millions of years - heck, let's say you're so high-profile that they'd put a farm of 100,000 IP addresses on it you're still looking at over a million years.
In many ways, these URIs can be made more secure than passwords since most passwords won't be as random or strong. There are some caveats:
These URIs will show up in browser histories and your server logs. They are one-time secure things. Once the user has used it, the next time they need such a thing, they need a new URI. If someone gets into your logs, they can see these URIs and reset peoples passwords unless they expire on use. Same with browser history.
As I've mentioned, they can be posted. Users post things they shouldn't all the time (including passwords). Have it time out so it's only a breach for a short period.
Don't use it as a replacement for user/pass. Just don't. If the same URI stays good, it is insecure.
Good luck!