Skip to content

qa(security): add supply-chain, fuzz, and authz coverage#23

Open
UberMetroid wants to merge 1 commit into
masterfrom
qa/security
Open

qa(security): add supply-chain, fuzz, and authz coverage#23
UberMetroid wants to merge 1 commit into
masterfrom
qa/security

Conversation

@UberMetroid

Copy link
Copy Markdown
Collaborator

Adds CI and code-level security coverage:

  • .github/workflows/security.yml — runs cargo-deny, cargo-audit, gitleaks, and cargo-cyclonedx SBOM (JSON + XML) on every PR and weekly on master. Includes a smoke build of the four fuzz targets.
  • fuzz/ — cargo-fuzz style crate with four stdin/file-driven harnesses (whois_parser, asn_parser, query_classify, pin_session) and a seed corpus per target. Harnesses work with cargo +nightly fuzz build (libfuzzer path) or cargo build --manifest-path fuzz/Cargo.toml --bin <target> (standalone path used in CI when g++ is unavailable).
  • backend/tests/authz.rs — 30 integration tests: per-IP rate limit, SSRF (private/loopback/reserved RFC1918/CGNAT/IPv6-special, scheme guards, oversized input, malformed hostnames, IPv6 literal handling), body size limit (positive + three rejection paths), security headers (positive responses and error responses), lookup route input classification (empty, SQL/XSS/path-traversal payloads, bracketed private IPs, oversized), and WHOIS-query control-character rejection through verify_pin.
  • .gitleaks.toml — config with regex allowlists for fixture PINs and fuzz/corpus/ test vectors; extends the default rule set.
  • backend/src/lib.rs — re-exports the binary's modules (asn_types, config, routes, services, state, utils) so integration tests and fuzz crates can compile against the same surface as main.rs.

Production-code changes (each a clear, minimal fix):

  • backend/src/main.rs — adds a RequestBodyLimitLayer::new(16 KiB) to /api/* routes so oversized POST bodies (e.g. /verify-pin) are rejected with 413 before any handler dispatches. Closes a memory-exhaustion gap surfaced by the authz tests.
  • backend/Cargo.toml — enables the limit feature on tower-http; adds dev-deps tower and http-body-util for the new tests.
  • deny.tomlallow-git was pointing at UberMetroid/shared-assets but the project now lives at studio2201/shared-assets; updated to match. Without this fix the cargo-deny sources check (which the new CI runs) fails with source-not-allowed.

Validation (locally, clean build):

  • cargo build --workspace — PASS
  • cargo test --workspace --bins — 22 passed, 0 failed
  • cargo test --test authz — 30 passed, 0 failed
  • cargo deny check — advisories ok, bans ok, licenses ok, sources ok (exit 0)
  • cargo audit — 2 ignored advisories present in deny.toml
  • gitleaks detect --config .gitleaks.toml --source . — no leaks found
  • cargo build --manifest-path fuzz/Cargo.toml --bin {whois_parser,asn_parser,query_classify,pin_session} — all four targets build; each runs cleanly on its seed corpus.

Limitations:

  • fuzz harness does not depend on libfuzzer-sys, so the standalone cargo +nightly fuzz build step in the CI workflow requires libfuzzer (g++) and will skip otherwise. CI is configured to install g++ before running the build. The harnesses also work via plain cargo build --manifest-path fuzz/Cargo.toml for environments without a C++ toolchain.
  • deny.toml still warns on three over-broad license allowlist entries (OpenSSL, Unicode-DFS-2016, Zlib); these were inherited from the pre-existing config and cause only non-blocking warnings, not failures.
  • The fuzz query_classify and whois_parser targets depend on tokio::net::lookup_host; in a fuzz session the resolver may surface unrelated No address associated with hostname errors rather than panics — those are caught by the runtime and not interpreted as fuzzer failures.

Adds .github/workflows/security.yml running cargo-deny, cargo-audit,
gitleaks, and cargo-cyclonedx SBOM generation on every PR and weekly on
master.

Adds fuzz/ with stdin/file-driven harnesses (compatible with cargo-fuzz
metadata) for the WHOIS parser, ASN parser, IP/CIDR/hostname classifier,
and PIN/session helpers, plus a small seed corpus per target.

Adds backend/tests/authz.rs with 30 integration tests covering rate limit,
SSRF (private/loopback/reserved, scheme guards, oversized input, IPv4 &
IPv6), body size limit, security headers, lookup input classification,
and PIN flow control-character rejection.

Adds .gitleaks.toml with project-specific allowlists for fixture PINs.

Adds backend/src/lib.rs re-exporting the binary's modules so integration
and fuzz crates can compile against the same public surface as main.

Production-code changes:
- backend/src/main.rs: add a 16 KiB RequestBodyLimitLayer to /api/* routes
  to reject oversized POST bodies (412) before handler dispatch.
- backend/Cargo.toml: enable tower-http 'limit' feature; add dev-deps
  for tower + http-body-util used by tests/authz.rs.
- deny.toml: update allow-git from stale 'UberMetroid' path to current
  'studio2201/shared-assets' so cargo-deny 'sources' check passes.

Validation run locally:
- cargo build/test --workspace: 22 existing + 30 authz tests pass.
- cargo deny check: PASS (advisories ok, bans ok, licenses ok, sources ok).
- cargo audit: PASS (2 ignored advisories present in deny.toml).
- gitleaks detect --config .gitleaks.toml: no leaks.
- cargo build --manifest-path fuzz/Cargo.toml --bin <target>: builds for
  all four targets (whois_parser, asn_parser, query_classify, pin_session).
  Each target runs cleanly against its seed corpus inputs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant