SECURITY.md
Rama dev · réplica de lectura del repositorio original.
# Security policy
Reaper holds credentials for your media server and it deletes files. A vulnerability here
costs someone their library, so security reports are welcome and are treated as the most
important thing in the tracker.
## Reporting a vulnerability
Use GitHub's [private vulnerability reporting form](https://github.com/scythe-labs/reaper/security/advisories/new).
It opens a discussion visible only to you and the maintainer, and it lets a fix be prepared
before anything is public.
Please avoid opening a public issue for a security problem until there is a release that
fixes it.
A useful report says what an attacker can reach, what they need in order to reach it, and
what happens once they do. Proof-of-concept code is welcome and never required.
### What to expect
Reaper is a hobby project maintained by one person, so response times are best effort.
In practice that means an acknowledgement within a few days and
an honest estimate once the problem is understood. If a report sits without a reply for a
week, a nudge on the same advisory thread is entirely reasonable.
Credit is given in the release notes unless you would rather it was not.
## Supported versions
The latest release is supported, and so is the current `dev` image. Fixes land on `dev`
first and ship in the next release.
## Where the sensitive parts are
If you are looking for somewhere to start, these carry the weight:
- **Credentials at rest.** API keys for Plex, Tautulli, Sonarr, and Radarr are encrypted
with a Fernet key that lives outside the database, and they are redacted from logs
(`src/reaper/secrets.py`, `src/reaper/logbuffer.py`).
- **Authentication and sessions.** Cookie sessions, the login flow, and the recovery paths
that exist so a locked-out operator can get back in (`src/reaper/auth/`).
- **API keys.** A request carrying `X-Api-Key` is judged on the key alone. What it can read
and write is an allowlist declared in one place (`src/reaper/api/middleware.py`).
Everything else that changes state needs the signed-in browser.
- **Reverse-proxy trust.** `X-Forwarded-For` and `X-Forwarded-Proto` are honored only when
the direct peer is a proxy the operator listed. They decide the rate-limit key and the
session cookie's `Secure` flag (`src/reaper/auth/proxy.py`).
- **The deletion path.** Deletion is armed from the interface behind a password, and the
one route that deletes requires both the armed host and an exact confirmation phrase that
is recomputed on the server from the plan's contents.
- **The transport guard.** `GuardedTransport` refuses any mutating request unless deletion
is armed on the host and the intent was written to the journal first. Arming is a
property of the machine itself, which a browser has no way to reach
(`src/reaper/clients/`).
- **Backup and restore.** A backup carries key material, and restore writes to the settings
that control everything above (`src/reaper/services/backup.py`,
`src/reaper/services/restore.py`).
## Especially interested in
Anything that lets a request cause a deletion without passing both independent layers: the
executor's interlocks and the transport guard. Those two are meant to be independent, so a
single flaw that defeats both is the highest-severity result this project has.
## Out of scope
- Reports that amount to "an operator with the admin password can delete media." That is
the purpose of the program.
- Findings from an automated scanner with no described impact.
- Vulnerabilities in Plex, Sonarr, Radarr, or Tautulli themselves. Please report those
upstream. If Reaper's handling of one makes it worse, that part is in scope here.