Fix Wardnet security gates and fuzz coverage#40
Conversation
Add cargo-fuzz (libFuzzer) harnesses plus a stable proptest mirror for the gateway's attacker-controlled and untrusted-config surfaces, identified with CodeGraph as the reachable, untested entry points for arbitrary input: - fuzz_score_request -> waf_ids_core::score_request (request scorer: percent-decode + signature/threat/DNSBL/anomaly matching) - fuzz_appdata_json -> serde_json::from_str::<AppData> (persisted state file) - fuzz_parse_admin_tokens -> waf_ids_ai_soc::parse_admin_tokens (ADMIN_TOKENS config) - fuzz_dnsbl_zone -> export_dnsbl_zone / validate_dnsbl (zone-file escaping) Each target asserts no panic on arbitrary input plus surface-specific invariants (non-empty reason, deterministic scoring, serde round-trip, no empty token/actor, fully-escaped TXT payloads), and ships a seed corpus of real attack payloads and edge cases. The fuzz crate is an isolated workspace so `cargo test --workspace` at the root is unaffected. crates/waf-ids-core/tests/fuzz_invariants.rs and tests/fuzz_invariants.rs re-assert the same invariants via proptest on stable, so they stay green in primary CI without a nightly toolchain. CI: .github/workflows/fuzz.yml runs each target for a bounded budget (60s/target on PRs, 300s nightly) to keep cost predictable. All added deps are permissive (cargo-fuzz, libfuzzer-sys, arbitrary, proptest: MIT OR Apache-2.0). Docs in docs/fuzzing.md; fuzzing survey paper in docs/papers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RTAMs4bpSZS77Xe3RQjv9P
Fixes the fuzz_dnsbl_zone crash and restores the coverage-evidence gate to 100% line/function coverage for PR #37. Real bug (fuzz crash): export_dnsbl_zone rendered the untrusted `origin` and each entry `code` into the zone file verbatim. A newline plus double quotes in `origin` (or a non-IP `code`) broke out of the generated zone and produced TXT records with unescaped quotes, violating the fuzz invariant. - Sanitize the zone origin to DNS-safe characters (LDH, `_`, `.`); empty input falls back to the reserved `.invalid` TLD. - Require each DNSBL response `code` to parse as an IP literal, re-rendering the canonical form and skipping entries that do not. - Escape control characters (including raw newlines) in TXT payloads as BIND decimal escapes so a crafted reason/source cannot inject extra zone lines. - Add regression tests reproducing the crash shape and the escaping paths. Coverage-evidence (workspace 100% line/function gate): move the env-parsing helpers into the tested library, add `run_from_env` (bound + served via an ephemeral listener under an immediate shutdown in-process), reduce main.rs to a thin shim covered end-to-end by tests/binary.rs (graceful SIGTERM shutdown), and add unit tests for every configuration branch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RTAMs4bpSZS77Xe3RQjv9P
…case Adds the exact libFuzzer crash input (newline + quotes in `origin`) to the fuzz_dnsbl_zone corpus so CI replays it and proves the zone-injection fix holds. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RTAMs4bpSZS77Xe3RQjv9P
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
OpenCode Review Overview
Pull request overviewOpenCode reviewed the current-head bounded evidence and found no blocking issues. FindingsNo blocking findings. SummaryApproval sufficiency: bounded evidence supplied affirmative approval evidence for changed files, coverage/docstring posture, risk surfaces, and current-head verification; approval is not based merely on the absence of known blockers.
Changed-File Evidence Mapflowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Workflow (3 files)"]
S1 --> I1["GitHub Actions review job"]
I1 --> R1["Review risk: Workflow (3 files)"]
R1 --> V1["actionlint plus required checks"]
Evidence --> S2["Changed file (34 files)"]
S2 --> I2["repository behavior"]
I2 --> R2["Review risk: Changed file (34 files)"]
R2 --> V2["required checks"]
Evidence --> S3["Docs (2 files)"]
S3 --> I3["operator or user guidance"]
I3 --> R3["Review risk: Docs (2 files)"]
R3 --> V3["docs review"]
Evidence --> S4["Test (2 files)"]
S4 --> I4["regression suite"]
I4 --> R4["Review risk: Test (2 files)"]
R4 --> V4["targeted test run"]
|
There was a problem hiding this comment.
Pull request overview
OpenCode reviewed the current-head bounded evidence and found no blocking issues.
Findings
No blocking findings.
Summary
Approval sufficiency: bounded evidence supplied affirmative approval evidence for changed files, coverage/docstring posture, risk surfaces, and current-head verification; approval is not based merely on the absence of known blockers.
Verification posture: CodeGraph evidence was initialized and bounded current-head evidence reviewed for changed-file evidence including .github/workflows/ci.yml, .github/workflows/fuzz.yml, .github/workflows/scorecard-analysis.yml, Cargo.lock, Cargo.toml, and 15 more.
Linter/static: workflow/static review evidence is bounded by the current-head GitHub Checks gate and changed-file evidence.
TDD/regression: coverage execution evidence and focused changed hunks were reviewed from bounded-review-evidence.md.
Coverage: coverage execution evidence reports supported repository test suites passed.
Docstring coverage: coverage execution evidence reports configured repository docstring gates passed or docstring coverage was advisory.
DAG: CodeGraph/source-backed behavior map connects .github/workflows/ci.yml to the affected review, runtime, or workflow path and required checks.
PoC/execution: coverage-evidence job executed on the current head and reported PASS.
DDD/domain: workflow and repository-governance invariants were reviewed against changed files in bounded evidence.
CDD/context: CodeGraph evidence, changed-file history, and focused hunks were reviewed from bounded-review-evidence.md.
Similar issues: changed-file history evidence was reviewed for comparable local precedents.
Claim/concept check: bounded evidence, repository source, current-head workflow evidence, and, where numeric, scientific, statistical, or literature-backed claims are affected, original-paper/formula evidence and parameter-recovery expectations were used for claims.
Standards search: standards and external-source checks are delegated to configured OpenCode web_search/Context7/DeepWiki sources when applicable; no evidence-backed standards blocker is present in bounded evidence.
Compatibility/convention: changed workflow/script conventions, object naming, and reserved-word safety for schema/API/config/code surfaces were checked in bounded evidence.
Breaking-change/backcompat: deployment evidence and changed-file history were checked for backward-compatibility risk.
Performance: changed surfaces were checked for performance risk in bounded evidence.
Developer experience: changed automation, review, test, setup, and maintenance surfaces were checked for helpful or obstructive DX impact in bounded evidence.
User experience: connected user, operator, API, CLI, documentation, review-comment, status-check, rendering, and workflow-reader behavior was checked for contradictions against code, docs, and tests in bounded evidence.
Visual/DOM: Playwright visual, DOM locator, ARIA snapshot, console, and responsive evidence were checked when a web UI surface was present; for non-web surfaces, API/CLI/log/docs/workflow interaction evidence was reviewed instead.
Accessibility/i18n: accessibility, localization, and human-readable text surfaces were checked where UI, CLI, API message, docs, logs, or review text changed.
Supply-chain/license: dependency, package, model, container, and external-tool changes were checked in bounded evidence.
Packaging: package, build, test, lint, and security contracts were checked in bounded evidence.
Security/privacy: workflow-token, review-gate, and repository-automation security/privacy boundaries were checked in bounded evidence.
- Result: APPROVE
- Reason: PR addresses security gates and fuzz coverage with pinned dependencies and Docker images
- Head SHA:
0e04be7ca112bdb138b3b6f8841cf5dc56d6e12c - Workflow run: 29083036706
- Workflow attempt: 1
Changed-File Evidence Map
flowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Workflow (3 files)"]
S1 --> I1["GitHub Actions review job"]
I1 --> R1["Review risk: Workflow (3 files)"]
R1 --> V1["actionlint plus required checks"]
Evidence --> S2["Changed file (34 files)"]
S2 --> I2["repository behavior"]
I2 --> R2["Review risk: Changed file (34 files)"]
R2 --> V2["required checks"]
Evidence --> S3["Docs (2 files)"]
S3 --> I3["operator or user guidance"]
I3 --> R3["Review risk: Docs (2 files)"]
R3 --> V3["docs review"]
Evidence --> S4["Test (2 files)"]
S4 --> I4["regression suite"]
I4 --> R4["Review risk: Test (2 files)"]
R4 --> V4["targeted test run"]
Summary
security-events: writeto the job scope.Code scanning items targeted
.github/workflows/ci.yml,.github/workflows/scorecard-analysis.yml, and the fuzz workflow action refs..github/workflows/scorecard-analysis.ymlnow grantssecurity-events: writeonly to the SARIF upload job.Verification
git diff --checkruby -e 'require "yaml"; ARGV.each { |f| YAML.load_file(f); puts "ok #{f}" }' .github/workflows/ci.yml .github/workflows/scorecard-analysis.yml .github/workflows/fuzz.yml\n-cargo fmt --check\n-cargo test --locked --workspace\n-cargo clippy --locked --workspace --all-targets -- -D warnings\n- Docker digest/apt evidence: registry digest lookup succeeded forrust:1.88-bookwormanddebian:bookworm-slim; Debian bookworm candidates wereca-certificates=20230311+deb12u1andcurl=7.88.1-10+deb12u14.\n-docker build -t wardnet-security-gates:local .reached the digest-pinned build image pull but local podman storage ran out while unpacking rustc:no space left on device. This is local container storage pressure, not a Dockerfile syntax or package-resolution failure.\n\n## PR queue note\n- This incorporates and pins the fuzzing work that test(fuzz): coverage-guided fuzzing for untrusted-input surfaces #37 had open review comments for, so the same SHA pinning issue is handled here on current base.