Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
9dfda58
feat(security): fail closed on outbound literal destinations
codex Aug 31, 2026
10f7347
fix(security): harden outbound egress validation
codex Aug 31, 2026
a27f8d6
fix(proxy): preserve first-hop redirects
codex Aug 31, 2026
5e8d24b
fix(egress): revalidate resolved outbound hosts
codex Aug 31, 2026
5f6184e
fix(egress): pin validated outbound DNS answers
codex Aug 31, 2026
8e0d826
docs(test): satisfy outbound policy review gates
codex Aug 31, 2026
e274d26
fix(egress): preserve pinned resolution for dotted hosts
codex Aug 31, 2026
4b1b458
fix(egress): bound pinned outbound client cache
codex Aug 31, 2026
0af75ab
docs(egress): document pinned client cache helpers
codex Sep 1, 2026
b07d0d7
merge: synchronize outbound security hardening with protected main
seonghobae Sep 1, 2026
79a0e0b
test(security): fence outbound HTTP policy architecture
seonghobae Sep 2, 2026
45484a9
test(security): make outbound policy fitness boundaries deterministic
seonghobae Sep 2, 2026
edf5e88
style(test): format outbound policy architecture contract
seonghobae Sep 2, 2026
3e66c26
test(security): repair outbound policy architecture fence
seonghobae Sep 2, 2026
f408500
test(security): red for shared outbound DNS deadline
seonghobae Sep 2, 2026
83e2b4f
build(security): enable Tokio deadline support
seonghobae Sep 2, 2026
3cb1047
test(security): format outbound deadline RED
seonghobae Sep 3, 2026
9978f8c
fix(security): bound outbound DNS by fetch deadline
codex Sep 4, 2026
28e5776
test(security): exercise pending DNS deadline
seonghobae Sep 4, 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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ reqwest = { version = "0.12", default-features = false, features = ["rustls-tls"
futures-util = { version = "0.3", default-features = false, features = ["std"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tokio = { version = "1", features = ["fs", "macros", "net", "rt-multi-thread", "signal", "sync"] }
tokio = { version = "1", features = ["fs", "macros", "net", "rt-multi-thread", "signal", "sync", "time"] }
waf-ids-core = { path = "crates/waf-ids-core" }

[dev-dependencies]
Expand Down
6 changes: 5 additions & 1 deletion docs/runbooks/operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,15 @@ When `WAF_IDS_STATE_PATH` is enabled, the process writes a temporary sibling fil
This baseline is suitable for local and controlled lab deployments. Internet-facing use still requires:

- TLS termination and identity-aware admin access
- upstream allowlists and egress controls
- DNS-aware allowlists and request-time egress revalidation beyond the current literal-host fail-closed checks
- durable database storage with backups
- SSO/OIDC federation (multi-token RBAC with readonly role and audit-log auth are available)
- asynchronous event persistence or a database-backed event store for high-throughput gateway traffic
- In-process Coraza embedding (HTTP audit ingest at `POST /api/waf/coraza/audit` already fuses block hits into DNSBL/`client_ip` indicators for gateway enforcement)
- Live Suricata EVE tailing / shipper (HTTP ingest of EVE alerts is available at `POST /api/ids/suricata/eve`)
- Live MISP REST pull or live OpenCTI GraphQL pull (HTTP STIX/MISP/OpenCTI document ingest and TAXII 2.1 poll are available at `POST /api/threat-intel/stix`, `POST /api/threat-intel/misp`, `POST /api/threat-intel/opencti`, and `POST /api/threat-intel/taxii/poll`)
- human approval workflow for AI SOC recommendations that change enforcement

Current outbound guardrails reject destination URLs that include embedded credentials or fragments, require HTTPS off loopback, and fail closed when either literal IPs or request-time DNS resolution land on localhost/private/link-local/documentation address space before proxying gateway traffic or calling feed, Clearfolio, or SOC-LLM upstreams. This is still a first layer rather than a full egress platform: Wessels et al. (2024) show that incomplete SSRF defenses remain common when services rely on ad hoc validation rather than explicit request policy, and Jackson et al. (2007) explain why DNS rebinding defenses need request-time hostname revalidation rather than one-time parsing alone. Hostname allowlisting, DNS pinning, and audited proxy configuration remain follow-up controls.

References: Wessels, M., Koch, S., Pellegrino, G., & Johns, M. (2024). *SSRF vs. developers: A study of SSRF-defenses in PHP applications*. https://trouge.net/papers/sec24_SSRF.pdf ; Jackson, C., Bortz, A., Boneh, D., & Mitchell, J. C. (2007). *Protecting browsers from DNS rebinding attacks*. https://web.eecs.umich.edu/~aprakash/eecs588/handouts/dns-rebinding.pdf. These links remain citation-only in this repository because this PR does not establish redistribution rights for the external paper PDFs.
2 changes: 1 addition & 1 deletion docs/security/threat-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
| Unauthorized management write | Route takeover or false blocking | `X-Admin-Token` write gate; multi-token RBAC with actor labels and readonly role; audit log for successful writes | SSO/OIDC, mTLS or identity proxy, SCIM |
| Malicious threat feed import | False positives or broad blocks | Validation, route-scoped enforcement | Source signing, feed confidence, staged promotion |
| State file corruption | Startup failure or stale policy | JSON parse failure surfaces startup error | Database, backup, schema migration |
| Upstream SSRF through routes | Internal network exposure | Upstream scheme validation | Upstream allowlists, egress policy |
| Upstream SSRF through routes | Internal network exposure | Shared outbound URL validation rejects credentials, fragments, and localhost/private literal destinations before proxy/fetch calls | DNS resolution allowlists, request-time rebinding checks, egress policy |
| Gateway DoS | Availability loss | Rust memory safety, event retention limit | Rate limits, body limits, async event sink |
| DNSBL abuse | Reputation damage | Loopback response-code validation | Authoritative DNS service, signing, publisher workflow |
| Secret disclosure | Admin compromise | Support bundle excludes admin token; secrets bootstrapped into credential registry (`WAF_IDS_CREDENTIALS_PATH` preferred over long-lived env); health exposes source label only | External secret manager / SSO, rotation, access review |
Expand Down
Loading
Loading