Skip to content

Security audit β€” 2026-06-22#71

Open
versila22 wants to merge 1 commit into
mainfrom
security-audit-2026-06-22
Open

Security audit β€” 2026-06-22#71
versila22 wants to merge 1 commit into
mainfrom
security-audit-2026-06-22

Conversation

@versila22

Copy link
Copy Markdown
Owner

Pentest mini-report β€” versila22/lima-app β€” 2026-06-22

Probed URL: https://limaimpro.duckdns.org/
Stack: React 18 (Vite + SWC) / npm / PWA=no + FastAPI (Python) backend
Counts: Critical=0 High=2 Medium=3 Low=1 Info=2

Findings

Sev Cat Title Location
High SAST Hardcoded admin seed credentials in source code backend/app/main.py:54
High SAST Unclaimed Lovable.app URL auto-injected into CORS_ORIGINS backend/app/config.py:37,85
Medium SAST vitest 3.2.4 β€” arbitrary file read/execute via UI server (CVE <3.2.6) package.json
Medium Infra npm audit: 8Γ—High vulns in undici/serialize-javascript/vite/fast-uri package-lock.json
Medium DAST CSP style-src unsafe-inline (nginx) nginx.conf
Low SAST /health/db leaks DB URL prefix unauthenticated backend/app/main.py (health route)
Info DAST Live DAST skipped β€” egress policy blocks outbound to limaimpro.duckdns.org N/A
Info SAST SameSite=None on cookies (cross-origin Safari support; note CSRF surface) backend/app/utils/security.py

Top 3 fixes

  1. Admin seed credentials β€” Add if settings.APP_ENV == "development": return at top of _ensure_seed_data(), or move seed to a CLI script.
  2. CORS/FRONTEND_URL default β€” Remove default value https://improv-cabaret-planner.lovable.app from config.py:37; require it to be set explicitly in production env.
  3. vitest β€” Upgrade vitest to β‰₯3.2.6 in devDependencies.

Evidence (Critical/High only)

[High] Hardcoded admin seed credentials β€” backend/app/main.py:54

_SEED_MEMBERS = [
    {"email": "admin@lima-impro.fr", ..., "password": "Admin1234!", "app_role": "admin", ...},
]
async def _ensure_seed_data() -> None: ...  # called in lifespan on every startup, no APP_ENV guard

Impact: Attacker with repo access can try admin@lima-impro.fr / Admin1234! on the production API.
Fix: Gate with if settings.APP_ENV == "development": return or extract to dev-only CLI.

[High] Unclaimed Lovable.app URL in CORS_ORIGINS β€” backend/app/config.py:37

FRONTEND_URL: str = "https://improv-cabaret-planner.lovable.app"  # default fallback
# auto-injected into CORS_ORIGINS at startup (config.py:85), allow_credentials=True

Impact: If FRONTEND_URL not set in Railway env, that third-party domain gets credentialed CORS access to the API.
Fix: Set FRONTEND_URL="" as default, or raise ValueError if unset in non-dev mode.

Verified safe

  • No hardcoded secrets/API keys in frontend or backend source
  • JWT secret validator rejects default in non-dev mode
  • Cookies are httpOnly=True, Secure flag follows x-forwarded-proto
  • HSTS, nosniff, X-Frame-Options: DENY set in nginx
  • Backend SecurityHeadersMiddleware sets full OWASP header suite
  • Rate limiting via slowapi on auth routes
  • No XSS sinks (innerHTML, dangerouslySetInnerHTML, eval) in frontend
  • No tokens/keys in localStorage (httpOnly cookies used)
  • Docs endpoints disabled in production
  • No VAPID or service worker

Needs server-side verification

  • TLS 1.0/1.1 disabled (egress blocked, cannot check live)
  • Actual CORS headers on Railway backend (is FRONTEND_URL set?)
  • Whether APP_ENV=production is set in Railway env

Tools

ran=npm-audit,grep-secrets,grep-SAST,static-analysis; skipped=curl-DAST(egress-blocked),openssl-TLS(egress-blocked)


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant