Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions security/pentest-2026-06-29.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Pentest mini-report — versila22/lima-app — 2026-06-29

**Probed URL:** https://limaimpro.duckdns.org/
**Stack:** React 18 + Vite 7 + TanStack Query + Radix UI (frontend) / FastAPI + Python-jose + SQLAlchemy (backend) / npm / PWA=yes (Workbox NetworkFirst, autoUpdate)
**Counts:** Critical=0 High=0 Medium=2 Low=1 Info=2

## Findings

| Sev | Cat | Title | Location |
|---|---|---|---|
| Medium | DAST | Unauthenticated health endpoints expose DB schema & stack traces | `backend/app/main.py:GET /health/db, /health/migrations` |
| Medium | SCA | react-router-dom 6.30.3 open redirect via `//`-prefixed path | `package.json` (react-router 6.30.3) |
| Low | SAST | Hardcoded default JWT secret in source (guarded by startup validator) | `backend/app/config.py:10` |
| Info | PWA | API responses cached 1 h NetworkFirst — stale data possible after logout | `vite.config.ts:workbox.runtimeCaching` |
| Info | SCA | Dev-toolchain vulns (vitest critical, vite/undici/fast-uri/serialize-js high) — no production impact | `package.json devDependencies` |

## Top 3 fixes
1. **Health endpoint auth** — Add an API-key or admin-only guard to `/health/db` and `/health/migrations`; remove the traceback from the JSON response body.
2. **react-router open redirect** — Upgrade to a patched release once available, or sanitize any user-controlled `redirect` param to block `//`-prefixed values.
3. **Dev dep upgrades** — Run `npm audit fix` to clear vitest critical and downgrade-chain highs (affects CI security, not production runtime).

## Evidence (Critical/High only)
*No Critical or High findings.*

## Verified safe
- No XSS sinks (`dangerouslySetInnerHTML`, `innerHTML=`, `eval`) found in `src/`
- No hardcoded API keys, bearer tokens, or private key material in tracked files
- CORS: explicit allowlist, `allow_credentials=True`, no wildcard origins
- Cookie flags: `httponly=True`, `secure` tied to request scheme, `samesite="none"` when HTTPS, `"lax"` otherwise
- Security headers middleware active: HSTS 1 yr, nosniff, X-Frame-Options DENY, CSP default-src 'none', Referrer-Policy, Permissions-Policy
- TLS: 1.0 and 1.1 disabled; 1.2 + 1.3 enabled; cert valid until 2026-07-29
- FastAPI `/docs` and `/redoc` disabled in non-development mode
- JWT secret startup validator refuses to start in production with the default value
- Sensitive files (.env, .git/config): network policy blocks external DAST probing (all 000)

## Needs server-side verification
- DAST headers (HSTS, CSP, nosniff) on https://limaimpro.duckdns.org/ — egress blocked; verified only via backend middleware source
- Cookie Secure/SameSite flags on live session cookies — requires browser/proxy inspection
- python-jose 3.5.0 CVE status — pip-audit unavailable; HS256 usage means algorithm-confusion CVEs don't apply, but confirm with `pip-audit -r backend/requirements.txt`
- PWA cache behaviour: confirm logout correctly invalidates cached API responses or SW is cleared on sign-out

## Tools
ran=npm-audit, grep-secrets, openssl-s_client (TLS/cert), grep-SAST; skipped=pip-audit (not installed), curl-DAST (egress blocked by network policy — 403 from proxy for all DAST checks)
Loading