logoalt Hacker News

vhsdevyesterday at 2:18 PM2 repliesview on HN

Hi, amichal. Nice finds. I will dig into more of the particulars where sensible. Please feel free to send up a pull request! Thanks for taking a peek.


Replies

tracker1yesterday at 10:08 PM

On the login... when failing either via user lookup, or password mismatch, I'll usually put a random 500-2500ms (or more) delay before logging and sending the response to handle timing attacks.

You can try a db transaction against a lock table for IP and Username as part of multi-request mitigation during any given request. CF offers Durable objects that can be used for this purpose. Return "too many requests" error if a request is sent before another is finished... this will slow things down.

On the minimum passphrase, there are some libraries you can use to get the printable character length... note: you should always normalize (NFC or NFKC) before doing any hashing or validation.

  function getPrintableLength(str) {
    // Use Intl.Segmenter for accurate, user-perceived character count
    const segmenter = new Intl.Segmenter("en-US", { granularity: "grapheme" });
    return [...segmenter.segment(str)].length;
  }
Personally, I usually just transparently set a max of 1024 bytes, I don't display a hint for it at runtime, only an error on submit though... if someone exceeds that, they deserve the generic error I return.

Email validation can be a bit rough, depending on how permissive or restricting you want to be. If you're willing to wait for a DNS/MX check on the domain, that's a good place to start. You most likely don't want less than 5 characters or more than 100.

vhsdevyesterday at 2:24 PM

Pretty sure all those are covered, upon more careful review. PRs open!

Edit: The create account I hadn't thought of for the email enum. Thanks!

Edit 2: Fixed up two schema issues identified and the last mitigated already via call: await passwords.rejectPasswordWithConstantTime(validatedData.password)