From 94a3404636d042f0c03e2d11602b984117600046 Mon Sep 17 00:00:00 2001 From: kamal Date: Thu, 2 Apr 2026 20:50:57 +0000 Subject: [PATCH] Add Security Policy --- Security-Policy.md | 121 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 Security-Policy.md diff --git a/Security-Policy.md b/Security-Policy.md new file mode 100644 index 0000000..74757fd --- /dev/null +++ b/Security-Policy.md @@ -0,0 +1,121 @@ +# Security Policy + +## Reporting a Vulnerability + +**Critical or high severity** (key leakage, authentication bypass, ratchet desync +that leaks plaintext, FFI memory corruption): + +> **security@lo.sh** + +Use this for anything an attacker could exploit. If you have our public key, +encrypt the report. We will acknowledge within 72 hours and aim to ship a fix +within 14 days of confirmation. + +**Medium or low severity** (interoperability bugs, non-exploitable logic errors, +documentation issues): + +> Open an issue at **https://git.lo.sh/lo/libsoliton** + +When in doubt, use the email. We would rather triage a false alarm than miss a +real vulnerability. + +## Supported Versions + +| Version | Supported | +|---------|-----------| +| 0.1.x | Yes | + +Only the latest release is supported. Security fixes are not backported. + +## Threat Model + +### In scope + +- **Protocol logic** in LO-KEX, LO-Ratchet, KEM authentication, and storage + encryption. Bugs here (wrong KDF inputs, missing domain separation, ratchet + state corruption) are the primary risk. +- **Memory safety** in the Rust code and the `unsafe` FFI boundary + (`libsoliton_capi`). Unsound pointer handling, use-after-free in opaque state + objects, buffer overflows in slice construction. +- **Wrapper binding correctness** (`soliton_py`, `soliton_wasm`, `soliton_zig`). + Incorrect type marshaling, use-after-free of opaque handles, missing zeroization + at the binding layer, header serialization mismatches. The Python and WASM + bindings wrap the core Rust API via PyO3 and wasm-bindgen respectively (no + `unsafe` in the bindings themselves). The Zig wrapper consumes the C ABI + directly. +- **Key management** — failure to zeroize secrets, key material leaking into + logs or error messages, nonce reuse. +- **Cryptographic misuse** — wrong algorithm parameters, truncated hashes, + clamping errors, incorrect domain separators. + +### Out of scope + +- **Side-channel attacks in upstream Rust crates.** Timing, power, or EM side + channels in ML-KEM-768 (`ml-kem`), ML-DSA-65 (`ml-dsa`), X25519 + (`x25519-dalek`), or Ed25519 (`ed25519-dalek`) are upstream concerns. + Report those to the relevant [RustCrypto](https://github.com/RustCrypto) + or [dalek-cryptography](https://github.com/dalek-cryptography) project. + XChaCha20-Poly1305 and Ed25519 are constant-time by construction (ARX + operations only, no table lookups). +- **WASM linear memory.** Secret key material in WASM cannot be reliably + zeroized — the linear memory is GC-managed by the JS engine and may be + copied, paged, or retained after `free()`. This is inherent to the WASM + execution model, not a library bug. +- **Python GC.** `bytes` objects returned by the Python binding are + GC-managed. The Rust side zeroizes its copy, but the Python object persists + until collected. Context managers (`with`) minimize the window. +- **Compression oracle (CRIME/BREACH-style).** When streaming AEAD compression + is enabled and an attacker controls partial plaintext, ciphertext length may + leak information about co-resident secret content. File transfer (the primary + use case) does not have attacker-controlled plaintext injection, so this is + not exploitable in the intended deployment. Applications mixing + attacker-controlled and secret data in a single compressed stream should + disable compression. +- **Hardware faults** — rowhammer, fault injection, glitching. +- **Denial of service** — resource exhaustion from large inputs is a bug, but + not a security vulnerability in a library context. + +### Known limitations + +- **PQ crates are pre-1.0.** ML-KEM and ML-DSA are NIST FIPS 203/204 final, + but the RustCrypto implementations (`ml-kem`, `ml-dsa`) have not undergone + the same decades of scrutiny as, say, OpenSSL's AES. This is inherent to + post-quantum cryptography in 2026. +- **X-Wing is a draft.** We implement draft-connolly-cfrg-xwing-kem-09. The + combiner and encoding may change before the RFC is finalized. +- **Ed25519 (RFC 8032)** is used for classical signing via `ed25519-dalek`. + Strict verification mode rejects non-canonical signatures and small-order + public keys, preventing malleability attacks. +- **XChaCha20-Poly1305** is constant-time by construction (ARX operations + only — no table lookups or secret-dependent branches). No hardware + acceleration is required; it runs at full speed on all platforms including + RISC-V. + +## Dependencies + +All dependencies are pure Rust — no C libraries, no cmake, no system linker +dependencies. + +| Dependency | Role | +|------------|------| +| [ml-kem](https://crates.io/crates/ml-kem) | ML-KEM-768 (inside X-Wing) | +| [ml-dsa](https://crates.io/crates/ml-dsa) | ML-DSA-65 hybrid signatures | +| [ed25519-dalek](https://crates.io/crates/ed25519-dalek) | Ed25519 signing/verification | +| [x25519-dalek](https://crates.io/crates/x25519-dalek) | X25519 (inside X-Wing) | +| [chacha20poly1305](https://crates.io/crates/chacha20poly1305) | XChaCha20-Poly1305 AEAD | +| [sha3](https://crates.io/crates/sha3) | SHA3-256 (HMAC, HKDF, fingerprints, X-Wing combiner) | +| [hmac](https://crates.io/crates/hmac) | HMAC-SHA3-256 | +| [hkdf](https://crates.io/crates/hkdf) | HKDF-SHA3-256 key derivation | +| [argon2](https://crates.io/crates/argon2) | Argon2id password hashing | +| [ruzstd](https://crates.io/crates/ruzstd) | Zstd decompression (storage blobs, streaming AEAD chunks) | +| [zeroize](https://crates.io/crates/zeroize) | Secret wiping | + +**Binding-specific dependencies** (not part of the core library): + +| Dependency | Role | +|------------|------| +| [pyo3](https://crates.io/crates/pyo3) | Python FFI bridge (`soliton_py`) | +| [wasm-bindgen](https://crates.io/crates/wasm-bindgen) | WASM/JS interop (`soliton_wasm`) | + +Vulnerabilities in these dependencies may affect libsoliton. We track upstream +advisories and update pins accordingly.