Skip to content

[codex] Harden DDoS protection controls - #2

Merged
CuriosityOS merged 31 commits into
mainfrom
Codex-Hardening
Jun 25, 2026
Merged

[codex] Harden DDoS protection controls#2
CuriosityOS merged 31 commits into
mainfrom
Codex-Hardening

Conversation

@CuriosityOS

@CuriosityOS CuriosityOS commented Jun 25, 2026

Copy link
Copy Markdown
Owner

Summary

  • Harden HTTP/TCP DDoS controls across request framing, upstream response framing, filter rule validation, learned filter sanitation, adaptive signatures, and runtime guardrail assertions.
  • Tighten CodexSDGate analyzer output so malformed provider IDs or optional matchers cannot poison runtime filter reloads.
  • Expand documentation and benchmark/assertion coverage for the hardened control surfaces.

Validation

  • cargo fmt --check
  • cargo clippy --all-targets -- -D warnings
  • cargo test --quiet
  • PYTHONPATH=tools python3 -m unittest discover -s tools -p 'test_*.py'
  • python3 tools/validate_edge_templates.py
  • python3 tools/assert_defense_bench.py --audit-tracked-artifacts benchmark_results --artifact-manifest benchmark_results/defense_artifacts_manifest.json
  • cargo audit
  • git diff --check
  • Core Linux validation: Rust tests, Python tests, edge template validation, defense artifact assertion, release build, and short loopback benchmark assertion
  • CodeRabbit review: no findings

Notes

  • This PR intentionally keeps working on branch Codex-Hardening and does not merge it.

Summary by CodeRabbit

  • New Features

    • Adaptive detectors can now activate rules using legacy request signatures when they differ from the current signature.
  • Bug Fixes

    • Hardened HTTP proxy parsing and framing: stricter Transfer-Encoding validation (limits empty elements), whitespace-tolerant Content-Length, improved upstream framing failures as 502 Bad Gateway, port-aware host checks, and stricter trusted-client IP handling.
    • Tightened filter validation and signature/header matching, with safer reload/activation behavior and bounded pruning.
    • TCP activity notifications are now bounded and coalesced.
  • Documentation

    • Updated README and hardening docs to reflect the stricter validation, identity sanitization, and safer filter controls.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9264a123-7e73-4aac-8bc3-015471e38618

📥 Commits

Reviewing files that changed from the base of the PR and between 8813497 and 954af28.

📒 Files selected for processing (2)
  • tools/run_edge_namespace_smoke.py
  • tools/test_ai_tools.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tools/run_edge_namespace_smoke.py
  • tools/test_ai_tools.py

📝 Walkthrough

Walkthrough

The PR updates filter signatures and validation, tightens HTTP framing and client-IP parsing, bounds TCP relay activity notifications, hardens provider filter sanitization, and expands benchmark assertions, runner behavior, tests, docs, artifacts, and one CI invocation.

Changes

Request hardening and tooling updates

Layer / File(s) Summary
Filter signatures and rule IDs
Cargo.toml, README.md, docs/ARCHITECTURE.md, src/filter.rs
Filter rule IDs are restricted to visible ASCII and header-safe bytes, signature matchers accept current and legacy hex forms, request signatures use blake3 hex, combined header values drive matching/classification, and the related docs/tests reflect the new formats.
HTTP framing and identity parsing
src/http_proxy.rs, docs/ARCHITECTURE.md, docs/EDGE_PROTECTION.md, docs/OPERATIONS.md
Request and response framing now trim Content-Length, cap empty Transfer-Encoding elements, validate upstream response framing, reject invalid header names, and tighten singleton client-IP, Connection, and host allow-list parsing; the related tests and docs are updated.
Legacy signature activation
src/adaptive.rs
AdaptiveDetector computes and activates a legacy request signature alongside the current one, and the tests cover matching legacy-keyed and current-keyed learned rules.
Provider sanitization and smoke parsing
tools/codex_analyzer.py, docs/AI_PROVIDERS.md, tools/run_edge_namespace_smoke.py, tools/test_ai_tools.py
Provider outputs are routed through shared sanitization helpers that enforce signature formats, HTTP token names, bounded UTF-8 lengths, non-empty conditions, and unique IDs before runtime filter files are written; the provider guidance, namespace smoke parsing, and tests are updated.
Bounded TCP activity notifications
src/tcp_proxy.rs
Relay idle coordination switches to a capacity-1 channel, relay writes call notify_activity, and repeated notifications are coalesced with try_send(()); the unit test checks the bounded queue.
Local bench runner and guardrail assertions
benchmark_results/defense_artifacts_manifest.json, tools/run_local_bench.py, tools/assert_local_bench.py, tools/test_ai_tools.py, .github/workflows/ci.yml, tools/validate_edge_templates.py
Startup and readiness failures collect bounded stderr tails, JSONL events are polled until predicates match, host-guard probes add unlisted-port cases, edge-template validation can skip nft syntax checks, and the assertion harness expands required checks across proxy, startup, logging, and admin probes. The benchmark artifact manifest, CI tool invocation, and tests are updated with the expanded evidence set.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~90+ minutes

Poem

🐇 I hopped through hashes, bright and neat,
and sniffed each header, crisp and sweet.
With bounded thumps and quieter rails,
the proxy guards its rabbit trails.
🎩✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: hardening DDoS protection controls across proxy, filter, and validation paths.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch Codex-Hardening

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/filter.rs (1)

2016-2030: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Pin the new signature test to a concrete digest.

This only proves length plus path normalization. A different 128-bit hash, or a basis tweak that still makes Lines 2023-2028 pass, would slip through without catching the compatibility regression this PR is trying to lock down.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/filter.rs` around lines 2016 - 2030, The new request signature test is
too loose because it only checks length, normalization, and ASCII hex, so it can
miss a compatibility regression in request_signature or
legacy_request_signature. Update
request_signature_uses_blake3_fingerprint_with_legacy_helper to assert the exact
expected digest for a fixed input, using request_signature and
legacy_request_signature as the targets, so the test pins the new BLAKE3-based
output to a concrete value and will fail if the hashing basis changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/filter.rs`:
- Around line 481-493: The merged snapshot in FilterEngine::reload/load path
only checks duplicate rule IDs via validate_unique_filter_rule_ids, so malformed
or unsafe rules can still be published. After loading and sorting `loaded`,
validate each rule with validate_filter_rule before building the runtime state,
ideally alongside the existing merged-filter checks in this same block, and
reject the reload if any rule fails. Keep the ID dedupe and activation deadline
retention logic unchanged, but ensure the final `loaded` collection is fully
validated before it is used by FilterEngine::new callers.

In `@src/http_proxy.rs`:
- Around line 1525-1533: The Content-Length validation in
validate_parsed_content_length only checks for trimmed ASCII digits, so
oversized values can slip through and bypass the fast-fail path. Update this
helper to also reject values that do not fit in u64 by parsing the trimmed
string as an integer and returning invalid_reason on parse overflow or failure,
so both request and response handling consistently rejects impossible
Content-Length values.

In `@tools/codex_analyzer.py`:
- Around line 827-829: `filter_has_matcher` is treating a condition with only an
empty `methods` array as a valid runtime rule, so update `sanitize_filter` to
omit the `methods` key when the cleaned list is empty. Make sure the matcher
check in `filter_has_matcher` continues to drop any rule that has no real
matcher after sanitization, so `runtime/filters.json` never includes degenerate
conditions.

---

Nitpick comments:
In `@src/filter.rs`:
- Around line 2016-2030: The new request signature test is too loose because it
only checks length, normalization, and ASCII hex, so it can miss a compatibility
regression in request_signature or legacy_request_signature. Update
request_signature_uses_blake3_fingerprint_with_legacy_helper to assert the exact
expected digest for a fixed input, using request_signature and
legacy_request_signature as the targets, so the test pins the new BLAKE3-based
output to a concrete value and will fail if the hashing basis changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3778a086-ada2-4696-81cc-d769841a7aea

📥 Commits

Reviewing files that changed from the base of the PR and between ba8cfc9 and b5dfe39.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (15)
  • Cargo.toml
  • README.md
  • benchmark_results/defense_artifacts_manifest.json
  • docs/AI_PROVIDERS.md
  • docs/ARCHITECTURE.md
  • docs/EDGE_PROTECTION.md
  • docs/OPERATIONS.md
  • src/adaptive.rs
  • src/filter.rs
  • src/http_proxy.rs
  • src/tcp_proxy.rs
  • tools/assert_local_bench.py
  • tools/codex_analyzer.py
  • tools/run_local_bench.py
  • tools/test_ai_tools.py

Comment thread src/filter.rs
Comment thread src/http_proxy.rs
Comment thread tools/codex_analyzer.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tools/run_edge_namespace_smoke.py (1)

135-206: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Whitespace normalization is applied inconsistently.

The SYN/Xmas/new-non-SYN matchers were migrated to compact_stdout, but the remaining substring checks (e.g. tcp_invalid_null_drop_present at Line 171‑172, update @tcp4_syn_rate``/limit rate over 5000... at Lines 178‑182, `udp_protected_port_drop_present` at Line 194, the connlimit and ICMP checks) still match against raw `stdout`. If real `nft list` output renders these rules with different inter-token spacing than the canonical single-spaced form, the migrated checks would still pass while these raw checks could spuriously report `False`. Consider matching all rule-presence substrings against `compact_stdout` for uniform robustness.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/run_edge_namespace_smoke.py` around lines 135 - 206, Whitespace
normalization is applied inconsistently in this smoke test: some rule matchers
use compact_stdout while several remaining presence checks still compare against
raw stdout. Update the rule-presence assertions in run_edge_namespace_smoke.py
to use compact_stdout consistently for all nft substring checks, including the
tcp_invalid_null_drop_present, syn backstop, connlimit, udp, and ICMP matches,
so spacing differences in nft output do not cause false negatives. Refer to the
existing compact_stdout normalization and the helper booleans in the return dict
to keep the matching style uniform.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tools/run_edge_namespace_smoke.py`:
- Around line 135-206: Whitespace normalization is applied inconsistently in
this smoke test: some rule matchers use compact_stdout while several remaining
presence checks still compare against raw stdout. Update the rule-presence
assertions in run_edge_namespace_smoke.py to use compact_stdout consistently for
all nft substring checks, including the tcp_invalid_null_drop_present, syn
backstop, connlimit, udp, and ICMP matches, so spacing differences in nft output
do not cause false negatives. Refer to the existing compact_stdout normalization
and the helper booleans in the return dict to keep the matching style uniform.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d4379678-0bb3-4130-b377-42bcae9dd870

📥 Commits

Reviewing files that changed from the base of the PR and between 5c94af2 and f61b1c4.

📒 Files selected for processing (2)
  • tools/run_edge_namespace_smoke.py
  • tools/test_ai_tools.py

@CuriosityOS
CuriosityOS merged commit 5d20b12 into main Jun 25, 2026
3 checks passed
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