Skip to content

security: require loopback or native TLS for HTTP MCP - #5

Merged
overdrivemh merged 6 commits into
mainfrom
deployment/secure-http-transport-20260930
Oct 7, 2026
Merged

overdrivemh merged 6 commits into
mainfrom
deployment/secure-http-transport-20260930

Conversation

@overdrivemh

Copy link
Copy Markdown
Owner

OWNER=builder:deployment
PARENT=overdrivemh/Mocc#7259
FINDING=RW-MCP-HTTP-CLEARTEXT-DEFAULT-004
FINDING_AUTHORITY=overdrivemh/Mocc#7259:5840587791
SOURCE_START=overdrivemh/Mocc#7259:5918936334
BASE=8c3fee2285ccf000ff45fe20f8a4573cab972f26
PROVIDER_MUTATION=false
AWS_MUTATION=false
PRODUCT_ACCEPTANCE=false
REPO_LOCAL_QT=true
REPO_LOCAL_RRPA=true
POST_MERGE_PROOF_DEFERRAL_ALLOWED=false

Outcome

Make bearer-bearing HTTP transport fail closed by construction.

  • default and empty listen host resolve to 127.0.0.1;
  • loopback cleartext remains available for local use;
  • non-loopback listeners are rejected unless both native TLS certificate and private-key files are configured;
  • remote native TLS uses net/http ListenAndServeTLS;
  • partial TLS configuration fails closed;
  • BaseURL, TrustProxyHeaders and forwarded request metadata cannot authorize remote cleartext;
  • existing bearer middleware, CORS and OAuth metadata semantics are unchanged.

Exact paths

  • cmd/github-mcp-server/main.go
  • cmd/github-mcp-server/main_test.go
  • pkg/http/server.go
  • pkg/http/server_test.go

Required proof before merge

go test ./cmd/github-mcp-server ./pkg/http

Because this is a P1 credential-transport property, deferred post-merge assurance under the Mocc non-circular source-merge exception is explicitly not allowed. Hosted/skipped/local diagnostic evidence receives no merge credit.

Copy link
Copy Markdown
Owner Author

REPOSITORY WATCH CHANGED-CAUSE SOURCE CLEAR — inbound bearer transport now fails closed before HTTP auth exposure

WATCH_PARENT=overdrivemh/Mocc#8323
OWNER_PACKET=overdrivemh/Mocc#7259
ROOT_FINDING=RW-MCP-HTTP-CLEARTEXT-DEFAULT-004
SUBJECT_PR=#5
EXACT_HEAD=88b80952b8cb3d25c917887397c0fecbdd8e130a
BASE_MAIN=8c3fee2285ccf000ff45fe20f8a4573cab972f26
P0_SOURCE=0
P1_SOURCE=0
SOURCE_CLEAR=true
MERGE_READY=false_pending_required_repo_local_proof
PROVIDER_MUTATION=false
PRODUCT_ACCEPTANCE=false

Exact source closure:

  • CLI default --listen-host is now 127.0.0.1 rather than wildcard;
  • empty ServerConfig ListenHost also normalises to 127.0.0.1;
  • cleartext admission accepts only literal IP addresses for which net.ParseIP(host).IsLoopback() is true;
  • hostname "localhost", wildcard addresses and all other non-loopback/hostname listeners cannot use cleartext;
  • partial cert/key configuration fails before server/router/auth construction;
  • a complete cert+key pair is required for non-loopback and routes through http.Server.ListenAndServeTLS;
  • BaseURL, TrustProxyHeaders and forwarded metadata do not participate in transport admission;
  • bearer/CORS/OAuth route semantics are otherwise unchanged.

This closes the concrete Watch impact from #7259:5840587791: default or explicit remote cleartext can no longer expose the bearer-authenticated MCP hop.

Adjacent bounded read:

  • existing http.Server retains ReadHeaderTimeout and the carrier does not weaken it;
  • native TLS is Go net/http under the repository's Go 1.25 line; no source evidence was found that this four-path correction reopens proxy/header authority;
  • later slow-body/OAuth/Git transport findings named in #7259 remain separate successors and are not silently claimed closed here.

REQUIRED_TERMINAL_PROOF=go test ./cmd/github-mcp-server ./pkg/http
POST_MERGE_DEFERRAL_ALLOWED=false
HOSTED_BACKCREDIT=false
NO_PROVIDER_PROOF=true

SECURITY_PATTERN=credential-bearing listener transport must be admitted before authentication data can arrive
FIX_STATUS=SOURCE_CLOSED_PROOF_PENDING

Copy link
Copy Markdown
Owner Author

REPOSITORY WATCH TARGETED EXACT-HEAD RECENSUS — HTTP MCP cleartext boundary

WATCH_AUTHORITY=overdrivemh/Mocc#8323 under github#1440/github#1452
SUBJECT_PR=#5
EXACT_HEAD=88b80952b8cb3d25c917887397c0fecbdd8e130a
BASE=8c3fee2285ccf000ff45fe20f8a4573cab972f26
TARGET_CLASS=bearer-bearing remote cleartext HTTP listener
P0_SOURCE=0
P1_SOURCE=0
WATCH_HOLD=false
PROVIDER_MUTATION=false
PRODUCT_ACCEPTANCE=false

Targeted source readback confirms:

  • empty/default bind becomes 127.0.0.1;
  • only literal IP loopback addresses may run cleartext;
  • wildcard, hostname and other non-loopback listeners fail closed without native TLS;
  • certificate/key must be supplied together;
  • remote TLS uses net/http ListenAndServeTLS;
  • BaseURL / trusted-proxy metadata cannot authorize remote cleartext;
  • hostiles cover IPv4/IPv6 loopback, wildcard cleartext, localhost-as-non-authority, proxy metadata and partial TLS configuration.

No new P0/P1 was found in this bounded correction. Because this is a P1 credential-transport property, preserve the PR's non-deferrable independent exact-head proof requirement; source inspection does not replace candidate execution or Product Acceptance.

@overdrivemh overdrivemh left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

RRPA PASS_BOUNDED

RR_WORKER=RR3_OTHER_REPOS_OLDEST_FIRST
EXACT_HEAD=88b80952b8cb3d25c917887397c0fecbdd8e130a
SOURCE_CLEAR=true
P0_SOURCE=0
P1_SOURCE=0
PROOF_CLASS=FOCUSED_QT
PROOF_REASON=P1 credential-bearing listener transport requires executable confirmation
MERGE_AFTER_PROOF=AUTHORIZED
PRODUCT_ACCEPTANCE=NOT_APPLICABLE

CANDIDATE_RISK_ENVELOPE=HTTP listener binding/TLS admission only
SELECTED_PROOF_PROPERTIES=empty/default and literal loopback may use cleartext; wildcard/hostname/non-loopback cleartext denied; partial TLS denied; remote native TLS admitted; BaseURL/proxy metadata cannot authorize cleartext
SELECTED_TEST_SCOPE=go test ./cmd/github-mcp-server ./pkg/http
TEST_SCOPE_RATIONALE=four-file bounded transport hardening; no broader runtime/provider semantics changed
FULL_SUITE_REQUIRED=false
UNRELATED_FAILURES_BLOCKING=false

Independent source read confirms transport admission occurs before app/router/auth construction, empty bind is loopback rather than wildcard, only literal IP loopback authorizes cleartext, and non-loopback requires paired native TLS files. No attributable P0/P1 remains.

Copy link
Copy Markdown
Owner Author

RR3 CURRENTNESS PRESERVATION AFTER #6 MERGE

SUBJECT=#588b8095
CURRENT_MAIN=190ebb95116c2fff2f7b8f6bce021317174e70c7
PRIOR_BASE=8c3fee2285ccf000ff45fe20f8a4573cab972f26
MAIN_MOVEMENT_FILES=pkg/github/wiki.go;pkg/github/wiki_test.go
#5_CHANGED_FILES=cmd/github-mcp-server/main.go;cmd/github-mcp-server/main_test.go;pkg/http/server.go;pkg/http/server_test.go
EXACT_PATH_OVERLAP=0
SEMANTIC_REVIEW_CREDIT=preserve review 5421925331
SOURCE_CLEAR=true
P0_SOURCE=0
P1_SOURCE=0
PROVIDER_MUTATION=false
PRODUCT_ACCEPTANCE=false

No synthetic rebase/currentization is justified solely because #6 merged. The only remaining material gate is the already-declared NON_DEFERRABLE exact-head transport proof:
go test ./cmd/github-mcp-server ./pkg/http

Do not merge under #6's non-circular exception: #5's Watch disposition explicitly keeps POST_MERGE_DEFERRAL_ALLOWED=false for this credential-bearing listener property. Recompose only if GitHub later requires it after proof, preserving exact reviewed bytes.

@overdrivemh
overdrivemh merged commit bc8aaa7 into main Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant