Skip to content

security: harden input validation, resource limits, and file permissions#63

Open
alexander-morris wants to merge 1 commit intosteipete:mainfrom
alexander-morris:security/audit-fixes
Open

security: harden input validation, resource limits, and file permissions#63
alexander-morris wants to merge 1 commit intosteipete:mainfrom
alexander-morris:security/audit-fixes

Conversation

@alexander-morris
Copy link
Copy Markdown

Summary

Comprehensive security audit with fixes for 12 findings across input validation, resource consumption, file permissions, and concurrency safety.

Changes

Resource Limits (HIGH):

  • Add 100MB file size check before reading uploads into memory (send_file.go)
  • Add 100MB media download size limit to prevent disk exhaustion (wa/media.go)

File Permissions (MEDIUM):

  • Enforce 0600 permissions on SQLite database files after creation (store/db.go)
  • Reject store paths containing URI-special characters ? and # (store/db.go, wa/client.go)

Input Validation (MEDIUM):

  • Validate phone numbers against E.164 format (^\d{1,15}$) in ParseUserOrJID (wa/client.go)

SQL Safety (LOW):

  • Escape LIKE metacharacters (%, _) in all search queries with ESCAPE '\' (store/search.go, store/chats_contacts_groups.go)
  • Sanitize FTS5 queries by wrapping in double-quotes to prevent operator injection (store/search.go)
  • Validate table names against ^[a-zA-Z_][a-zA-Z0-9_]*$ in PRAGMA queries (store/migrations.go)

Path Safety (LOW):

  • Strip null bytes and control characters in SanitizeSegment and SanitizeFilename (pathutil/sanitize.go)

Concurrency & Stability (MEDIUM/LOW):

  • Add defer recover() in event handler and media worker goroutines (app/sync.go, app/media.go)
  • Fix goroutine leak: drop media jobs when queue full instead of spawning unbounded goroutines (app/sync.go)
  • Use sync.Once to prevent race condition in OpenWA initialization (app/app.go)
  • Add forced exit on second SIGINT during sync (cmd/wacli/sync.go)

Related Issues

Closes #50, closes #51, closes #52, closes #55, closes #56, closes #57, closes #58, closes #59, closes #60, closes #61, closes #62

Issues #53 (rate limiting) and #54 (unbounded history sync) are documented but require more extensive changes beyond this PR.

Test plan

  • Verify wacli send file rejects files > 100MB
  • Verify media downloads are rejected when fileLength > 100MB
  • Verify database files are created with 0600 permissions
  • Verify phone number validation rejects non-digit input
  • Verify LIKE search with % or _ returns literal matches
  • Verify FTS5 search treats operators as literal text
  • Run existing test suite: go test ./...
  • Verify second Ctrl+C during sync --follow forces immediate exit

🤖 Generated with Claude Code

Address findings from a comprehensive security audit:

- Add file size limit (100MB) before reading uploads into memory
- Add media download size limit to prevent disk exhaustion
- Enforce 0600 permissions on SQLite database files
- Validate phone numbers against E.164 format (1-15 digits)
- Escape LIKE metacharacters (%, _) in all search queries
- Sanitize FTS5 queries to prevent operator injection
- Validate table names in PRAGMA queries
- Strip null bytes and control characters in path sanitization
- Add panic recovery in event handler and media worker goroutines
- Fix goroutine leak: drop media jobs when queue full instead of spawning
- Add forced exit on second SIGINT during sync
- Use sync.Once to prevent race condition in OpenWA initialization
- Reject paths containing URI-special characters for SQLite connections

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment