diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fa8827..781d252 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,40 @@ # Changelog +## [Unreleased] - 2026-07-15 + +### Security + +Multi-round security-hardening pass (audit → adversarial review → fix, +followed by standing red-team/blue-team sparring rounds) ahead of SOC 2 +Type II control-mapping work. See [SECURITY.md](SECURITY.md#security-hardening--soc-2-type-ii-readiness) +for the full readiness summary. Highlights: + +- **`verify()` on TSA timestamps was not actually verifying the TSA's + attestation** — it compared `sha256(data)` against a caller-supplied + `message_imprint` field instead of the hash the TSA itself signed. Now + DER/CMS-decodes the real response and checks the TSA-attested hash and + `SignerInfo` signature. +- **SSRF**: outbound TSA requests now require `https://` and resolved hosts + are checked against private/loopback/link-local/metadata-endpoint ranges. +- **Timing side-channels** in the pure-Python secp256k1 signer: modular + inverse moved to fixed-shape exponentiation; scalar multiplication moved + to a constant-iteration schedule. +- **Key hygiene**: `destroy()` now overwrites the private-key buffer in + place instead of just dropping the reference. +- **Execution/settlement integrity**: execution attestations are now + cross-validated against the commitment's authorised trade terms + (qty/price/symbol/side); broker settlement acknowledgements are now + cryptographically authenticated instead of accepted as a free-form string. +- **Identity binding**: new `AccountKeyRegistry` (`identity.py`) closes a + gap where any self-signed key could pass every check with no proof it + belonged to the account holder. +- **Concurrency**: audit-log JSONL/SQLite-index writes are now lock-guarded + against a race that could silently overwrite a duplicate order/phase + record. +- DoS bounds on unbounded JSON/HTTP-response reads; silent exception + swallowing removed from the audit-rebuild and TSA request paths. +- Every fix carries a dedicated regression test; suite grew to 137 tests. + ## [0.1.0] - 2026-06-03 ### Added diff --git a/README.md b/README.md index 2489684..9ac76eb 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,8 @@ Each phase lands in the audit log under `DECISION_COMMITMENT`, `EXECUTION_ATTEST See [SECURITY.md](SECURITY.md) for the full threat model, assumptions, and how to report a vulnerability. The full technical white paper — the CVE-2025-59536 problem, the design, and honest scope — is in [`docs/WHITEPAPER.md`](docs/WHITEPAPER.md). +**Security hardening.** Protocol-C went through a multi-round audit → adversarial-review → fix cycle plus standing red-team/blue-team sparring in July 2026 — TSA verification, SSRF, signer timing side-channels, key hygiene, execution/settlement integrity, identity binding, and audit-log concurrency. Not SOC 2 certified — see [SECURITY.md#security-hardening--soc-2-type-ii-readiness](SECURITY.md#security-hardening--soc-2-type-ii-readiness) for exactly what's covered and what isn't. + ## Honest about "quantum-safe" Read this part. "Quantum-safe" here is a **temporal** argument, **not** post-quantum cryptography: diff --git a/SECURITY.md b/SECURITY.md index c039748..9dfbf1a 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -69,6 +69,42 @@ This public package is **CSPRNG-only**: all entropy comes from `secrets.token_bytes`. The quantum-hardware entropy variant is a separate, private project and ships no code here. +## Security hardening & SOC 2 Type II readiness + +Protocol-C is not SOC 2 certified — no independent auditor has issued a +report. What's here is an honest account of the engineering work done so +far toward that posture, so anyone evaluating the library for a +compliance-relevant use case can see exactly what's been checked and +what's still open. + +**2026-07-15 hardening pass** (tracked in [PR #8](https://github.com/DBarr3/protocol-c/pull/8)): +a multi-round audit → adversarial review → fix cycle, followed by standing +red-team/blue-team sparring rounds against the hardened surface. Every +fix carries a dedicated regression test (suite: 137 tests). Summary — +full detail in [CHANGELOG.md](CHANGELOG.md#unreleased---2026-07-15): + +| Area | What was found and fixed | +|---|---| +| TSA verification | `verify()` wasn't checking the TSA's actual signed attestation — now parses and verifies the real CMS/TSTInfo structure. | +| Network (SSRF) | Outbound TSA requests now require HTTPS and reject private/loopback/link-local/metadata-endpoint hosts. | +| Timing side-channels | Modular inverse and scalar multiplication in the secp256k1 signer moved to fixed-shape/constant-iteration implementations. | +| Key hygiene | `destroy()` now zeroes the private-key buffer in place. | +| Business-logic integrity | Execution attestations are now cross-checked against the commitment's authorised trade terms; broker settlement acknowledgements are now cryptographically authenticated. | +| Identity binding | New `AccountKeyRegistry` closes a gap where any self-signed key could pass every check with no proof of account ownership. | +| Concurrency | Audit-log writes are now lock-guarded against a race that could silently overwrite a duplicate record. | +| Availability | DoS bounds added on unbounded JSON/HTTP-response reads. | +| Observability | Silent exception swallowing removed from the audit-rebuild and TSA request paths in favor of structured logging. | + +This addresses SOC 2 control areas most relevant to a signing/attestation +library — **change integrity** (tamper detection, non-repudiation), +**logical access** (identity binding on signers), and **availability** +(DoS bounds, graceful failure) — but a hardening pass is not a +certification. Still open before any real SOC 2 Type II claim: an +independent third-party audit, formal control documentation, and +continuous-monitoring evidence over the required observation period. If +you're evaluating Protocol-C for a compliance-relevant deployment, treat +this section as "here's what's been checked," not "this is certified." + ## Cryptographic implementation notes - **Signer:** original pure-Python secp256k1 ECDSA in `ephemeral_signer.py`,