Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
6ccc277
docs(audits): add 2026-02 rust security correctness audit
bb-connor Feb 10, 2026
8741408
fix(audit): remediate CS-AUDIT-001..006
bb-connor Feb 10, 2026
a0d2c12
fix(hush-cli): harden CONNECT proxy policy/resource bounds
bb-connor Feb 10, 2026
a292e66
fix(clawdstrike): fail closed on IRM path and URL spoof bypasses
bb-connor Feb 10, 2026
b347eff
fix(remote-extends): validate git refs and block option injection
bb-connor Feb 10, 2026
1555397
fix(policy): bound extends recursion and async background inflight
bb-connor Feb 10, 2026
6f00b19
fix(audit): finalize remediation evidence and ipv6 parity
bb-connor Feb 10, 2026
88fc6fb
fix(hush-cli): pin CONNECT hostname resolution to policy-checked IP
bb-connor Feb 10, 2026
973e5bb
fix(clawdstrike): fail closed when filesystem IRM path extraction is …
bb-connor Feb 10, 2026
a0e00ba
chore(security): codify advisory exceptions and wave3 remediation proof
bb-connor Feb 10, 2026
c791e13
feat(security): add pre-release posture docs, regressions, fuzz, and …
bb-connor Feb 10, 2026
ec15c3e
fix(review): address CONNECT retry, SCP parsing, and session lock pru…
bb-connor Feb 10, 2026
a2f500c
fix(remote-extends): treat scheme remotes as URLs before scp parsing
bb-connor Feb 10, 2026
e6cc36a
fix(hush-run): block full non-public ipv4 special-use ranges
bb-connor Feb 10, 2026
e0d88a8
fix(irm): accept bare filenames in path extraction
bb-connor Feb 10, 2026
a32ee10
fix(hushd): use cached git policy before DNS host checks
bb-connor Feb 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,28 @@ env:
RUST_BACKTRACE: 1

jobs:
security-regressions:
name: Fast Security Regressions
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v6

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable

- name: Run security regression contract tests
run: |
cargo test -p hush-cli --test abuse_harness -- --nocapture
cargo test -p clawdstrike --test security_regressions -- --nocapture
cargo test -p hushd --test security_regressions -- --nocapture
cargo test -p hush-cli hush_run::tests::connect_proxy_rejects_ip_target_with_allowlisted_sni_mismatch -- --exact
cargo test -p hush-cli hush_run::tests::connect_proxy_hostname_target_is_ip_pinned_after_policy_check -- --exact

check:
name: Check
runs-on: ubuntu-latest
needs: security-regressions
steps:
- uses: actions/checkout@v6

Expand Down Expand Up @@ -244,6 +263,7 @@ jobs:
security-audit:
name: Security Audit
runs-on: ubuntu-latest
needs: security-regressions
steps:
- uses: actions/checkout@v6

Expand All @@ -253,8 +273,18 @@ jobs:
- name: Install cargo-audit
run: cargo install cargo-audit --locked --version 0.22.0

- name: Enforce advisory exception policy metadata
run: tools/scripts/check-advisory-expiry.sh

- name: Run security audit
run: cargo audit
run: |
cargo audit --deny warnings \
--ignore RUSTSEC-2024-0375 \
--ignore RUSTSEC-2025-0141 \
--ignore RUSTSEC-2024-0388 \
--ignore RUSTSEC-2024-0436 \
--ignore RUSTSEC-2025-0134 \
--ignore RUSTSEC-2021-0145

license-check:
name: License Check
Expand Down Expand Up @@ -427,8 +457,9 @@ jobs:
fi

fuzz-check:
name: Fuzz Check
name: Fuzz Smoke (PR)
runs-on: ubuntu-latest
needs: security-regressions
steps:
- uses: actions/checkout@v6

Expand All @@ -443,6 +474,13 @@ jobs:
cd fuzz
cargo +nightly build

- name: Run fuzz smoke targets
run: |
cd fuzz
cargo +nightly fuzz run fuzz_policy_parse -- -max_total_time=30
cargo +nightly fuzz run fuzz_irm_net_parse -- -max_total_time=30
cargo +nightly fuzz run fuzz_remote_extends_parse -- -max_total_time=30

typescript-sdk:
name: TypeScript SDK
runs-on: ubuntu-latest
Expand Down
21 changes: 11 additions & 10 deletions .github/workflows/fuzz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,18 @@ jobs:
uses: dtolnay/rust-toolchain@nightly

- name: Install cargo-fuzz
run: cargo install cargo-fuzz
run: cargo install cargo-fuzz --locked --version 0.13.1

- name: Run fuzz targets (time-boxed)
run: |
cd fuzz
# Keep these time-bounded to avoid runaway CI costs.
# 60s per target, ~6 minutes total.
cargo +nightly fuzz run fuzz_dns_parse -- -max_total_time=60
cargo +nightly fuzz run fuzz_sni_parse -- -max_total_time=60
cargo +nightly fuzz run fuzz_policy_parse -- -max_total_time=60
cargo +nightly fuzz run fuzz_secret_leak -- -max_total_time=60
cargo +nightly fuzz run fuzz_sha256 -- -max_total_time=60
cargo +nightly fuzz run fuzz_merkle -- -max_total_time=60

# Nightly deep run: 120s per target (~18m total for 9 targets).
cargo +nightly fuzz run fuzz_dns_parse -- -max_total_time=120
cargo +nightly fuzz run fuzz_sni_parse -- -max_total_time=120
cargo +nightly fuzz run fuzz_policy_parse -- -max_total_time=120
cargo +nightly fuzz run fuzz_secret_leak -- -max_total_time=120
cargo +nightly fuzz run fuzz_sha256 -- -max_total_time=120
cargo +nightly fuzz run fuzz_merkle -- -max_total_time=120
cargo +nightly fuzz run fuzz_irm_fs_parse -- -max_total_time=120
cargo +nightly fuzz run fuzz_irm_net_parse -- -max_total_time=120
cargo +nightly fuzz run fuzz_remote_extends_parse -- -max_total_time=120
39 changes: 39 additions & 0 deletions .github/workflows/miri.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Miri (Scheduled)

on:
workflow_dispatch: {}
schedule:
- cron: '0 5 * * 1'

env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
MIRIFLAGS: -Zmiri-strict-provenance

jobs:
miri-curated:
name: Miri Curated Security Tests
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v6

- name: Install Rust nightly + miri
uses: dtolnay/rust-toolchain@nightly
with:
components: miri

- name: Set up Miri
run: cargo +nightly miri setup

- name: Run policy depth regression under Miri
run: cargo +nightly miri test -p clawdstrike policy_extends_depth_limit_enforced -- --exact

- name: Run IRM fs traversal regression under Miri
run: cargo +nightly miri test -p clawdstrike irm::fs::tests::filesystem_irm_denies_traversal_when_path_is_in_nonfirst_object_arg -- --exact

- name: Run IRM net spoof regression under Miri
run: cargo +nightly miri test -p clawdstrike irm::net::tests::test_userinfo_spoof_url_uses_actual_host_and_is_denied -- --exact

- name: Run async runtime cap regression under Miri
run: cargo +nightly miri test -p clawdstrike --test security_regressions security_regression_async_background_guards_enforce_inflight_limit -- --exact
37 changes: 37 additions & 0 deletions .github/workflows/sanitizers.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Sanitizers (Scheduled)

on:
workflow_dispatch: {}
schedule:
- cron: '0 4 * * *'

env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1

jobs:
asan-smoke:
name: ASAN Smoke (hush-cli + clawdstrike)
runs-on: ubuntu-latest
timeout-minutes: 90
steps:
- uses: actions/checkout@v6

- name: Install build prerequisites
run: |
sudo apt-get update
sudo apt-get install -y clang lld

- name: Install Rust nightly
uses: dtolnay/rust-toolchain@nightly
with:
targets: x86_64-unknown-linux-gnu

- name: Run ASAN smoke tests
env:
RUSTFLAGS: -Zsanitizer=address
ASAN_OPTIONS: detect_leaks=1:strict_string_checks=1
run: |
cargo +nightly test -Zbuild-std --target x86_64-unknown-linux-gnu -p hush-cli hush_run::tests::connect_proxy_rejects_ip_target_with_allowlisted_sni_mismatch -- --exact
cargo +nightly test -Zbuild-std --target x86_64-unknown-linux-gnu -p hush-cli hush_run::tests::connect_proxy_hostname_target_is_ip_pinned_after_policy_check -- --exact
cargo +nightly test -Zbuild-std --target x86_64-unknown-linux-gnu -p clawdstrike --test security_regressions security_regression_async_background_guards_enforce_inflight_limit -- --exact
35 changes: 35 additions & 0 deletions NON_GOALS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Non-Goals

This document lists explicit non-goals for the current pre-release security posture.

## Adversarial ML guarantees

- We do not claim perfect jailbreak prevention.
- We do not claim complete resistance against adaptive adversarial prompt attacks.

## Host compromise classes

- We do not defend against kernel-level compromise.
- We do not defend against malicious root/admin on the host.
- We do not defend against a fully compromised dependency ecosystem.

## Filesystem edge classes not universally guaranteed

- We do not claim comprehensive defense across all mount/hardlink/junction corner cases on every platform.
- We do not claim universal elimination of check-then-open (TOCTOU) races in all external integrations.

## Platform parity limitations

- Security behavior can differ by platform/runtime features and available sandboxing primitives.
- Linux/macOS-oriented controls may not map 1:1 to Windows semantics.

## Network perimeter non-goals

- We do not claim this repository alone enforces kernel/network microsegmentation.
- Defense in depth with platform/network controls remains an operator responsibility.

## What we do instead

- Fail closed by default for ambiguous security-relevant parsing.
- Use bounded queues, inflight caps, and timeouts for DoS resistance.
- Maintain targeted regression tests, fuzzing, and scheduled memory/concurrency sensors.
Loading