Skip to content

fix(INSECURE_TRANSPORT): detect ws:// declared via top-level serverUrl#41

Open
dmchaledev wants to merge 1 commit into
mainfrom
claude/amazing-franklin-ryrtel
Open

fix(INSECURE_TRANSPORT): detect ws:// declared via top-level serverUrl#41
dmchaledev wants to merge 1 commit into
mainfrom
claude/amazing-franklin-ryrtel

Conversation

@dmchaledev

Copy link
Copy Markdown
Contributor

Summary

INSECURE_TRANSPORT only reads config.transport?.url, so a config that declares its endpoint at the top level as serverUrl: "ws://…" — with no nested transport.url block — passes the scan with zero findings. That is a false negative in a CI/CD security gate: an unencrypted WebSocket endpoint (auth tokens and tool payloads in cleartext) is reported as clean.

serverUrl is a documented, first-class field — examples/minimal-config.json uses it alone with no transport block — and the sibling rule MISSING_TLS already falls back to it (config.transport?.url ?? config.serverUrl, src/rules/auth-rules.ts:101). INSECURE_TRANSPORT did not, creating an inconsistency where a ws:// endpoint slips through both rules: MISSING_TLS excludes the WebSocket scheme (it's owned by INSECURE_TRANSPORT), and INSECURE_TRANSPORT never looked at serverUrl.

Repro (built CLI, before this change)

// wsurl.json — endpoint declared only at the top level
{ "serverUrl": "ws://insecure.example.com",
  "transport": { "auth": { "token": "abcdefghijklmnopqrstuvwxyz0123456789abcd" } },
  "rateLimit": { "enabled": true } }
$ node dist/cli.js wsurl.json --format=table
Found 0 finding(s): 0 critical, 0 high, 0 medium, 0 low
PASSED          # cleartext ws:// endpoint reported clean

The identical config with the URL duplicated under transport.url correctly fires INSECURE_TRANSPORT. After this change both forms fire.

Fix

One-line change in src/rules/runtime-rules.ts: read config.transport?.url ?? config.serverUrl, mirroring MISSING_TLS. No behavior change for configs that set transport.url (it still takes precedence).

Tests

Adds three regression tests to the INSECURE_TRANSPORT suite:

  • ws:// serverUrl with no transport.url → fires (HIGH)
  • wss:// serverUrl with no transport.url → does not fire
  • both fields present → transport.url takes precedence (evidence reflects it)

npm run typecheck, npm run lint, and npm test all pass (121 tests).

Scope

Independent of the open backlog — no open issue or PR touches INSECURE_TRANSPORT's serverUrl fallback (#18 concerns the MISSING_TLS wss:// false positive, a different direction).

🤖 Generated with Claude Code

https://claude.ai/code/session_01RfTG58p1JL5Va5ZNKVP1Rv


Generated by Claude Code

INSECURE_TRANSPORT only read config.transport?.url, so a config that
declares its endpoint at the top level as serverUrl: "ws://..." with no
nested transport.url block passed the scan with zero findings — a false
negative for a security gate on a cleartext WebSocket endpoint.

MISSING_TLS already falls back to serverUrl (config.transport?.url ??
config.serverUrl); serverUrl is a documented, first-class field
(examples/minimal-config.json uses it alone). Mirror that fallback here
so the same endpoint is evaluated regardless of which field carries it.

Adds regression tests: ws:// serverUrl fires, wss:// serverUrl does not,
and transport.url still takes precedence when both are present.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RfTG58p1JL5Va5ZNKVP1Rv
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.

2 participants