Skip to content

fix(middlewares): route preset fetches through safe HTTP transport (#615)#624

Merged
CybotTM merged 2 commits into
mainfrom
fix/issue-615
May 13, 2026
Merged

fix(middlewares): route preset fetches through safe HTTP transport (#615)#624
CybotTM merged 2 commits into
mainfrom
fix/issue-615

Conversation

@CybotTM

@CybotTM CybotTM commented May 13, 2026

Copy link
Copy Markdown
Member

Summary

middlewares/preset.go::loadFromURL previously fetched remote presets via http.DefaultClient.Do(req). The TLS posture was implicit (Go stdlib defaults — safe today, but untested) and inconsistent with the webhook delivery stack, which routes through middlewares.TransportFactory() in middlewares/webhook_security.go.

This PR routes preset fetches through the same TransportFactory() so the TLS / proxy posture is centrally configured and pinned by regression tests.

Changes

  • middlewares/preset.go — replace http.DefaultClient.Do(req) with &http.Client{Transport: TransportFactory()}. The request-level deadline is already set by context.WithTimeout, so no Client.Timeout is added.
  • middlewares/preset_security_test.go (new) — three regression tests:
    1. TestPresetLoader_LoadFromURL_RejectsUntrustedTLS — self-signed httptest.NewTLSServer is rejected at handshake (would fail if a permissive transport ever slips in).
    2. TestTransportFactory_SafePostureTransportFactory() does not enable InsecureSkipVerify.
    3. TestPresetLoader_LoadFromURL_UsesTransportFactoryloadFromURL actually obtains its transport via TransportFactory(). Would catch a future revert to http.DefaultClient.
  • CHANGELOG.md — entry under [Unreleased] → Security.

Behavior change

None for operators on default config. The pre-fix code already used safe TLS defaults; this change makes the contract explicit and centralizes future tuning.

Test plan

  • go test -race ./middlewares/ — passes (all existing + 3 new tests).
  • golangci-lint run --timeout=3m ./middlewares/ — 0 issues.
  • go build ./... — clean.
  • Verified the UsesTransportFactory test FAILS on pre-fix code (proves the regression guard is meaningful).

Fixes #615

`middlewares/preset.go::loadFromURL` previously called
`http.DefaultClient.Do(req)` for remote preset fetches when
`webhook-allow-remote-presets = true`. The TLS posture was implicit
(Go stdlib defaults — safe today, but untested) and inconsistent with
the webhook delivery stack, which routes through `TransportFactory()`
in `middlewares/webhook_security.go`.

Route preset fetches through the same `TransportFactory()` so the
TLS / proxy posture is centrally configured, and add three regression
tests:

- Self-signed `httptest.NewTLSServer` is rejected at handshake.
- `TransportFactory()` does not enable `InsecureSkipVerify`.
- `loadFromURL` actually obtains its transport via `TransportFactory()`
  (would catch a future revert to `http.DefaultClient`).

The request-level deadline is already set by `context.WithTimeout`,
so no `Client.Timeout` is added.

Fixes #615

Signed-off-by: Sebastian Mendel <[email protected]>
Copilot AI review requested due to automatic review settings May 13, 2026 16:03
@github-actions

github-actions Bot commented May 13, 2026

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests labels May 13, 2026
github-actions[bot]
github-actions Bot previously approved these changes May 13, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Automated approval for maintainer PR

All automated quality gates passed. See SECURITY_CONTROLS.md for compensating controls.

@github-actions

Copy link
Copy Markdown

⚠️ Mutation Testing Results

Mutation Score: 0.00% (threshold: 60%)

⚠️ Score is below threshold. Consider improving test coverage or test quality.

What is mutation testing?

Mutation testing measures test quality by introducing small changes (mutations) to the code and checking if tests detect them. A higher score means better test effectiveness.

  • Killed mutants: Tests caught the mutation (good!)
  • Survived mutants: Tests missed the mutation (needs improvement)

@codecov

codecov Bot commented May 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.34%. Comparing base (d014841) to head (f88b12b).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #624      +/-   ##
==========================================
- Coverage   87.38%   87.34%   -0.04%     
==========================================
  Files          88       88              
  Lines       10722    10723       +1     
==========================================
- Hits         9369     9366       -3     
- Misses       1112     1115       +3     
- Partials      241      242       +1     
Flag Coverage Δ
integration 87.34% <100.00%> (-0.04%) ⬇️
unittests 84.12% <100.00%> (-0.04%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request updates the remote preset fetching logic to use a centralized TransportFactory() instead of http.DefaultClient, ensuring consistent TLS verification and security posture. New regression tests have been added to verify certificate rejection and transport configuration. A review comment suggests improving performance by reusing the http.Client instance within the PresetLoader to allow for proper connection pooling.

Comment thread middlewares/preset.go

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens remote preset fetching in the middlewares package by routing HTTP(S) downloads through the same centrally configured HTTP transport used for webhook delivery, and adds regression tests to pin the intended TLS posture.

Changes:

  • Switch remote preset downloads in PresetLoader.loadFromURL from http.DefaultClient to an http.Client using TransportFactory().
  • Add security-focused regression tests ensuring TLS verification remains enforced and that loadFromURL actually uses TransportFactory().
  • Document the change in CHANGELOG.md under Security.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
middlewares/preset.go Uses TransportFactory() for remote preset HTTP requests instead of http.DefaultClient.
middlewares/preset_security_test.go Adds regression tests for TLS verification posture and transport-factory usage.
CHANGELOG.md Adds an Unreleased security note describing the transport change and new regression guards.

Comment thread middlewares/preset.go
Comment thread middlewares/preset.go
Comment thread middlewares/preset_security_test.go Outdated
Comment thread middlewares/preset_security_test.go Outdated
- Rename TestPresetLoader_LoadFromURL_RejectsUntrustedTLS to
  _PinsTLSVerificationPosture. The original name implied it was the
  #615 regression guard, but http.DefaultClient already rejects
  self-signed certs - the test passes both before and after the fix
  (test reviewer correctly flagged the framing as misleading). The
  actual regression guard is UsesTransportFactory; reflect that in
  the docstring.
- Strengthen UsesTransportFactory with an observingRoundTripper that
  proves the factory-returned transport actually serves a request,
  not just that the factory function is called. Closes the future-
  refactor gap test reviewer identified (factory called but result
  ignored).
- Migrate defer SetXxxForTest -> t.Cleanup so cleanup runs on
  t.FailNow / panic, not just on a clean return.

Signed-off-by: Sebastian Mendel <[email protected]>
@sonarqubecloud

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Automated approval for maintainer PR

All automated quality gates passed. See SECURITY_CONTROLS.md for compensating controls.

@CybotTM CybotTM added this pull request to the merge queue May 13, 2026
Merged via the queue into main with commit c1c4fc9 May 13, 2026
27 checks passed
@CybotTM CybotTM deleted the fix/issue-615 branch May 13, 2026 18:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Preset loader uses http.DefaultClient for remote URL fetch — no explicit TLS posture

2 participants