From f2f334331174e1b54bbc5dd1b5c007af2ea9bf76 Mon Sep 17 00:00:00 2001 From: Charis Daniels Date: Tue, 29 Sep 2026 17:06:28 +0000 Subject: [PATCH] fix: add detect-secrets baseline and triage cargo-audit advisories (#1211, #1203) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit a committed .secrets.baseline so the pre-commit detect-secrets hook passes deterministically: findings from a full tracked-file scan were audited (6 false positives: dev-only compose credentials, a usage placeholder and public Substrate test addresses) and documented in .secrets-audit-justifications.md together with the baseline workflow. Ignore the pinned-transitive h2 (RUSTSEC-2026-0258) and rustls-webpki (RUSTSEC-2026-0098) advisories in audit.toml with per-entry justification, per the approach accepted in the issue, and record the triage in AUDIT_LOG.md. Closes #1211 Closes #1203 🤖 Generated with Codebuff Co-Authored-By: Codebuff --- .secrets-audit-justifications.md | 27 +++++ .secrets.baseline | 167 +++++++++++++++++++++++++++++++ AUDIT_LOG.md | 24 +++++ audit.toml | 15 ++- 4 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 .secrets-audit-justifications.md create mode 100644 .secrets.baseline diff --git a/.secrets-audit-justifications.md b/.secrets-audit-justifications.md new file mode 100644 index 000000000..73315065d --- /dev/null +++ b/.secrets-audit-justifications.md @@ -0,0 +1,27 @@ +# `.secrets.baseline` Audit Justifications + +The `detect-secrets` pre-commit hook runs with `--baseline .secrets.baseline` +(see `.pre-commit-config.yaml`). The baseline is generated from a scan of all +tracked files and every finding below has been manually reviewed and marked +`"is_secret": false` with the justification recorded here. + +## Baselined findings + +| File | Line | Type | Justification | +| --- | --- | --- | --- | +| `docker-compose.yml` | 42 | Secret Keyword | Local-only dev Postgres password (`propchain123`) for the `propchain-postgres` container. Port is bound to localhost; never used in staging/production. | +| `docker-compose.yml` | 68 | Basic Auth Credentials | `DATABASE_URL` embedding the same local-only dev credential (`propchain:propchain123@postgres`) for the indexer container. | +| `scripts/archive-events.sh` | 9 | Basic Auth Credentials | Usage docstring template `postgres://user:pass@host:5432/db`. Literal placeholder, not a credential. | +| `scripts/test_accounts.rs` | 8-10 | Base64 High Entropy String | Well-known public Substrate/ink test account addresses (Alice/Bob/Charlie `5Grw...`, `5FHne...`, `5FLSi...`). Public keys, not private keys or seeds. | + +## Baseline workflow + +- **Regenerate** after adding files or plugins: + `detect-secrets scan $(git ls-files) > .secrets.baseline` +- **Audit new findings** and mark them `is_secret: true/false` with: + `detect-secrets audit .secrets.baseline` (interactive) or + `detect-secrets audit --report .secrets.baseline` (summary). +- **Record justification** for every `is_secret: false` finding in the table + above. +- The hook passes when `pre-commit run detect-secrets` reports no findings that + are both outside the baseline and not marked audited. diff --git a/.secrets.baseline b/.secrets.baseline new file mode 100644 index 000000000..0d53a7e95 --- /dev/null +++ b/.secrets.baseline @@ -0,0 +1,167 @@ +{ + "version": "1.4.0", + "plugins_used": [ + { + "name": "ArtifactoryDetector" + }, + { + "name": "AWSKeyDetector" + }, + { + "name": "AzureStorageKeyDetector" + }, + { + "name": "Base64HighEntropyString", + "limit": 4.5 + }, + { + "name": "BasicAuthDetector" + }, + { + "name": "CloudantDetector" + }, + { + "name": "DiscordBotTokenDetector" + }, + { + "name": "GitHubTokenDetector" + }, + { + "name": "HexHighEntropyString", + "limit": 3.0 + }, + { + "name": "IbmCloudIamDetector" + }, + { + "name": "IbmCosHmacDetector" + }, + { + "name": "JwtTokenDetector" + }, + { + "name": "KeywordDetector", + "keyword_exclude": "" + }, + { + "name": "MailchimpDetector" + }, + { + "name": "NpmDetector" + }, + { + "name": "PrivateKeyDetector" + }, + { + "name": "SendGridDetector" + }, + { + "name": "SlackDetector" + }, + { + "name": "SoftlayerDetector" + }, + { + "name": "SquareOAuthDetector" + }, + { + "name": "StripeDetector" + }, + { + "name": "TwilioKeyDetector" + } + ], + "filters_used": [ + { + "path": "detect_secrets.filters.allowlist.is_line_allowlisted" + }, + { + "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies", + "min_level": 2 + }, + { + "path": "detect_secrets.filters.heuristic.is_indirect_reference" + }, + { + "path": "detect_secrets.filters.heuristic.is_likely_id_string" + }, + { + "path": "detect_secrets.filters.heuristic.is_lock_file" + }, + { + "path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string" + }, + { + "path": "detect_secrets.filters.heuristic.is_potential_uuid" + }, + { + "path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign" + }, + { + "path": "detect_secrets.filters.heuristic.is_sequential_string" + }, + { + "path": "detect_secrets.filters.heuristic.is_swagger_file" + }, + { + "path": "detect_secrets.filters.heuristic.is_templated_secret" + } + ], + "results": { + "docker-compose.yml": [ + { + "type": "Secret Keyword", + "filename": "docker-compose.yml", + "hashed_secret": "3fd126d0044349a396d456cd0236e83af899e7e3", + "is_verified": false, + "is_secret": false, + "line_number": 42 + }, + { + "type": "Basic Auth Credentials", + "filename": "docker-compose.yml", + "hashed_secret": "3fd126d0044349a396d456cd0236e83af899e7e3", + "is_verified": false, + "is_secret": false, + "line_number": 68 + } + ], + "scripts/archive-events.sh": [ + { + "type": "Basic Auth Credentials", + "filename": "scripts/archive-events.sh", + "hashed_secret": "9d4e1e23bd5b727046a9e3b4b7db57bd8d6ee684", + "is_verified": false, + "is_secret": false, + "line_number": 9 + } + ], + "scripts/test_accounts.rs": [ + { + "type": "Base64 High Entropy String", + "filename": "scripts/test_accounts.rs", + "hashed_secret": "b12e86602d4a3f5138f96fd8a03d267f5ba8f3b5", + "is_verified": false, + "is_secret": false, + "line_number": 8 + }, + { + "type": "Base64 High Entropy String", + "filename": "scripts/test_accounts.rs", + "hashed_secret": "e59ebce0dbf9dc0984432207d619d2d24ee4e362", + "is_verified": false, + "is_secret": false, + "line_number": 9 + }, + { + "type": "Base64 High Entropy String", + "filename": "scripts/test_accounts.rs", + "hashed_secret": "331d7cbc9e945dcba2ff31c668cba758bed56e44", + "is_verified": false, + "is_secret": false, + "line_number": 10 + } + ] + }, + "generated_at": "2026-09-29T17:02:57Z" +} diff --git a/AUDIT_LOG.md b/AUDIT_LOG.md index e9d9838d9..21e0877c4 100644 --- a/AUDIT_LOG.md +++ b/AUDIT_LOG.md @@ -491,3 +491,27 @@ workspace: /home/runner/work/PropChain-contract/PropChain-contract/Cargo.toml | ^ error: could not compile `propchain-bridge` (lib test) due to 1 previous error + +--- + +## ✅ Advisory Triage — h2 / rustls-webpki (issue #1203, 2026-09-29) + +`cargo-audit` flags 8 advisories against transitive dependencies pinned by the +substrate/ink toolchain. They are now explicitly ignored with justification in +`audit.toml` so that remaining *new* advisories fail the audit gate: + +| Advisory | Crate (pinned version) | Action & justification | +| --- | --- | --- | +| RUSTSEC-2026-0258 | h2 0.3.27 | Ignored. Upgrade path (h2 >= 0.4.16) requires a hyper/tokio stack bump out of scope for ink! 5.1. No workspace code path exposes the vulnerable HTTP/2 empty-DATA-frame handling; contracts never terminate HTTP/2. | +| RUSTSEC-2026-0098 | rustls-webpki 0.101.7 / 0.102.8 | Ignored. Fix line (0.103.x) requires a rustls major bump. Workspace has no rustls client parsing untrusted certificates. | +| RUSTSEC-2026-0104 | rustls-webpki 0.101.7 / 0.102.8 | Already ignored (pre-existing entry, unchanged). | +| RUSTSEC-2026-0002 | lru 0.12.5 | Already ignored (pre-existing entry, unchanged). | + +Each ignore entry in `audit.toml` carries a comment with the justification and +a re-evaluation note for the next toolchain upgrade. `cargo-deny check` must be +re-run in CI to confirm zero unignored advisories (deny.toml license-key +cleanup is tracked separately and out of scope here). + +Secrets scanning (issue #1211): `.secrets.baseline` committed; audited +findings and the baseline workflow are documented in +`.secrets-audit-justifications.md`. diff --git a/audit.toml b/audit.toml index c20a0e803..6388eeccb 100644 --- a/audit.toml +++ b/audit.toml @@ -1,2 +1,15 @@ [advisories] -ignore = ["RUSTSEC-2026-0104", "RUSTSEC-2026-0002"] +# h2 0.3.27 (RUSTSEC-2026-0258, unbounded empty DATA frames). +# Pinned transitively by the substrate/ink toolchain; h2 >= 0.4 needs a +# hyper/tokio stack bump that is out of scope for the ink! 5.1 workspace. +# No workspace code path exposes the vulnerable HTTP/2 DATA-frame handling. +# Re-evaluate on the next toolchain upgrade. Tracked in issue #1203. +"RUSTSEC-2026-0258", +# rustls-webpki 0.101.7/0.102.8 (RUSTSEC-2026-0098, URI name constraints +# incorrectly accepted). Pinned transitively by the substrate/ink toolchain; +# 0.103.x requires a rustls major bump. No rustls client in this workspace +# parses untrusted certificates. Re-evaluate on the next toolchain upgrade. +# Tracked in issue #1203. +"RUSTSEC-2026-0098", +"RUSTSEC-2026-0104", +"RUSTSEC-2026-0002"]