From 4fdb7eebd916f81bfde7dc4c6adbc8387d6699ca Mon Sep 17 00:00:00 2001 From: Anshul Nitin Date: Fri, 3 Jul 2026 20:34:03 +0530 Subject: [PATCH] fix: address remaining security audit findings (round 2) (#628) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Follow-up to #623 — addresses security findings **not covered** by the maintainer's draft PR #627. The original scope was larger; out-of-scope changes were reverted (see `revert: drop out-of-scope changes from security round 2`) and are **no longer part of this PR** (details under _Reverted / not included_). ## Changes ### Rate limiting - `routes/api.php`: authenticated API group throttled at `300,1` (per user). An SPA with offline sync + multi-widget dashboards fans out many requests per interaction, so a tighter cap throttled legitimate bursts. - `routes/web.php`: unauthenticated open-banking callback throttled at `30,1` (per IP), enough headroom for browser retries and the iOS PWA → Safari hand-off that can fire the callback twice. - `use-decrypt-transactions.ts`: the legacy decrypt migration loops without backoff (~3 requests per 100 encrypted transactions), so a large account could hit the API throttle and abort the whole migration silently. It now honours Laravel's `Retry-After` header on 429 and retries the same request instead of bailing. ### State token persistence on failure - `AuthorizationController::callback`: clears `state_token` on the connection when EnableBanking session creation fails, preventing a stale token from being replayed. ### Trust proxies hardening - `bootstrap/app.php`: replaced `trustProxies(at: '*')` with an env-based `TRUSTED_PROXIES` config. When unset, no proxy is trusted (Laravel default) instead of trusting every IP. - ⚠️ **Deploy requirement:** production runs behind a reverse proxy / TLS terminator (`Dockerfile.production` + nginx serve HTTP on :80). With `TRUSTED_PROXIES` unset, Laravel stops trusting `X-Forwarded-For`/`X-Forwarded-Proto` → client IPs collapse to the proxy IP (contaminating logs and per-IP throttling) and HTTPS detection breaks. `TRUSTED_PROXIES` **must** be set in the production environment before merge, and should be added to `.env.production.example`. ### XSS-safe Blade-to-JS injection - `app.blade.php`: replaced `{{ }}` Blade syntax inside `