Count sign-ups by network, not only by address #77

Merged
paulhitt merged 2 commits from feat/signup-network-limits into main 2026-09-02 23:53:45 +00:00
paulhitt commented 2026-09-02 01:18:00 +00:00 (Migrated from gitlab.com)

Closes #41 — and corrects that ticket's premise. The existing limit is per address,
not per account: 50/hour keyed on the client IP. What it misses is that more addresses is
the cheapest thing an abuser buys.

Fifty accounts from one address is refused. Fifty each from two hundred addresses in one
/24 is ten thousand accounts, and one request at a time it looks exactly like a busy
afternoon. The address limit stays; a much larger ceiling now sits behind it, keyed on the
network.

/48 for IPv6, not /64. A /64 is one machine and a customer is often handed many, so
keying on it is barely better than keying on the address. A /48 is a site.

An IPv4-mapped address is IPv4. Treating ::ffff:203.0.113.7 as IPv6 would drop
every mapped address into one enormous shared bucket — the same as no limit, and worse,
since everybody in it would be punished for each other.

Unparseable input keys on itself, never on a constant. Failing open into a shared
bucket would let one attacker exhaust everybody's budget; returning empty would make the
check removable by sending nonsense. Two tests hold that, including one asserting two
different garbage values do not collide.

The allowance is eight times the per-address one, deliberately. A university, an office,
or a carrier behind CGNAT is thousands of real people on one network — refusing them is far
worse than admitting a determined abuser. A ceiling on industrial-scale registration, not a
throttle on ordinary use.

Both limits go through consumeAll, so a refusal by either does not spend the other —
otherwise one machine could burn the network budget and lock out its neighbours.

Tests: 9 new, proven able to fail — folding IPv6 into one bucket turns 8 red. 479 in 41
suites pass. Not merged, not deployed.

Closes #41 — and corrects that ticket's premise. The existing limit is per **address**, not per account: 50/hour keyed on the client IP. What it misses is that more addresses is the cheapest thing an abuser buys. Fifty accounts from one address is refused. Fifty each from two hundred addresses in one /24 is ten thousand accounts, and one request at a time it looks exactly like a busy afternoon. The address limit stays; a much larger ceiling now sits behind it, keyed on the network. **/48 for IPv6, not /64.** A /64 is one machine and a customer is often handed many, so keying on it is barely better than keying on the address. A /48 is a site. **An IPv4-mapped address is IPv4.** Treating `::ffff:203.0.113.7` as IPv6 would drop every mapped address into one enormous shared bucket — the same as no limit, and worse, since everybody in it would be punished for each other. **Unparseable input keys on itself, never on a constant.** Failing open into a shared bucket would let one attacker exhaust everybody's budget; returning empty would make the check removable by sending nonsense. Two tests hold that, including one asserting two different garbage values do not collide. The allowance is eight times the per-address one, deliberately. A university, an office, or a carrier behind CGNAT is thousands of real people on one network — refusing them is far worse than admitting a determined abuser. A ceiling on industrial-scale registration, not a throttle on ordinary use. Both limits go through `consumeAll`, so a refusal by either does not spend the other — otherwise one machine could burn the network budget and lock out its neighbours. **Tests:** 9 new, proven able to fail — folding IPv6 into one bucket turns 8 red. 479 in 41 suites pass. Not merged, not deployed.
paulhitt commented 2026-09-02 14:56:42 +00:00 (Migrated from gitlab.com)

mentioned in merge request !25

mentioned in merge request !25
paulhitt commented 2026-09-02 19:34:34 +00:00 (Migrated from gitlab.com)

added 6 commits

  • 2ff45519...1a0a93fa - 4 commits from branch main
  • 68f644db - Count sign-ups by network, not only by address
  • a49a0f68 - Give network counting a switch, with zero meaning off

Compare with previous version

added 6 commits <ul><li>2ff45519...1a0a93fa - 4 commits from branch <code>main</code></li><li>68f644db - Count sign-ups by network, not only by address</li><li>a49a0f68 - Give network counting a switch, with zero meaning off</li></ul> [Compare with previous version](/paulhitt/flamenet-relay/-/merge_requests/14/diffs?diff_id=2000708377&start_sha=2ff45519da9fedb1fec7c741337d43534640b405)
paulhitt commented 2026-09-02 23:53:34 +00:00 (Migrated from gitlab.com)

added 8 commits

  • a49a0f68...7da09f19 - 6 commits from branch main
  • 21c77f67 - Count sign-ups by network, not only by address
  • e7e1a787 - Give network counting a switch, with zero meaning off

Compare with previous version

added 8 commits <ul><li>a49a0f68...7da09f19 - 6 commits from branch <code>main</code></li><li>21c77f67 - Count sign-ups by network, not only by address</li><li>e7e1a787 - Give network counting a switch, with zero meaning off</li></ul> [Compare with previous version](/paulhitt/flamenet-relay/-/merge_requests/14/diffs?diff_id=2001132006&start_sha=a49a0f6825d3ec77938098820625023e93550904)
paulhitt (Migrated from gitlab.com) merged commit 83f0a02920 into main 2026-09-02 23:53:45 +00:00
paulhitt commented 2026-09-02 23:53:46 +00:00 (Migrated from gitlab.com)

mentioned in commit 83f0a02920

mentioned in commit 83f0a02920b945487d797d6cb60166ba6ba116ad
paulhitt commented 2026-09-09 18:59:20 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
Sign in to join this conversation.