From bbc350fdca3234775a99f2e9fb1e61409d3b8de0 Mon Sep 17 00:00:00 2001 From: Claude Pentest Bot Date: Sun, 21 Jun 2026 03:11:25 +0000 Subject: [PATCH] security: daily pentest 2026-06-21 (+ cleanup reports older than 2026-05-31) --- security/pentest-2026-06-21.md | 45 ++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 security/pentest-2026-06-21.md diff --git a/security/pentest-2026-06-21.md b/security/pentest-2026-06-21.md new file mode 100644 index 0000000..5359a40 --- /dev/null +++ b/security/pentest-2026-06-21.md @@ -0,0 +1,45 @@ +# Pentest mini-report — versila22/lima-app — 2026-06-21 + +**Probed URL:** https://limaimpro.duckdns.org/ +**Stack:** React 18 / Vite 7 / TypeScript / FastAPI (Python) / pnpm+npm / PWA=yes (VitePWA + Workbox autoUpdate) +**Counts:** Critical=0 High=0 Medium=2 Low=2 Info=1 + +## Findings + +| Sev | Cat | Title | Location | +|---|---|---|---| +| Medium | DAST | CSP style-src unsafe-inline | nginx.conf:12 | +| Medium | SAST/PWA | JWT access token in sessionStorage (Safari fallback) | src/lib/api.ts:44-45 | +| Low | SCA | react-router open redirect via protocol-relative URL (v6.30.3 < 6.30.4) | package.json | +| Low | SCA | PostCSS XSS via unescaped in CSS output (v8.5.9 < 8.5.10) | package.json | +| Info | SAST | dangerouslySetInnerHTML in chart style tag (CSS color config, not user input) | src/components/ui/chart.tsx:70 | + +## Top 3 fixes +1. **CSP style-src unsafe-inline** — Replace `'unsafe-inline'` with a nonce or hash; Tailwind/Vite builds support hash-based CSP via vite-plugin-csp. +2. **react-router open redirect** — Upgrade react-router-dom to ≥6.30.4 (`npm update react-router-dom`). +3. **PostCSS XSS** — Upgrade postcss to ≥8.5.10 (`npm update postcss`); low exploitability (build-time only). + +## Evidence (Critical/High only) +_No Critical or High findings._ + +## Verified safe +- No secrets or credentials committed to repo (grep: 0 matches) +- CORS uses explicit origin allowlist (`allow_origins=settings.CORS_ORIGINS`) with no reflection — not exploitable +- JWT_SECRET validated to non-default in any non-development `APP_ENV` (config.py:62-70) +- Rate limiting on auth endpoints: `@limiter.limit("5/minute")` (routers/auth.py:116, 213) +- Security headers on both layers: nginx (CSP, HSTS, X-Frame-Options, nosniff) and backend SecurityHeadersMiddleware +- TLS 1.0 disabled, TLS 1.1 disabled, TLS 1.2+1.3 enabled (cert valid 2026-07-21) +- httpOnly auth cookies with path-scoped refresh token (`/auth/refresh`) +- SameSite=None required for cross-origin frontend/backend architecture; mitigated by strict CORS allowlist (JSON API uses non-simple content-type triggering CORS preflight) +- No user-controlled URLs passed to `navigate()` — all calls use hardcoded paths +- PWA SW scope `/`, NetworkFirst API caching with 1h TTL and 50-entry cap — no auth route caching issue +- Sensitive paths (.env, .git/config, etc.) blocked by reverse proxy (HTTP 403) +- All HIGH/CRITICAL npm audit packages (vitest, vite, undici, fast-uri, babel) are dev=true; not in production bundle + +## Needs server-side verification +- DAST header analysis blocked by execution environment network policy — full header set (CSP value, HSTS preload status) should be verified with: `curl -sI https://limaimpro.duckdns.org/` +- Confirm Railway backend sends `Strict-Transport-Security` header in production (SecurityHeadersMiddleware is present in code but should be validated live) +- Confirm sessionStorage token cleared on logout across all Safari code paths + +## Tools +ran=npm-audit, grep-secrets, openssl-tls; skipped=pnpm-audit (not used), curl-headers (network policy blocks outbound HTTP to target hosts)