Skip to content
Open
Changes from all commits
Commits
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
19 changes: 19 additions & 0 deletions docs/product-technical-gap-baseline.md
Original file line number Diff line number Diff line change
Expand Up @@ -2628,6 +2628,25 @@ Higgins, S. S., Crepalde, N., & Fernandes, L. (2021). Segmented multiplexity: A

**Evidence / acceptance.** Permanent tests forbid retry/deadline/sampling symbols in the caller and prove one gateway request, one attempt annotation, control-character-safe telemetry, missing-value rejection, valid trailing-comma normalization, and exact changed-line guidance. Fresh exact-head repository checks and reviews remain the admission authority; predecessor-head evidence is not transferable. The remaining runtime work is to preserve distinct `request_too_large`, discovery, rate-limit, provider transport, malformed-output, stale-head, and sandbox-command-timeout categories in hosted logs.

## Backlog item 7 (route communication security through EgressWeave/wardnet) scoping — 2026-09-02

**Status:** Scoping only, per this session's throttle agreement. Corrected per Devin review feedback: this is **not** "a confirmed gap in three separate repos" — of the three repos surveyed below, only one (`.github`) has a confirmed protection gap; `contextual-orchestrator`'s implementation is not a gap at all (a correct, independently-authored transport), and `naruon`'s is a maintenance-fragility risk (private-internals dependency), not itself a demonstrated SSRF/DNS-rebinding gap. What all three share is duplicated implementation of the same security-critical logic instead of depending on EgressWeave — migrating any of them is new consumer-integration work, not a repair of something already broken in this repository — deferred pending queue relief or explicit owner direction, matching this session's other scoping-only entries.

**Item text.** "각종 통신 보안 이슈는 EgressWeave와 wardnet을 이용해서 처리하는 쪽으로 이관 바람" — migrate assorted communication/network-security concerns to route through EgressWeave and wardnet instead of ad-hoc per-repo handling.

**EgressWeave's actual maturity, checked first.** Not vaporware: an actively maintained (pushed same day as this entry), well-documented Python library providing SSRF- and DNS-rebinding-safe `httpx` clients — exact `(host, port)` allowlisting, up-front DNS resolution with the validated address *pinned* into the transport (closing the validate-then-connect TOCTOU/DNS-rebinding gap, CWE-350), a positive HTTP-method allowlist, disabled redirects, and bounded request/response sizes and timeouts (CWE-400). Not yet on PyPI as of this entry (README: install from a reviewed source checkout until a verified PyPI release exists) — a real adoption friction point, not a design gap. `wardnet` is a separate, inbound-facing WAF/IDS/SOC gateway (route scoring, DNSBL, monitor/block enforcement) — relevant to *inbound* traffic protection, not to the outbound-egress duplication found below; the two core repos serve different halves of "communication security."

**Survey: three repos independently reimplement outbound SSRF/DNS-rebinding protection instead of depending on EgressWeave**, read directly, not inferred from names:

1. **`ContextualWisdomLab/.github`** (this repository, `main` at commit `8c085835fbf77de2321b72fa6b8dd946227e523e`) — `scripts/ci/noema_review_gate.py:1369` (`reject_private_llm_url()`) validates `NOEMA_LLM_API_URL`'s scheme, rejects localhost, resolves the hostname via `socket.getaddrinfo` (`:1390`), and rejects private/loopback/link-local/multicast/unspecified addresses — **once, at call time.** The actual request at `:1468` (`urllib.request.Request(api_url, ...)`) is plain `urllib.request`, which re-resolves DNS independently at connect time with no pinning. **This is a real, confirmed TOCTOU/DNS-rebinding gap** — exactly the class of bug EgressWeave's README states it exists to close — not merely style duplication: a DNS answer that changes between the check at `:1390` and the connect triggered from `:1468` bypasses the validation entirely. **Exploitability nuance (confirmed by a peer session, re-verified here):** `is_allowed_orchestrator_sidecar_url()` (`:1343`) short-circuits `reject_private_llm_url()` via a direct loopback-literal comparison against `CONTEXTUAL_ORCHESTRATOR_BASE_URL` — no DNS lookup at all — for the normal contextual-orchestrator-sidecar deployment, so the `getaddrinfo`/TOCTOU path only runs when `NOEMA_LLM_API_URL` is configured to a non-loopback external hostname. That variable is read from `os.environ` (`:1421`), i.e. operator-set configuration, not PR-controllable content — so this is not a "any PR triggers it" severity finding. It is still a real gap worth closing: the function's docstring ("Reject non-sidecar localhost, private, and non-http(s) LLM targets") claims to fully prevent SSRF and does not, for any deployment that legitimately points `NOEMA_LLM_API_URL` at a non-loopback host.
2. **`ContextualWisdomLab/contextual-orchestrator`** (`main` at commit `212ff437dc297613289dba2e6064ade9942e07d8`) — `contextual_orchestrator/provider_transport.py` (module docstring: *"DNS-pinned HTTPS primitives for validated model-provider egress"*) implements its own `PinnedHTTPSConnection(http.client.HTTPSConnection)` (`:16`) that connects to a pre-validated IP while preserving the original hostname for TLS SNI, plus `validated_public_addresses()` (`:49`) for the public-address check. **This is not a protection gap** — the design correctly closes the same TOCTOU class EgressWeave targets — but it is a second, independently-authored, independently-maintained implementation of the identical security-critical logic, built on raw `http.client`/`socket`/`ssl` rather than depending on the org's own purpose-built library.
3. **`ContextualWisdomLab/naruon`** (`main` at commit `042b0c70531b229af3acbd0421a2f23098d848b3`) — `backend/services/llm_provider_urls.py` has a *third* independent implementation: `_validate_global_address()` (`:84`) rejects the same private/loopback/link-local/reserved/unspecified/multicast/non-global address classes. Unlike `contextual-orchestrator`'s raw-socket approach, this one is built directly on `httpx`/`httpcore` **private, underscore-prefixed internals** — `httpcore._backends.auto.AutoBackend` (`:9`), `httpx._config.create_ssl_context` (`:10`), `httpx._transports.default.map_httpcore_exceptions` (`:11`). This is a real, additional fragility risk beyond mere duplication: these are not part of `httpx`'s/`httpcore`'s public API contract and can change or disappear in a minor version bump with no deprecation notice, unlike EgressWeave's public, versioned surface.

**Why this matters.** Three independent implementations of identical security-critical logic means three independent places that can drift, three independent audit surfaces, and (confirmed in case 1) at least one that is already measurably weaker than the shared library the org has already built and released for exactly this purpose. This is precisely the "consumer duplicates functionality an owner repo already provides" pattern the refreshed standing directive's no-consumer-workaround rule addresses (§2) — except here the *owner* repo (EgressWeave) is not immature; it is genuinely usable today (modulo the PyPI-publication friction noted above), and none of the three consumers has adopted it.

**Not fully surveyed.** Only the three repos the requesting session named as candidates were checked. This is not a claim that these are the only three repos with duplicated egress-validation logic org-wide — a fuller sweep (similar in spirit to the earlier `orchestrator/free` org-wide audit, PR #1688) would be needed to bound the total scope before committing to a migration plan.

**Suggested next steps (deferred, not started).** (1) File an owner-path tracking issue in `.github` for `reject_private_llm_url()`/`noema_review_gate.py` specifically, since it has a confirmed live gap, not just duplication — scoped as "known-fix, not-yet-implemented" by a peer session at time of writing. The fix is a proper DNS-pin (resolve once, validate, connect to the pinned IP with correct Host/SNI handling for HTTPS), which is what routing through EgressWeave (once installable) or vendoring it from source would provide, rather than patching the existing hand-rolled check in place. Priority is real but not urgent given the exploitability nuance above (operator-configuration-gated, not PR-triggerable). (2) For `contextual-orchestrator` and `naruon`, whose existing implementations are not measurably broken, migration is a larger, lower-urgency refactor (replace a working, tested transport) — worth an ADR-style decision (per this session's item-27 pattern) on whether the maintenance-burden reduction justifies the migration risk, rather than an immediate diff. (3) A broader org-wide sweep for the same pattern, once (1)/(2) establish the migration is worth doing at all.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔍 Tracking status lacks durable source

The known-fix, not-yet-implemented status cites only an unnamed peer session. Record it in the repository or Project so future agents can verify it.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

## 2026-09-02 `test_strix_quick_gate.sh` stale cron assertion left broken by the `#1630` cadence lengthening

**Problem.** The required `exact-head-path-policy` check (which runs `bash
Expand Down
Loading