Files
ledgerdock/REPORT.md

5.4 KiB

Security Production Readiness Report

Date: 2026-03-01 Repository: /Users/bedas/Developer/GitHub/dcm Assessment type: Static code/configuration review with local security-test execution

Verdict

Not production ready.

Reason: one blocking, code-level security issue was found.

Scope

  • Backend API and worker code in backend/app
  • Frontend auth/API client code in frontend/src
  • Runtime/deployment configuration in .env and docker-compose.yml

Validation Commands And Outcomes

  • command -v git -> pass
  • git rev-parse --is-inside-work-tree -> pass (true)
  • git status --short -> clean working tree before analysis
  • /Users/bedas/Developer/Python/global_venv/bin/python backend/tests/test_security_controls.py -> pass (24 tests)
  • /Users/bedas/Developer/Python/global_venv/bin/python backend/tests/test_app_settings_provider_resilience.py -> pass (6 tests)
  • /Users/bedas/Developer/Python/global_venv/bin/python backend/tests/test_processing_log_retention_settings.py -> pass (5 tests)
  • /Users/bedas/Developer/Python/global_venv/bin/python backend/tests/test_upload_request_size_middleware.py -> failed to run (import error in test setup)
  • /Users/bedas/Developer/Python/global_venv/bin/python -m pytest ... -> not runnable in current venv (No module named pytest)

Blocking Security Findings

High: No brute-force protection on authentication login

  • Severity: High (blocking)
  • Why this is blocking: /api/v1/auth/login accepts unlimited credential attempts with no per-IP or per-username throttling, no lockout, and no backoff. This leaves credential stuffing and password guessing defenses incomplete for production.
  • Impact: online account takeover risk increases substantially when passwords are weak, reused, leaked, or defaulted.
  • Exploit path: repeated automated POST requests to /api/v1/auth/login until valid credentials are found.
  • Evidence:
    • backend/app/api/routes_auth.py:34 defines login endpoint
    • backend/app/api/routes_auth.py:42 to backend/app/api/routes_auth.py:51 performs auth check and returns 401 only
    • backend/app/api/routes_documents.py:75 to backend/app/api/routes_documents.py:95 shows rate limiting exists but is applied only to content export, not login
    • backend/app/services/rate_limiter.py:16 to backend/app/services/rate_limiter.py:42 contains reusable limiter logic currently not used by auth routes
  • Required remediation:
    • add login throttling keyed by username and source IP
    • add escalating delay or temporary lockout on repeated failures
    • return a stable error message and status on throttled attempts
    • log and monitor failed auth attempt rates

Additional Code-Level Findings (Non-blocking)

Medium: Non-deterministic frontend dependency versioning

  • Severity: Medium
  • Risk: lucide-react is set to latest, making builds time-dependent and increasing supply-chain unpredictability.
  • Evidence:
    • frontend/package.json:13
  • Recommendation:
    • pin an explicit semver version and update intentionally via dependency review workflow

Low: One security middleware regression test is currently not executable

  • Severity: Low
  • Risk: reduced confidence in continued enforcement of upload middleware behavior.
  • Evidence:
    • backend/tests/test_upload_request_size_middleware.py currently errors at import time when run directly in this environment
  • Recommendation:
    • fix test stubs/import assumptions so this test is runnable in CI and local developer environments

MUST KNOW User-Dependent Risks (Not Blocking Per Request)

These are deployment/operator-controlled and therefore reported as must-know, not blocking findings.

  1. Environment is set to development posture with broad host binding.
  • Evidence: .env:1 (APP_ENV=development), .env:2 (HOST_BIND_IP=0.0.0.0)
  • Risk: exposed surface and relaxed defaults if used outside isolated development network.
  1. Bootstrap credentials appear placeholder/weak and must be replaced before live use.
  • Evidence: .env:15, .env:17
  • Risk: straightforward credential compromise if unchanged.
  1. Sensitive log text persistence is enabled in current .env.
  • Evidence: .env:22, .env:23; code path at backend/app/services/processing_logs.py:47 and backend/app/services/processing_logs.py:128
  • Risk: OCR/model prompts, responses, and payload text can be stored and later exposed to admins or backups.
  1. Provider outbound network controls are permissive in current .env.
  • Evidence: .env:29 to .env:31
  • Risk: admin-configured provider endpoints can target non-HTTPS/private hosts if account compromise occurs.
  1. Public base URL is HTTP and CORS includes LAN origin.
  • Evidence: .env:33, .env:34
  • Risk: transport security and origin trust are weaker than production HTTPS allowlist posture.
  1. Redis transport is non-TLS in current env posture.
  • Evidence: .env:10 to .env:12
  • Risk: acceptable for isolated local stack, unsafe for untrusted networks.
  1. Compose defaults are development-first for several sensitive controls.
  • Evidence: docker-compose.yml:40, docker-compose.yml:52, docker-compose.yml:53, docker-compose.yml:60, docker-compose.yml:68
  • Risk: if overrides are missed, deployment may run with weaker network and provider policies.

Production Decision

Current state is not production ready due to the blocking auth brute-force gap.

After fixing the blocking issue, production readiness still depends on secure operator configuration of .env and runtime network perimeter.