Block the whole network for a flagged signup, not just its /32
docker-build-push / build-push (push) Successful in 4s

register_ip_block always blocked the exact signup IP as a /32 (or /128
for v6), which is close to pointless for the datacenter/VPN/proxy space
these flags fire on: a repeat bad actor from the same provider almost
never reuses the exact same address, but very often reuses a different
one in the same block.

classify_signup_ip now returns a fourth value, block_cidr — ipapi.is's
asn.route CIDR when it's a valid network that actually contains the
signup IP (already being tracked in ipapi_range_cache purely for lookup
caching), falling back to the address's own /32 or /128 when no usable
route exists. register_ip_block blocks that instead of always deriving
a /32 itself.

Added range_cache_tests() covering the cache/fallback logic directly
(pure sqlite + ipaddress, no network), and updated the existing
ip_scrutiny_tests()/combined_signal_tests() mocks for the new 4-tuple
classify_signup_ip return and register_ip_block arity.
This commit is contained in:
pmb
2026-07-15 10:25:14 -07:00
parent fc965e3f17
commit b39528ac30
4 changed files with 109 additions and 35 deletions
+9 -3
View File
@@ -72,10 +72,16 @@ Every `account.created` delivery already carries the signup IP for free
on `account.created` and only sent when `account.approved` fires, i.e.
once a human clears yttrx's existing approval-required registration
gate. If the signup is rejected instead, no welcome is ever sent.
- **Auto-registered IP block** (`IP_SCRUTINY_AUTO_IPBLOCK`) — the IP is
- **Auto-registered IP block** (`IP_SCRUTINY_AUTO_IPBLOCK`) — the *network*
the signup IP belongs to (ipapi.is's `asn.route`, when it's a valid CIDR
that actually contains the IP; otherwise just that one `/32`/`/128`) is
added to Mastodon's native `Admin::IpBlock` at
`IP_SCRUTINY_IPBLOCK_SEVERITY` (default `sign_up_requires_approval`,
reversible from the admin UI).
reversible from the admin UI). Blocking the whole network rather than
the single address matters here specifically because a flagged signup is
almost always datacenter/VPN/proxy space — a repeat bad actor is far more
likely to come back from a different address in the same block than the
exact one, unlike a residential IP where that reasoning wouldn't hold.
- **Lowered abuse-bot threshold** — if this account is later reported, the
usual `ABUSE_SOURCES_*` distinct-reporter threshold is replaced by
`IP_SCRUTINY_ABUSE_THRESHOLD` (whichever is lower), since a flagged
@@ -211,7 +217,7 @@ Copy `.env.example` to `.env` and fill in:
| `IP_SCRUTINY_DRY_RUN` | `true` — classify + DM only, no held welcome, no ip_block write |
| `IP_SCRUTINY_HOLD_WELCOME` | `true` — hold the welcome for a flagged signup until `account.approved` |
| `IP_SCRUTINY_ABUSE_THRESHOLD` | Distinct-reporter threshold used (if lower) for accounts with a flagged signup IP |
| `IP_SCRUTINY_AUTO_IPBLOCK` | Auto-register a flagged IP into Mastodon's `Admin::IpBlock` |
| `IP_SCRUTINY_AUTO_IPBLOCK` | Auto-register a flagged signup's network (ipapi.is route, or its own `/32`/`/128` if no route) into Mastodon's `Admin::IpBlock` |
| `IP_SCRUTINY_IPBLOCK_SEVERITY` | `sign_up_requires_approval` (default), `sign_up_block`, or `no_access` |
| `CHECK_MAIL_ENABLED` | Master switch for disposable/high-risk email signup scrutiny |
| `CHECK_MAIL_API_KEY` | check-mail.org API key; blank disables the check |