Add an auth abuse-prevention playbook #24
Loading…
Reference in a new issue
No description provided.
Delete branch "docs/auth-hardening-playbook"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adds
docs/Topics/Auth-Hardening.md: how to make sign-in and sign-up hostile toabuse in a Symfony application.
Extracted from doing exactly that on someones.computer, but written to be
applied rather than to describe that project — the same controls belong on
every project here, vpnondemand included. File paths in the "as built" callouts
point at the reference implementation; none of the reasoning depends on it.
What is in it
Six controls, ordered by value, because the order is itself the advice:
almost every "we should add a CAPTCHA" conversation is really a missing rate
limit, and a proof-of-work widget bolted onto an unlimited endpoint is
decoration.
Each one names what it stops, what it costs, and what a wrong setting looks like
from the outside. There is a sizing table with starting numbers, an adoption
checklist, and a section on what is deliberately not included
(disposable-email blocklists, IP reputation, fingerprinting, MFA) so the
omissions read as decisions rather than gaps.
Why it is worth the length
The traps. Each cost real time to find and none is obvious from a library's
README:
consume(0)->isAccepted()is always true. It is the natural way to peek ata rate limiter without spending from it. Acceptance asks whether there are at
least N tokens left, and there are always at least zero — so written that way a
limiter sits in the code, passes a careless test, and never once refuses a
request. This was a live bug in the implementation, caught by a test that
asserted the refusal rather than the wiring.
still shows in the status code, the timing, and whether a session appeared —
and "registration signs the new account in" is the one that gets missed,
because it can only happen when the address was free.
the provider's email is self-asserted, which on GitHub it is. The library reads
the
verifiedflag that would say so and discards it.caller's problem, not the library's.
Passport::getUser()in a login-failure listener throws on the most commonfailure there is — no such account — so the logging added to observe attacks
becomes an incident itself.
Verification
markdownlintclean. Every claim about Symfony behaviour, the ALTCHA library andthe OAuth client libraries was verified against the vendored source while
implementing the reference version, not from memory.
No code in this repo, so nothing to run.
Related
The consuming change lands separately on someones.computer (implementation plus
the submodule pointer bump), per the two-PR rule in
VCS.mdfor a standardschange.