diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 258451e..8ae7fdd 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -1,23 +1,46 @@ -# Reporting Vulnerabilities +# Security policy -**⚠️ Please do not file public GitHub issues for security vulnerabilities as they are open for everyone to see! ⚠️** +pytest-print is a pytest plugin that lets tests print progress and debug lines into pytest's report. This policy says +how to report a security problem and how we decide whether a report is one. -We encourage responsible disclosure practices for security vulnerabilities. +## Reporting a vulnerability -## Reporting a Vulnerability +**Do not open a public issue for a security problem.** Use +[GitHub's private vulnerability reporting](https://github.com/pytest-dev/pytest-print/security/advisories/new). If you +do not have a GitHub account, or you are a Tidelift subscriber, report through the +[Tidelift security contact](https://tidelift.com/security) instead; Tidelift coordinates the fix and the disclosure with +us. If neither works for you, email [gaborjbernat@gmail.com](mailto:gaborjbernat@gmail.com). -If you believe you've found a security-related bug, fill out a new vulnerability report via GitHub directly. To do so, -follow these instructions: +Include what the attacker controls and what they gain, the steps or a proof of concept, and the versions and platform +you tested. Write the report yourself; unreviewed tool or model output takes longer to triage. -1. Click on the `Security` tab in the project repository. -1. Click the green `Report a vulnerability` button at the top right corner. -1. Fill in the form as accurately as you can, including as many details as possible. -1. Click the green `Submit report` button at the bottom. +## What to expect -## Don't have a GitHub account? +Volunteers maintain pytest-print, with no on-call rotation. We aim to acknowledge a report within **5 working days** and +assess it within **15 working days**. Fixes are developed in a private fork attached to the draft advisory, ship in a +new release, and the advisory, with a CVE requested through GitHub, goes out with that release. The default embargo is +**90 days** from the report; we agree any change with the reporter. We credit reporters in the advisory under the name +they choose, or not at all. There is no bug bounty. -Alternatively, to report a security vulnerability, please use the -[Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. +## Supported versions -It is currently set up to forward every incoming report to Bernát Gábor. We will try to assess the problem in timely -manner and disclose it in a responsible way. +Only the latest release receives fixes. Confirm the problem reproduces on it before reporting. + +## Vulnerability or bug + +A report is a vulnerability when an attacker who controls only an input that the [threat model](THREAT_MODEL.md) lists +as untrusted breaks a guarantee pytest-print makes. A report that first needs control of something the threat model +trusts, such as the tests that call it or the pytest configuration, is a bug: we fix it in the open and publish no +advisory. Classify by who supplies the dangerous input, not by how bad the outcome sounds. + +**In scope** + +- pytest-print writing anywhere other than pytest's terminal reporter. +- pytest-print printing when its option or fixture was not used, in a way that exposes test data. + +**Out of scope** + +- Anything a test prints through the fixtures: tests are trusted code and choose what they print. +- Terminal escape sequences in printed text; tests control the text. + +If you cannot tell which side a finding falls on, report it privately and we will decide. diff --git a/.github/THREAT_MODEL.md b/.github/THREAT_MODEL.md new file mode 100644 index 0000000..9e27fa7 --- /dev/null +++ b/.github/THREAT_MODEL.md @@ -0,0 +1,85 @@ +# Threat model + +This model says what pytest-print trusts, where untrusted input enters, and which guarantees hold at each boundary, so a +report can be classified as a vulnerability or a bug. [SECURITY.md](SECURITY.md) covers reporting; if the two disagree, +SECURITY.md wins and we fix this file. + +## How pytest-print works + +pytest-print provides fixtures (`printer`, `printer_session`, `pretty_printer`, `create_pretty_printer`) that write +lines through pytest's terminal reporter while tests run, when `--print` or `-v` is given. It reads nothing from disk or +the network and runs no code of its own beyond formatting the text it is given. + +```mermaid +flowchart LR + test["Test code
(trusted)"] -->|"printer(msg)"| pp["pytest-print"] + cfg[("pytest options
(trusted)")] --> pp + pp -->|"terminal reporter"| out["Test report"] + classDef trusted fill:#cfe4ff,stroke:#1f6feb,color:#0b1f3a; + classDef boundary fill:#ffe3a3,stroke:#d29200,color:#3a2c00; + class test,cfg,pp trusted; + class out boundary; +``` + +## Compared with similar tools + +We drew the boundary where comparable projects in other ecosystems draw theirs. The shared rule, stated by the +[Node.js threat model](https://github.com/nodejs/node/blob/main/SECURITY.md#the-nodejs-threat-model), is that a report +which first needs a trusted element compromised is out of scope; the first triage question, as +[DOMPurify](https://github.com/cure53/DOMPurify/blob/main/SECURITY.md#what-we-consider-a-vulnerability) puts it, is what +the attacker controls. + +| Project | Language | Where it draws the line | +| -------------------------------------------------------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| [Vitest](https://github.com/vitest-dev/vitest/security/policy) | JavaScript | Trusts the developer, the config file, plugins and every project file; only reports that need no trusted element compromised count. | +| [Jest](https://github.com/jestjs/jest/security/policy) | JavaScript | Test runner; private reports with an escalation path, and no separate threat model. | +| [Mocha](https://github.com/mochajs/mocha/security/policy) | JavaScript | Test runner; reports through Tidelift, with no further scope. | + +## Trusted + +An attacker who controls any of these already has what pytest-print could give them: + +- The tests and the text they pass to the fixtures. +- pytest, its configuration and its terminal reporter. + +## Untrusted inputs + +| Input | Comes from | What pytest-print guarantees | +| --------------- | ---------------------------------------------------- | --------------------------------------------------------- | +| None of its own | pytest-print takes input only from trusted test code | Prints only when enabled, only through pytest's reporter. | + +## Threats and controls + +| STRIDE | Threat | Control | +| ---------------------- | --------------------------------------------------------------------- | ------------------------------------------ | +| Information disclosure | Debug lines with sensitive data appear when printing was not enabled. | Output is gated on `--print` or verbosity. | + +## Release chain + +Releases run on the shared [tox-dev/github-workflows](https://github.com/tox-dev/github-workflows) pipeline. A release +App, not a person, pushes the release commit and tag; the build installs its tools from a hash-checked `pylock.toml` +resolved with a seven-day upload cooldown by default; PyPI receives the files through +[trusted publishing](https://docs.pypi.org/trusted-publishers/) with attestations, and the GitHub Release is immutable. +Every workflow pins third-party actions to a commit SHA. + +## Vulnerability or bug + +| Report | Verdict | Why | +| ---------------------------------------- | ------------------- | --------------------------------------- | +| A test prints a token with `printer` | Not a vulnerability | The test chose to print it. | +| pytest-print writes lines to a file | Vulnerability | It must only use the terminal reporter. | +| Indentation is wrong in `pretty_printer` | Bug | Formatting only. | + +## Severity + +- **Medium:** pytest-print writes anywhere other than pytest's terminal reporter. +- **Low:** pytest-print prints while neither `--print` nor `-v` is given. + +## Accepted risks + +- None beyond what the tests print. + +## Keeping this current + +Revisit this model when pytest-print gains a new input source, network access, a new way to run code, or a new place it +writes to, and whenever an advisory is published. diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index ae419c1..0000000 --- a/SECURITY.md +++ /dev/null @@ -1,9 +0,0 @@ -# Security Policy - -## Supported Versions - -Only the latest released version is supported with security updates. Older versions will not receive patches. - -## Reporting a Vulnerability - -Please report security vulnerabilities via [GitHub's private vulnerability reporting](../../security/advisories/new).