b50289074d
gates / gates (push) Successful in 28s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
3.6 KiB
3.6 KiB
Catalog sweep 1/4 — READ in source at each pinned tag (not measured live). Subagent report 2026-10-01, condensed.
Apps: actualbudget adventurelog audiobookshelf bentopdf bookstack calcom calibre-web claper code-server crafty-controller dawarich docmost emby ghost. NEW chain = tunnel "forged…, real, 172.16.253.2"; LAN "lanclient".
| App (tag) | How it reads the visitor | Used for | Verdict | Evidence |
|---|---|---|---|---|
| actualbudget 26.9.0 | Express trust proxy, CIDR list from the RIGHT (ACTUAL_TRUSTED_PROXIES default private ranges) |
login limiter 5/15 min by IP | SAFE; real client on both paths after Part A | packages/sync-server/src/app.ts:31; load-config.js:133-143; app-account.js:26-33 |
| adventurelog v0.13.0 | django-allauth 0.63.3 LEFTMOST XFF | allauth defaults: login_failed 10/m/ip + 5/300s/username | RISK (per-IP part forgeable) → router reset | allauth account/adapter.py:704-710; app settings.py:326,375-386 |
| audiobookshelf 2.37.1 | request-ip: x-client-ip, LEFTMOST XFF, cf-connecting-ip, x-real-ip | auth limiter 40/10 min by IP ONLY | RISK (unlimited guessing) → router reset | server/utils/rateLimiterFactory.js:9-10,53-61; libs/requestIp/index.js:16-68 |
| bentopdf v2.8.6 | — static | nothing | SAFE | Dockerfile:80,105 |
| bookstack 26.09.1 | Laravel TrustProxies from the RIGHT, only with APP_PROXIES (empty) |
login 5/min username|ip; MFA limiter by IP; audit IP |
SAFE as is (sees traefik); APP_PROXIES=172.16.0.0/12 → real client on both paths |
TrustProxies.php; ThrottlesLogins.php:63-66; MfaVerificationLimiter.php:60 |
| calcom v6.2.0 | cf-connecting-ip, true-client-ip, LEFTMOST XFF, x-real-ip | limits are no-ops without UNKEY_ROOT_KEY; IP_BANLIST unset | SAFE as is (revisit if those are set) | packages/lib/getIP.ts:22-33; rateLimit.ts:33-41 |
| calibre-web CWA v4.0.8 | werkzeug ProxyFix count from the right (TRUSTED_PROXY_COUNT=1) |
login limit by USERNAME; register/kobo by IP; session bound to IP | SAFE as is (count 1 → cloudflared on the tunnel, LAN client on the LAN); count 2 breaks the LAN path and proto/host — keep 1 | cps/__init__.py:89-92; cps/web.py:2056-2057,2218-2219 |
| claper v2.5.0 | remote_ip from the RIGHT skipping private ranges | auth limiter 10/min by IP | SAFE; real client on the tunnel | lib/claper_web/endpoint.ex:63-65; remote_ip lib/remote_ip.ex:252-278 |
| code-server 4.129.0 | logs the raw XFF | global login limiter | SAFE (log text client-written) → router reset for the log | src/node/routes/login.ts:12-26,105-111 |
| crafty-controller 4.11.0 | X-Real-IP first, then leftmost XFF | logs; lockout keys never match (inert, inferred) | SAFE (X-Real-Ip is traefik-set) | base_handler.py:71-101 |
| dawarich 1.15.3 | Rack Request#ip from the RIGHT, default trusted private | Rack::Attack logins/ip 20/min, logins/email 5/min; Devise lockable | SAFE; real client after Part A | config/initializers/rack_attack.rb:269-292 |
| docmost 0.96.0 | Fastify trustProxy true = LEFTMOST | AUTH throttler 10/min by IP ONLY | RISK → router reset | apps/server/src/main.ts:25,97; user-throttler.guard.ts |
| emby 4.11.0.4 (decompiled) | LEFTMOST XFF, else X-Real-IP; wizard forces AllAddresses | LAN PRIVILEGES (remote access off-users, IP filter bypass, forgot-password PIN) | RISK → router reset; and a risk TODAY: cloudflared/traefik are private → every tunnel visitor is "LAN" (row) | BaseRequest.cs InitRemoteConnectionInfo; NetworkManager.cs:397-437 |
| ghost 6.67.0 | Express trust proxy true = LEFTMOST | brute: userLogin IP+username, globalBlock per IP | RISK → router reset | ghost/core/core/shared/express.js:21-25; brute.js |