Files
jobtrackingapp/docs/cv-import/SECURITY.md
T

4.3 KiB

Security and privacy assessment

26 October 2026. Decision: CONDITIONAL, not production security acceptance.

Boundary / threat Implemented protection Evidence / remaining limit
Upload spoofing/exhaustion Authenticated entitlement/admission, 5 MiB cap, extension/signature validation, SHA identity, active duplicate reuse, pending/file caps Backend admission/security regressions; distributed abuse/load qualification open
Malicious DOCX Entry/path/expanded-size/ratio limits, DTD prohibited, XML resolver disabled, bounded XML, reject active/external payloads Real archive/DTD/security tests; inert http/https/mailto hyperlink text allowed without dereferencing
Malicious PDF Page cap, active/embedded/launch/script content rejection, local native conversion Inert web/mailto links allowed; binary/native parser vulnerabilities require ongoing patch qualification
Parser side effects Existing private subprocess, stripped environment/private HOME, offline configuration, deny network/process audit hook, timeout/tree termination, one child, POSIX limits Real native extraction and network-disabled/read-only Linux tests; audit hook is defense in depth, not a native-code security boundary; Windows memory ceiling open
SSRF/external AI Active import is deterministic; optional local adapter disabled, local address restrictions, no proxy/redirect, strict schema Synthetic adapter tests; no external document transfer or actual model inference
Prompt injection/unsupported output CV text is untrusted data; constrained source references, schema/category/date/token validation; every selected value reviewed Deterministic injected-text fixture + synthetic adversarial responses; semantic model adversarial qualification BLOCKED
Cross-user/tenant access Existing authenticated principal ownership in run/artifact/operation/profile/source APIs Unit/provider + browser foreign-owner 404; no alternate tenant key accepted from caller
Stale/lost writes Canonical expected revision, existing atomic transaction/history/children/projection, lease-conditioned publication/status, idempotent apply Actual MariaDB stale/rollback/idempotency, RD21 regressions; successful response follows durable commit
Privacy/retention Original source private/no-store/nosniff, authenticated blob preview, safe owned paths, bounded sanitized parser errors, cleanup retry and reparse/root checks Retention/orphan/cancel/expiry tests; account export/delete reuse existing owners

Original import files and extraction evidence last up to seven days (one day for failed/cancelled/discarded work), plus up to the hourly sweep interval while the application is running. Startup sweep catches expired work after downtime. Pending work is revoked before deletion; failed deletion retains the reference for retry. Original source becomes unavailable after expiration. Approved canonical facts, review history and approved evidence snippets follow existing account-retention/deletion policy; they are not silently deleted with the temporary source. Operators must account for normal backup retention separately.

No production services, Docker configuration, MariaDB schema, filesystem, model cache, Ollama model or deployment was changed. Test containers use owned disposable identities and synthetic documents. Test service port is loopback-only. New dependencies were installed only into isolated development runtimes and hash-verified wheel contexts. Current dependency checks: npm 881 dependencies / zero reported vulnerabilities, NuGet API no reported vulnerable packages, CV-import Python lock 48 dependencies / zero skipped / zero reported vulnerabilities. Evidence: .artifacts/cv-import/{npm-audit-01.json,dotnet-audit-01.json,pip-audit-01.json}. Advisory queries are point-in-time checks, not proof against all vulnerabilities.

Inherited legacy Python/model/cache advisory qualification, production filesystem integrity, off-disk backup/recovery and hosted-provider isolation remain unresolved or unverified. New slim lock auditing does not close those gates. The current local AI adapter is a tested seam and remains disconnected from active processing until isolated model qualification can establish relationship grounding, compatibility and privacy controls. No permanent general-purpose model is selected.