Summary
Two compounding vulnerabilities in pdf-autofillr-doc-upload v0.1.5 allow an unauthenticated attacker to read arbitrary local files from the server via a single HTTP request to the /extract endpoint.
Package: pdf-autofillr-doc-upload
Affected versions: v0.1.5 (latest), all prior versions likely affected
Reported by: Farid Narimanov (independent security researcher) — coordinated disclosure
Vulnerability 1 — Auth bypass when AUTH_TOKEN is not set
File: pdf_autofillr_doc_upload/entrypoints/fastapi_app.py
def _check_api_key(provided: Optional[str]) -> None:
expected = os.environ.get("AUTH_TOKEN")
if not expected:
return # auth disabled
...
When AUTH_TOKEN is not configured in the environment (which is the default — no value is set out of the box), _check_api_key returns immediately without enforcing any authentication. Every endpoint protected by this check is publicly accessible with no credentials.
Vulnerability 2 — Path traversal / arbitrary file read in download_document()
File: pdf_autofillr_doc_upload/storage/local_storage.py
def download_document(self, source_path: str, local_dest: str) -> str:
src = Path(source_path)
dst = Path(local_dest)
if src.resolve() != dst.resolve():
dst.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(str(src), str(dst))
return str(dst)
The document_path field in ExtractRequest is a plain str with no validation, no allowed-directory check, and no path canonicalization. An attacker can supply any absolute path (e.g. /etc/passwd, SSH private keys, .env files) and the code will copy and process it — leaking its contents via the extraction pipeline response or job output endpoints. In deployments using an external LLM provider, the file contents are also sent to that provider as part of the extraction prompt.
Impact
These two vulnerabilities compound each other:
- Default config = no auth required
- No path restriction = any file readable
A single unauthenticated POST to /extract with a crafted document_path exfiltrates arbitrary server files.
Proof of Concept
# Auth bypass confirmed
from pdf_autofillr_doc_upload.entrypoints.fastapi_app import _check_api_key
_check_api_key(None) # returns without error when AUTH_TOKEN not set
# Path traversal confirmed
from pdf_autofillr_doc_upload.storage.local_storage import LocalStorage
storage = LocalStorage(data_path="/tmp/safe_upload_dir")
storage.download_document("/etc/passwd", "/tmp/out.txt")
# => contents of /etc/passwd copied and readable
Recommended Fixes
Auth bypass:
- Default
AUTH_TOKEN to a required field — fail closed if unset rather than open
- Or generate a random token on first run and log it to stdout
Path traversal:
- In
download_document(), validate that source_path.resolve() starts with the configured data_path
- Add the same check at the API layer in
ExtractRequest validation
# Example fix for download_document
def download_document(self, source_path: str, local_dest: str) -> str:
src = Path(source_path).resolve()
allowed_root = Path(self.data_path).resolve()
if not str(src).startswith(str(allowed_root)):
raise ValueError(f"Path '{source_path}' is outside the allowed directory")
...
Disclosure Timeline
- Reported privately to Engineersmind security team by Farid Narimanov
- Verified by internal security review
- Fix in progress — coordinated public disclosure planned after patch release
/cc @Deewang-Mathur — please prioritize a patched release
Summary
Two compounding vulnerabilities in
pdf-autofillr-doc-uploadv0.1.5 allow an unauthenticated attacker to read arbitrary local files from the server via a single HTTP request to the/extractendpoint.Package:
pdf-autofillr-doc-uploadAffected versions: v0.1.5 (latest), all prior versions likely affected
Reported by: Farid Narimanov (independent security researcher) — coordinated disclosure
Vulnerability 1 — Auth bypass when
AUTH_TOKENis not setFile:
pdf_autofillr_doc_upload/entrypoints/fastapi_app.pyWhen
AUTH_TOKENis not configured in the environment (which is the default — no value is set out of the box),_check_api_keyreturns immediately without enforcing any authentication. Every endpoint protected by this check is publicly accessible with no credentials.Vulnerability 2 — Path traversal / arbitrary file read in
download_document()File:
pdf_autofillr_doc_upload/storage/local_storage.pyThe
document_pathfield inExtractRequestis a plainstrwith no validation, no allowed-directory check, and no path canonicalization. An attacker can supply any absolute path (e.g./etc/passwd, SSH private keys,.envfiles) and the code will copy and process it — leaking its contents via the extraction pipeline response or job output endpoints. In deployments using an external LLM provider, the file contents are also sent to that provider as part of the extraction prompt.Impact
These two vulnerabilities compound each other:
A single unauthenticated POST to
/extractwith a crafteddocument_pathexfiltrates arbitrary server files.Proof of Concept
Recommended Fixes
Auth bypass:
AUTH_TOKENto a required field — fail closed if unset rather than openPath traversal:
download_document(), validate thatsource_path.resolve()starts with the configureddata_pathExtractRequestvalidationDisclosure Timeline
/cc @Deewang-Mathur — please prioritize a patched release