From 548fe85bd8813d0beac11c56a64e42f79d5ed4a2 Mon Sep 17 00:00:00 2001 From: Claude Pentest Bot Date: Tue, 23 Jun 2026 03:09:27 +0000 Subject: [PATCH] security: daily pentest 2026-06-23 (+ cleanup reports older than 2026-06-02) --- security/pentest-2026-06-23.md | 45 ++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 security/pentest-2026-06-23.md diff --git a/security/pentest-2026-06-23.md b/security/pentest-2026-06-23.md new file mode 100644 index 0000000..bf31857 --- /dev/null +++ b/security/pentest-2026-06-23.md @@ -0,0 +1,45 @@ +# Pentest mini-report — versila22/lima-app — 2026-06-23 + +**Probed URL:** https://limaimpro.duckdns.org/ +**Stack:** React 18 (Vite/SWC) + FastAPI (Railway) / npm / PWA=yes (workbox, autoUpdate) +**Counts:** Critical=0 High=0 Medium=2 Low=3 Info=2 + +## Findings + +| Sev | Cat | Title | Location | +|---|---|---|---| +| Medium | SAST | Auth token stored in sessionStorage (Safari ITP workaround) | `src/lib/api.ts:45` | +| Medium | Infra | devDep npm vulns — vitest CVSS 9.8, vite, undici (6 high) | `package.json` / npm audit | +| Low | DAST | CSP `style-src 'unsafe-inline'` | `nginx.conf:26` | +| Low | SAST | react-router@6.30.3 same-origin open redirect (CWE-601) | `package.json` | +| Low | SAST | Sidebar cookie missing `Secure;SameSite` flags | `src/components/ui/sidebar.tsx:68` | +| Info | SAST | Default FRONTEND_URL (lovable.app) auto-appended to CORS whitelist | `backend/app/config.py:35,85-87` | +| Info | DAST | HTTP response headers unverified (egress blocked in audit env) | `https://limaimpro.duckdns.org/` | + +## Top 3 fixes +1. **devDep vulns** — `npm update vitest vite undici` and pin to patched versions in package.json +2. **sessionStorage auth token** — prefer httpOnly-only cookie flow; reduce `ACCESS_TOKEN_EXPIRE_MINUTES` (currently 480 min) if sessionStorage fallback is retained +3. **CSP unsafe-inline styles** — replace `style-src 'unsafe-inline'` with content hash or nonce in nginx.conf + +## Evidence (Critical/High only) + +_No Critical or High findings this run._ + +## Verified safe +- No XSS sinks: `dangerouslySetInnerHTML`, `innerHTML`, `eval` — none found in `src/` +- No hardcoded secrets in client source (VITE_API_URL only, not sensitive) +- Nginx serves HSTS (max-age=31536000), X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy, Permissions-Policy per `nginx.conf` +- Backend CORS uses explicit whitelist (`allow_origins=settings.CORS_ORIGINS`) with `allow_credentials=True` — no wildcard reflection +- PWA SW scope `/`; API caching uses NetworkFirst; auth tokens not in localStorage +- TLS 1.0/1.1 disabled; TLS 1.2 + 1.3 only +- No prototype pollution surface (no Object.assign/lodash.merge on user input) +- No postMessage listeners without origin validation + +## Needs server-side verification +- CORS reflection on production Railway API (`https://api-production-e15b.up.railway.app`) — verify `Access-Control-Allow-Origin` is never reflected from request `Origin` +- Actual HTTP response headers from limaimpro.duckdns.org (nginx.conf has correct config, but deployment must be confirmed) +- `FRONTEND_URL` and `JWT_SECRET` env vars overridden in Railway environment (defaults are `lovable.app` URL and `insecure_dev_secret_change_me`) +- Sensitive path probing (`.env`, `.git/config`) — all returned 403 from audit env proxy, not from actual server + +## Tools +ran=npm-audit, grep-secrets, openssl-tls; skipped=pnpm-audit (not installed), DAST-curl (egress policy blocks limaimpro.duckdns.org and railway API)