Skip to content

OWASP Top 10 hardening — injection, auth, headers, logging, passwords#53

Merged
MotWakorb merged 8 commits intodevfrom
owasp-hardening
Mar 31, 2026
Merged

OWASP Top 10 hardening — injection, auth, headers, logging, passwords#53
MotWakorb merged 8 commits intodevfrom
owasp-hardening

Conversation

@MotWakorb
Copy link
Copy Markdown
Owner

Summary

Security hardening based on OWASP Top 10 evaluation. Addresses findings across 6 categories:

  • A03/A10 Injection & SSRF: ffmpeg -protocol_whitelist on all invocations, URL scheme validation (http/https only) on M3U/XC/EPG input endpoints
  • A01/A07 Auth: Login rate limiting (5/min per IP via slowapi), client IP in failure logs
  • A05 Misconfiguration: Security headers (X-Frame-Options, X-Content-Type-Options, Referrer-Policy), CORS restricted to explicit methods/headers
  • A09 Logging: Global 500 response scrubbing (generic message, real error stays in logs), auth header/body redaction in validation error logs
  • A07 Passwords: NIST 800-63B alignment — drop composition rules, 10k common password list, uniform 8-char minimum for all users including admin-created
  • A03 Hardening: Zip backup path canonicalization (defense-in-depth)

Commits

  1. a6ba953 ffmpeg protocol whitelist + URL scheme validation
  2. addc6b3 Login rate limiting with slowapi
  3. dd16f55 Security headers, CORS, 500 scrubbing, log redaction
  4. 89e7f93 NIST 800-63B password policy
  5. 31b95b6 Zip backup path canonicalization
  6. 4927aed Test updates

Test plan

  • Backend: 2263 tests pass
  • Frontend: 1027 tests pass
  • file://, data://, gopher:// URLs rejected with 400 at M3U/EPG endpoints
  • Stream preview works with protocol whitelist (http streams play normally)
  • Login rate limiting: 6th attempt in 1 minute returns 429
  • Security headers present on all responses (verified via curl)
  • 500 responses return generic "Internal server error" (no leaked details)
  • Validation error logs redact Authorization header and auth endpoint bodies
  • All-lowercase passwords accepted (no composition rules)
  • Common passwords ("password", "12345678") rejected
  • Admin-created users subject to same password policy
  • CORS preflight returns explicit methods/headers, not wildcards
  • UI functional after frontend build deploy

🤖 Generated with Claude Code

Claude and others added 8 commits March 30, 2026 22:08
Restrict ffmpeg/ffprobe to safe protocols (http,https,tcp,udp,rtp,rtmp,pipe)
via -protocol_whitelist flag on all invocations. Validate URL schemes
(http/https only) at input time on M3U, XC, and EPG source endpoints.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rate limit /api/auth/login and /api/auth/dispatcharr/login to 5 requests
per minute per IP. Uses slowapi with in-memory backend. Includes client IP
in login failure logs for forensics. Disabled in tests via env var.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…5/A09)

- Security headers middleware: X-Frame-Options DENY, X-Content-Type-Options
  nosniff, Referrer-Policy strict-origin-when-cross-origin
- CORS: replace wildcard methods/headers with explicit allow lists
- Global HTTPException handler scrubs 500 response bodies to generic message
- Validation error handler redacts Authorization/Cookie headers and auth
  endpoint request bodies from logs
- Register slowapi rate limit handler

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Drop composition rules (uppercase/lowercase/number) per NIST guidance.
Replace 33-word inline list with 10k common passwords file. Apply uniform
8-char minimum to admin-created users. Remove frontend composition checks
from SetupPage and ResetPasswordPage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add os.path.resolve() check to verify extracted zip paths stay within
CONFIG_DIR. Defense-in-depth alongside existing '..' and absolute path
checks — current code already uses zf.read()+write_bytes() not extractall().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Assert generic 'Internal server error' on 500 responses (scrubbed)
- Remove composition rule tests, add NIST-aligned password tests
- Disable rate limiting in test environment
- Update backup test expectations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Channel names from Dispatcharr include the channel number (e.g.,
"535 | Willow 2"). The normalizer kept the digits, producing
"535willow2" instead of "willow2", guaranteeing zero EPG matches.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@MotWakorb MotWakorb merged commit 12eb842 into dev Mar 31, 2026
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