This project is in active development and only the latest published release is supported. Older versions will not receive backported security fixes — please update before reporting.
| Version | Supported |
|---|---|
| latest | ✅ |
| anything older | ❌ |
Please do not open a public GitHub Issue for security reports. Use GitHub's Private Vulnerability Reporting to send the report privately. That keeps the details off the public timeline until a fix is available.
If for some reason you cannot use Private Vulnerability Reporting, you can also reach the maintainer by opening a draft issue titled "Security: please reach out" without details, and we'll move the conversation to a private channel from there.
- A clear description of the issue
- Steps to reproduce (specific Zotero version, docling-serve version, plugin version, sample input if relevant)
- The impact you observed (file written outside expected directory, sensitive data leak, etc.)
- Any mitigations you've found
This plugin is solo-maintained on a best-effort basis. Realistic expectations:
- Acknowledgement: within ~1 week of report
- Triage and assessment: within ~2 weeks
- Fix and release: depends on severity and complexity; critical issues prioritised
Reporters will be credited in the release notes unless they prefer to remain anonymous.
The plugin supports optional authentication (Bearer token, Basic auth, or a custom header) against a protected docling-serve instance. These credentials are stored in Zotero.Prefs, which writes to a plain-text prefs.js file inside the user's Zotero profile directory. There is no OS-keyring integration in v1.
Practical implications:
- Anyone with read access to the user's Zotero profile directory can read the stored credentials. This includes other local users on the same machine, full-disk backups, and unencrypted sync targets.
- Use a least-privilege credential. Prefer a server-side API key scoped to docling-serve only, or a Basic-auth account with no other use, over a shared secret that grants access elsewhere.
- Prefer HTTPS for non-local servers. The configured auth header is sent on every request, including the
/healthpreflight; over plain HTTP it is visible to anyone on the network path. - Profile-directory threats remain out of scope (see below) — once an attacker has the profile, they can do worse things directly.
This plugin runs inside Zotero's plugin sandbox and communicates with a user-configured docling-serve HTTP endpoint. In-scope security concerns include:
- Arbitrary file write outside the intended location — e.g. a crafted PDF or server response that escapes the temp directory or export folder
- Prefs / config injection — a flaw that lets external content mutate plugin preferences
- Server URL handling — anything that lets a malicious actor redirect conversions to an attacker-controlled server without user consent
- Markdown injection that escapes its container — e.g. content that breaks out of Zotero's storage model or escapes the markdown attachment context
- Subprocess / privileged-API abuse — the plugin does not currently spawn subprocesses, but if it ever does, that surface is in scope
- Bugs in Docling itself — report those to the Docling team.
- Bugs in docling-serve — report to docling-serve's repository.
- Zotero itself — report to the Zotero team.
- Network-level attacks when the user has configured a remote
serverUrlover plain HTTP. The plugin trusts whatever endpoint the user points it at; use HTTPS for non-local servers. - Vulnerabilities that require the attacker to already have access to the user's Zotero profile directory — at that point the attacker can already do worse things directly.
This project is licensed under AGPL-3.0-or-later. If you redistribute a modified version of this plugin, you are responsible for the security of your fork. Security fixes from upstream are not automatically applied to forks.