# SCAN: privategpt date: 2026-02-13 | program: privategpt | repo: https://github.com/zylon-ai/private-gpt | bounty: $0-$1500 ## summary raw_findings: 6 | real: 0 | high_conf: 0 | med_conf: 0 | low_conf: 0 | false_pos: 6 scan_method: manual_review version: 0.6.2 ## analysis notes Thorough manual review of all API endpoints, auth system, file ingestion pipeline, settings loading, YAML parsing, and document management. No semgrep or trufflehog results available. ### Known CVEs verified as fixed - CVE-2024-3403 (LFI via file upload): FIXED. File ingestion now uses `tempfile.NamedTemporaryFile` - user-supplied filename only used for extension detection and metadata, never as a file path for reading. - CVE-2024-5186 (SSRF via file upload path): FIXED. No URL-based ingestion endpoints exist in v0.6.2. - CVE-2024-5936 (Open redirect): No redirect functionality found in current codebase. ### Architecture observations (not reportable) - Auth disabled by default (`auth.enabled: false` in settings.yaml). By design for local use. - CORS allows all origins/methods/headers by default. By design. - Server binds to 0.0.0.0. By design for Docker. - No multi-tenant isolation - all users share one vector store. By design (single-user tool). - HuggingFace `trust_remote_code: true` in default config. Documented risk, not user-exploitable at runtime. - No rate limiting on any endpoint. ## findings (none meet reporting threshold) --- ## skipped | file:line | rule | reason | |-----------|------|--------| | private_gpt/server/ingest/ingest_router.py:60 | file.filename user-controlled | Only used for extension detection via Path(name).suffix and stored as metadata; actual file written to tempfile. No path traversal. Already fixed from CVE-2024-3403. | | private_gpt/server/ingest/ingest_router.py:80 | ingest_text file_name user-controlled | Same as above - file_name from body only affects extension detection and metadata storage. | | private_gpt/settings/yaml.py:20 | YAML loading | Uses SafeLoader with custom env var resolver. No deserialization risk. | | private_gpt/server/utils/auth.py:42 | timing-safe comparison | Uses `secrets.compare_digest` - correct. Auth is disabled by default but that's documented behavior. | | private_gpt/server/recipes/summarize/summarize_router.py:19 | user-controlled prompt parameter | Prompt injection is inherent to LLM apps. The prompt parameter lets users customize summarization - this is intended functionality, not a vulnerability. No system-level impact. | | private_gpt/settings/settings.yaml:9 | CORS allow_origins: ["*"] | Intentional default config for local development. All deployment guides recommend configuring this. |