Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 45 additions & 9 deletions .github/SECURITY.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,49 @@
# Security Policy
# Security policy

## Supported Versions
PyVenvManage is a JetBrains IDE plugin that marks virtual environment folders in the project view and sets one as the
project or module interpreter on request. This policy says how to report a security problem and how we decide whether a
report is one.

| Version | Supported |
| ------- | ------------------ |
| 2.x | :white_check_mark: |
| \<2 | :x: |
## 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/tox-dev/PyVenvManage/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).

To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift
will coordinate the fix and disclosure.
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.

## What to expect

Volunteers maintain PyVenvManage, 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.

## Supported versions

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 PyVenvManage makes. A report that first needs control of something the threat model
trusts, such as the IDE, the open project, or the user's choice of interpreter, 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**

- The plugin setting or changing an interpreter without the user choosing the action.
- The plugin running a program while it decorates the project view; decoration only reads files.
- Crafted `pyvenv.cfg` or marker content making the plugin read or write outside the environment folder.

**Out of scope**

- What the IDE does with an interpreter after the user selects it: indexing and running it is the IDE's behavior.
- A malicious interpreter inside a project's virtual environment the user chose to use.
- Vulnerabilities in the IntelliJ Platform or the Python plugin.

If you cannot tell which side a finding falls on, report it privately and we will decide.
88 changes: 88 additions & 0 deletions .github/THREAT_MODEL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Threat model

This model says what PyVenvManage 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 PyVenvManage works

PyVenvManage scans the project view for folders that hold a `pyvenv.cfg` and a Python executable, and decorates them
with the Python version read from `pyvenv.cfg` and an environment type guessed from markers in the folder (a
`conda-meta` directory, a Hatch `.gitignore`, the user's Poetry and Pipenv locations). When the user right-clicks such a
folder and chooses an action, it registers that folder's interpreter as an SDK and sets it for the project or module. It
starts no process and opens no network connection of its own.

```mermaid
flowchart LR
user["User action<br/>(trusted)"] --> pvm["PyVenvManage"]
proj[("Project folders,<br/>pyvenv.cfg (untrusted)")] -->|"read version, type"| pvm
pvm -->|"register SDK, set interpreter"| ide["IDE, Python plugin"]
classDef trusted fill:#cfe4ff,stroke:#1f6feb,color:#0b1f3a;
classDef boundary fill:#ffe3a3,stroke:#d29200,color:#3a2c00;
class user,pvm,ide trusted;
class proj 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 |
| ------------------------------------------------------------------------------------------------ | --------------- | ---------------------------------------------------------------------------------------------------- |
| [JetBrains project trust](https://www.jetbrains.com/help/idea/project-security.html) | Kotlin and Java | A project opened in Safe Mode restricts executing code, builds and scripts until the user trusts it. |
| [VS Code Workspace Trust](https://code.visualstudio.com/docs/editing/workspaces/workspace-trust) | TypeScript | Extensions disable features that run workspace code until the user trusts the folder. |
| [IntelliJ Platform](https://github.com/JetBrains/intellij-community/security/policy) | Kotlin and Java | JetBrains' reporting policy for the platform the plugin runs on. |

## Trusted

An attacker who controls any of these already has what PyVenvManage could give them:

- The user and the actions they choose.
- The IDE, the Python plugin and the SDK table.

## Untrusted inputs

| Input | Comes from | What PyVenvManage guarantees |
| -------------------------------------------- | ---------------- | ------------------------------------------------- |
| `pyvenv.cfg`, marker files and folder layout | A cloned project | Read as text to label the folder; never executed. |

## Threats and controls

| STRIDE | Threat | Control |
| ---------------------- | --------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| Tampering | A crafted `pyvenv.cfg` points the plugin outside the project. | The interpreter path comes from the folder the user clicked, not from `pyvenv.cfg`. |
| Elevation of privilege | Opening a project silently switches to a malicious interpreter. | Interpreters change only on an explicit action. |

## Release chain

Releases run on the shared [tox-dev/github-workflows](https://github.com/tox-dev/github-workflows) pipeline. A release
App pushes the release commit and tag, the plugin ZIP is signed before it reaches the
[JetBrains Marketplace](https://plugins.jetbrains.com/docs/marketplace/plugin-signing.html), and the immutable GitHub
Release carries the same ZIP with GitHub's release attestation. Every workflow pins third-party actions to a commit SHA.

## Vulnerability or bug

| Report | Verdict | Why |
| ----------------------------------------------------------------- | ------------------- | --------------------------------------- |
| Opening a project sets its `.venv` as interpreter without a click | Vulnerability | Interpreter changes need a user action. |
| The user picks a malicious `.venv` and the IDE runs it | Not a vulnerability | The user chose it. |
| A folder shows the wrong Python version | Bug | Label only. |

## Severity

- **High:** the plugin runs a program, or sets an interpreter, without the user choosing the action.
- **Medium:** crafted project content makes the plugin read or write outside the environment folder.
- **Low:** a crash or wrong label on a malformed environment folder.

## Accepted risks

- The plugin does not consult the IDE's trusted-project state; it reads `pyvenv.cfg` in untrusted projects too.

## Keeping this current

Revisit this model when PyVenvManage 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.
Loading