diff --git a/.github/ISSUE_TEMPLATE/security.md b/.github/ISSUE_TEMPLATE/security.md new file mode 100644 index 0000000..8fc18d4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/security.md @@ -0,0 +1,30 @@ +--- +name: Security Vulnerability +about: Report a security vulnerability privately +title: '[SECURITY] ' +labels: security +--- + +# Security Vulnerability Report + +**IMPORTANT:** This issue template is for reference only. **Do NOT submit a public issue for security vulnerabilities.** + +Security vulnerabilities must be reported through private channels only: + +1. **Email (preferred):** [security@jedarden.com](mailto:security@jedarden.com) + - PGP-encrypted emails are strongly encouraged + - PGP key: [`docs/security/pgp-public-key.asc`](../docs/security/pgp-public-key.asc) + - PGP key fingerprint: See README.md + +2. **GitHub Private Vulnerability Reporting:** + - Use the [Security tab](https://github.com/jedarden/pdftract/security/advisories) + - This provides a private discussion forum + +See [`SECURITY.md`](../SECURITY.md) for details on our disclosure process, supported versions, and safe harbor policy. + +**Why not a public issue?** +- Public issues expose vulnerabilities to attackers before a fix is available +- We need time to prepare patches for supported versions +- We coordinate with downstream packagers (Homebrew, distros) before disclosure + +Thank you for helping keep pdftract secure! diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 67166ac..d8c123c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -94,4 +94,23 @@ cargo fmt --check ## Security +### Responsible Disclosure + +If you discover a security vulnerability, please do **NOT** open a public issue or pull request. Instead, report it privately: + +1. **Email (preferred):** [security@jedarden.com](mailto:security@jedarden.com) + - PGP-encrypted emails are strongly encouraged + - PGP key: [`docs/security/pgp-public-key.asc`](docs/security/pgp-public-key.asc) + +2. **GitHub Private Vulnerability Reporting:** + - Use the [Security tab](https://github.com/jedarden/pdftract/security/advisories) + +See [`SECURITY.md`](SECURITY.md) for our full disclosure policy, including: +- Supported versions and security fix timeline +- 90-day disclosure window +- CVE assignment process +- Safe harbor for good-faith researchers + +### Supply-Chain Security + This project uses `cargo-audit` and `cargo-deny` for supply-chain security. New direct dependencies require an ADR or written justification in the PR description. diff --git a/README.md b/README.md index 05f46a3..8410205 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,76 @@ Rust core with PyO3 Python bindings and a CLI binary. The same binary runs as a See `docs/research/` for technical deep-dives into the PDF specification, font encoding, glyph Unicode recovery, and tagged PDF structure. See `docs/notes/` for SDK invocation examples in Python, Node.js, Go, Ruby, Java, Rust, and Bash. +## Verifying Releases + +All releases are signed using [Sigstore](https://sigstore.dev/) keyless signing with OIDC from the iad-ci cluster. This provides cryptographic proof that artifacts were produced by the official CI/CD pipeline and haven't been tampered with. + +### Verify Binary Archives + +To verify downloaded binary archives: + +```bash +# Download release artifacts +gh release download vX.Y.Z --dir /tmp/pdftract-release + +# Verify the SHA256SUMS signature +cosign verify-blob \ + --certificate-identity-regexp 'https://iad-ci-oidc.ardenone.com.*' \ + --certificate-oidc-issuer 'https://iad-ci-oidc.ardenone.com' \ + --signature SHA256SUMS.sig \ + --certificate SHA256SUMS.pem \ + SHA256SUMS + +# Verify individual artifacts against checksums +sha256sum -c SHA256SUMS +``` + +### Verify Docker Images + +To verify Docker images before running them: + +```bash +# Verify the main image +cosign verify \ + --certificate-identity-regexp 'https://iad-ci-oidc.ardenone.com.*' \ + --certificate-oidc-issuer 'https://iad-ci-oidc.ardenone.com' \ + ghcr.io/jedarden/pdftract:X.Y.Z + +# Verify the OCR variant +cosign verify \ + --certificate-identity-regexp 'https://iad-ci-oidc.ardenone.com.*' \ + --certificate-oidc-issuer 'https://iad-ci-oidc.ardenone.com' \ + ghcr.io/jedarden/pdftract:ocr-X.Y.Z + +# Verify the full variant +cosign verify \ + --certificate-identity-regexp 'https://iad-ci-oidc.ardenone.com.*' \ + --certificate-oidc-issuer 'https://iad-ci-oidc.ardenone.com' \ + ghcr.io/jedarden/pdftract:full-X.Y.Z +``` + +### View SLSA Provenance + +Each Docker image includes SLSA provenance attestation: + +```bash +cosign verify-attestation \ + --certificate-identity-regexp 'https://iad-ci-oidc.ardenone.com.*' \ + --certificate-oidc-issuer 'https://iad-ci-oidc.ardenone.com' \ + --type slsaprovenance \ + ghcr.io/jedarden/pdftract:X.Y.Z +``` + +The provenance includes the build configuration, source commit, and builder identity. + +## Security + +For responsible disclosure of security vulnerabilities, please email [security@jedarden.com](mailto:security@jedarden.com). See [`SECURITY.md`](SECURITY.md) for our disclosure policy, supported versions, and PGP key for encrypted reports. + +**PGP Key:** The public key for `security@jedarden.com` is available at [`docs/security/pgp-public-key.asc`](docs/security/pgp-public-key.asc). + +> **NOTE:** The PGP key is currently a placeholder. The security contact must generate and publish a 4096-bit RSA key for `security@jedarden.com`. See `docs/security/pgp-public-key.asc` for generation instructions. + ## Status Early development. See `docs/plan/` for the implementation roadmap. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..31a6376 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,89 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +|---------|-----------| +| Latest minor release | Yes | +| Previous minor release | Yes (security fixes only) | +| Older releases | No | + +Security updates are published for the latest minor release and the previous minor release. Older releases do not receive security updates — users must upgrade to a supported version. + +## Reporting a Vulnerability + +**Do NOT open a public issue or pull request for security vulnerabilities.** + +### Private Disclosure + +Please report vulnerabilities privately using one of the following methods: + +1. **Email (preferred):** [security@jedarden.com](mailto:security@jedarden.com) + - PGP-encrypted emails are strongly encouraged + - PGP key fingerprint: `PLACEHOLDER — see docs/security/pgp-public-key.asc for instructions` + - Public key available at: [`docs/security/pgp-public-key.asc`](docs/security/pgp-public-key.asc) + +2. **GitHub Private Vulnerability Reporting:** + - Use the [Security tab](https://github.com/jedarden/pdftract/security/advisories) on this repository + - This provides a private discussion forum coordinated with GitHub's security team + +## Disclosure Window + +Our disclosure timeline is designed to balance rapid fixes with thorough, safe deployment: + +| Stage | Timeline | +|-------|----------| +| **Acknowledgment** | Within 48 hours of receipt | +| **Initial Triage** | Within 5 business days (confirmed/disputed/need-more-info) | +| **Fix & CVE Publication** | Within 90 days of confirmation | +| **Public Disclosure** | Simultaneous with fix release | + +- **Extension policy:** The 90-day window may be extended by mutual agreement for complex issues requiring coordinated fixes across multiple releases or downstream ecosystems. +- **Embargoed coordination:** For major vulnerabilities, we coordinate disclosure with downstream packagers (Homebrew, Linux distributions) prior to public announcement. + +## CVE Assignment + +CVEs are assigned via [GitHub Security Advisories](https://github.com/jedarden/pdftract/security/advisories). GitHub is a CVE CNA (CVE Numbering Authority), which allows us to request CVEs directly without going through the MITRE backlog. + +- Researchers are credited in the advisory unless they request anonymity. +- Vulnerability severity is assessed using the [CVSS v3.1](https://www.first.org/cvss/calculator/3.1) standard. + +## Scope + +### In Scope + +The following classes of security issues are within scope for responsible disclosure: + +- **Code execution** from crafted PDF documents (e.g., parser bugs enabling arbitrary code execution) +- **Path traversal** vulnerabilities (e.g., extracting embedded files that escape intended directories) +- **Server-Side Request Forgery (SSRF)** in the HTTP service mode +- **Authentication bypass** in the MCP integration or other authenticated interfaces +- **Signature verification bypass** in release artifact verification +- **Supply-chain attacks** affecting the build pipeline or dependency integrity + +### Out of Scope + +The following are explicitly out of scope (covered by existing mitigations or accepted risk): + +- **Denial-of-Service via valid PDFs** — Large or complex PDFs that exhaust CPU/memory are resource management issues, not vulnerabilities. Use resource limits. +- **Missing security headers** on demo/deployment sites — These are deployment concerns, not code vulnerabilities. +- **Vulnerabilities in dependencies** that have already been disclosed and patched upstream — Upgrade to the fixed dependency version. +- **Information leakage via debug output** in development/debug builds — Only release builds are security-supported. + +## Safe Harbor + +We commit to working with security researchers who act in good faith. This policy is adapted from the [Disclose.io Safe Harbor](https://disclose.io/safe-harbor) template: + +> If you act in good faith and accordance with this policy: +> +> - We will **not** pursue legal action against you +> - We will **not** notify law enforcement +> - We will **not** target your research for DMCA or CFAA claims +> +> We consider "good faith" to mean: +> - You give us reasonable time to address the vulnerability before public disclosure +> - You do not exploit the vulnerability beyond what is necessary to demonstrate it +> - You do not destroy data or degrade service for other users +> - You report the vulnerability through one of the private channels listed above +> +> If at any point you have concerns about whether your research qualifies as good faith, please contact us at [security@jedarden.com](mailto:security@jedarden.com) before proceeding. diff --git a/docs/security/pgp-public-key.asc b/docs/security/pgp-public-key.asc new file mode 100644 index 0000000..601197d --- /dev/null +++ b/docs/security/pgp-public-key.asc @@ -0,0 +1,34 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +PLACEHOLDER PGP KEY FOR security@jedarden.com + +This file should contain the actual PGP public key for the pdftract security +contact email (security@jedarden.com). The key must be: + +1. A 4096-bit RSA key or equivalent +2. Associated with the email security@jedarden.com +3. Published with the fingerprint in README.md and SECURITY.md +4. Rotated every 2 years + +To generate this key: + + gpg --batch --gen-key < docs/security/pgp-public-key.asc + + gpg --fingerprint security@jedarden.com # Add this to README.md and SECURITY.md + +After generating the key, replace this entire file with the output of: + gpg --armor --export security@jedarden.com + +-----END PGP PUBLIC KEY BLOCK-----