Two security reviews, and what they changed for you
You are handing us your customers' phone numbers and your revenue. Here is what is different about how that is held.
- Passwords are hashed with scrypt at OWASP's recommended settings. It is memory-hard, meaning each guess costs an attacker 128 MB of memory as well as time — which is what makes cracking stolen password databases with graphics cards expensive rather than cheap. Your password is re-hashed the next time you sign in; you do not have to do anything.
- Your account is created when you confirm your email address, not when you submit the form. Until then nothing exists but a pending registration that deletes itself if the link goes unused — so nobody can open an account on your address, set a password on it, and wait for you to find it and adopt it.
- Password reset and email verification links are single-use in the strict sense: the database allows exactly one redemption, so two clicks arriving together cannot both work. They were re-redeemable within their window before, and a link sitting in a mailbox is one of the easier things for someone else to reach.
- New and changed passwords are checked against passwords exposed in public breaches. The password never leaves our servers — we send five characters of its hash and do the comparison here, so the provider cannot tell which password was checked or whose it was.
- Signing in, signing up and resetting a password now sit behind a bot challenge as well as rate limits, which makes working through a list of leaked passwords cost more than it returns.
- No analytics or tag manager loads on the pages where you type a password. They had been allowed there, which is one more piece of somebody else's code on the page that matters most.
- Exports are safe to open. A cell starting with an equals sign is a formula to a spreadsheet, so a value in a CSV you uploaded could have become a command on the machine of whoever opened your export. Ordinary numbers and negative amounts are untouched.
- Anything a CloseRev administrator does to your account is written into a chained record: each entry seals the one before it, and the database refuses to alter a sealed entry. Deleting or editing history now breaks the chain visibly instead of leaving no trace.
- The status page tests sign-in and billing rather than only reporting that the site answers, and you can report a vulnerability through /.well-known/security.txt.