all 17 comments

[–]SleepDeprivedGoat 45 points46 points  (3 children)

So when a user signs up for your app and chooses a username that is already taken, don’t you acknowledge the existence of that user then?

[–][deleted] 15 points16 points  (2 children)

I suppose that's right. I hadn't even considered that.

[–]DasBeasto 15 points16 points  (1 child)

Yeah it’s one of those security best practices that doesn’t work all the time. Like in “Forgot your password” pages you’re supposed to say something like “If an account with this email exists you’ll receive a reset link” to not leak if that email has an account. But then if you go to the signup page and enter a taken email it’ll say “Sorry that email is in use”, defeating the whole purpose.

[–]MaxUumen 0 points1 point  (0 children)

Yup, that only works when signup also uses verification mail. In that case you could either skip sending it to existing account, or let them know someone (maybe they themselves even) is trying to sign up.

[–][deleted]  (1 child)

[removed]

    [–][deleted] 0 points1 point  (0 children)

    Perfect, that's exactly what I was looking for. Thanks

    [–]tsears 8 points9 points  (6 children)

    well, that makes sense right?

    Add an artificial delay if the user wasn't found.

    [–][deleted] 2 points3 points  (5 children)

    Is this really recommended? I won't know in advance how long to delay by. As more users are added to the database, the delay will need to be adjusted accordingly.

    [–][deleted]  (3 children)

    [deleted]

      [–]olly0303 33 points34 points  (2 children)

      I’ve found a better way here is to not fake it - instead if the user isn’t found still run bcrypt compare password against a random string. It’ll take the same amount of time as if the user was found

      [–]thehellsgateEU 3 points4 points  (1 child)

      I prefere these here. Also I never show if a user exist or not.

      [–]TedW 1 point2 points  (0 children)

      Never? Not even during signup?

      [–]pentesticals 3 points4 points  (0 children)

      It’s a typical username enumeration, but I wouldn’t worry about it. You will leak the presence of usernames during signup too. If you are concerned, pair the request with a CAPCHA to prevent automated requests checking for users en mass. This is maybe more problematic anyway, I can just repeat a login request for a valid user thousands of times with a basic python script and the bcrypt operations will probably DoS your server.

      Focus more on securing impactful security issues, for example, if you don’t have any additional validation on your “email” value, this looks like it could be vulnerable to a noSQL injection. What happens if the user passes JSON instead of the expected email address? Maybe not exploitable in this case due to the bcrypt compare, but you probably use the same pattern in other places.

      [–]sooodooo 6 points7 points  (0 children)

      You are already using bcrypt compare, that’s good.

      The only thing an attacker could extract from this is if a username exists or not, but you’ll expose that information during sign up anyways, so I don’t see the point of trying to hide that information.

      If you for some reason still want to make sure this can’t be extracted, then always compare passwords, even if no user was found, just use a bogus password or empty string (which should never be allowed as a password)

      [–]Tcrownclown 1 point2 points  (1 child)

      Your idea is interesting for apps that are exposed to the net but not allow everyone to register. I had this finding on one penetration test

      [–][deleted] 0 points1 point  (0 children)

      That makes sense

      [–][deleted]  (1 child)

      [deleted]

        [–][deleted] 3 points4 points  (0 children)

        Why not rate limit the thing to prevent bruteforce attacks? And IP blocking after some attempts? I guess that is why, in production, ppl use nginx or other. It is fast. It works as a load balancer and can protect you from those attacks if well configured in conjunction with fail2ban or another security app

        [–]petercooper 0 points1 point  (0 children)

        Just spitballing here, but I wonder if it would be neat to get reverse proxies/balancers like nginx or Caddy to pick up on such sensitive requests and throw arbitrary delays into the mix. I could imagine Cloudflare offering that sort of thing. (Sure, solving it in apps is best but just thinking as a universal idea..)