# Security Policy ## Reporting Vulnerabilities If you discover a security vulnerability in ChordSketch, please report it responsibly by [opening a GitHub security advisory][advisory]. Do **not** file a public issue for security-sensitive reports. [advisory]: https://github.com/koedame/chordsketch/security/advisories/new We aim to acknowledge reports within 72 hours and provide a fix or mitigation plan within 30 days. ## Threat Model ChordSketch processes **untrusted** `.cho` (ChordPro) files and renders them to text, HTML, and PDF. The primary threat is a malicious or crafted input file attempting to: - Execute arbitrary code on the host. - Read or write files outside the intended scope. - Produce excessively large output to exhaust memory or disk. - Inject scripts or markup into rendered HTML/SVG output. ### Trust Boundaries | Source | Trust Level | Notes | |--------|-------------|-------| | CLI flags and environment variables | **Trusted** | Controlled by the invoking user | | System and user config files | **Trusted** | Located under `/etc/` or `~/.config/` | | Project-level config files | **Untrusted** | May come from a cloned repository | | Song `.cho` files | **Untrusted** | Primary attack surface | | Delegate tool output (abc2svg, Lilypond) | **Untrusted** | External process output is sanitized | ## Security Controls ### Configuration File Loading - **Hierarchy**: defaults → system → user → project → song-level overrides. - **Symlink rejection**: Config files are opened with `O_NOFOLLOW` on Unix to prevent symlink-based redirection. - **File size limit**: Config files are capped at 10 MB (`MAX_CONFIG_FILE_SIZE`). - **Delegate execution restriction**: Only system-level, user-level config, or explicit CLI flags can enable delegate execution. Project-level and song-level configs cannot enable delegates — any attempt is silently overridden with a warning. ### RRJSON Parser - **Nesting depth limit**: 64 levels (`MAX_NESTING_DEPTH`). - **Entry count limit**: 10,000 entries per object or array (`MAX_ENTRIES`). - **Non-finite number rejection**: `Infinity`, `-Infinity`, and `NaN` are rejected. ### Delegate Execution (abc2svg, Lilypond) Delegate environments invoke external tools to convert music notation to SVG. Multiple defense layers are applied: 1. **Content-level sanitization** — dangerous constructs are stripped from input before the external tool is invoked: - ABC: `%%beginjs`/`%%endjs` blocks and `%%javascript` directives are removed (case-insensitive). - Lilypond: lines containing dangerous Scheme functions (`system`, `getenv`, `open-input-file`, `open-output-file`, `open-file`, `primitive-load`, `primitive-load-path`, `eval-string`, `load`, `ly:gulp-file`, `ly:system`, `ly:parser-include`, `ly:set-option`) are stripped. 2. **Process sandboxing** — Lilypond is invoked with the `-dsafe` flag to sandbox its embedded Scheme interpreter. 3. **Safe command construction** — all arguments are passed via the `Command::arg()` API, preventing shell metacharacter injection. 4. **Output sanitization** — SVG output from delegates is run through the SVG sanitizer before inclusion in rendered output. 5. **Temp file safety** — temporary files use PID + atomic counter for unique names, are created with `O_EXCL` (exclusive create) semantics, and directories use `create_dir` (not `create_dir_all`) to prevent symlink attacks on parent paths. ### SVG Sanitization All SVG content (from delegates or `{start_of_svg}` sections) is sanitized: - **Dangerous elements stripped**: `