Skip to content

Feat: ConfigMap-driven workflow HTTP denylist and SSRF hardening - #235

Open
roguepikachu wants to merge 9 commits into
kubevela:mainfrom
roguepikachu:fix/ssrf-http-guard
Open

Feat: ConfigMap-driven workflow HTTP denylist and SSRF hardening#235
roguepikachu wants to merge 9 commits into
kubevela:mainfrom
roguepikachu:fix/ssrf-http-guard

Conversation

@roguepikachu

@roguepikachu roguepikachu commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Description of your changes

Adds ConfigMap-driven HTTP denylist support on top of the default private-address / SSRF hardening for workflow HTTP requests (request / provider http).

Controllers can load a denylist ConfigMap (denyHosts, denyCIDRs) at startup, watch it for updates, and fail closed on missing/invalid ConfigMaps when the flag is set. Also includes a startup fix so the initial load uses the API reader instead of the cache client (cache is not ready before mgr.Start).

Helm wiring:

  • workflow.disableWorkflowHTTP
  • workflow.blockPrivateHTTPAddresses
  • workflow.httpDeny.configMapName

I have:

  • Read and followed KubeVela's contribution process.
  • Related Docs updated properly. In a new feature or configuration option, an update to the documentation is necessary.
  • Run make reviewable to ensure this PR is ready for review.
  • Added backport release-x.y labels to auto-backport this PR if necessary.

How has this code been tested

  • Unit tests for pkg/utils/httpguard and HTTP provider deny-host paths.
  • k3d pair with KubeVela mainline (fix/ssrf-workflow-http-guard): controllers Ready, ConfigMap reload logged, WorkflowRun to http://blocked.example.com/path failed with blocked SSRF host: blocked.example.com.

Special notes for your reviewer

  • Merge this first. KubeVela main and the release backports depend on a published workflow revision that includes these commits.
  • Companion KubeVela PR will follow after maintainers cut a private fork / publishable workflow SHA if needed for the CVE timeline.
  • Related release PRs (after this lands / is tagged as needed):
    • release-0.6 backport for KubeVela 1.9
    • pin-based branch for KubeVela 1.10 (v0.6.3-0.20250717221743-56b80cee4121)

Summary by cubic

Adds default SSRF hardening for workflow HTTP requests with a ConfigMap-driven denylist and strict provider-level enforcement, plus Helm feature gates and a validated CUE ConfigTemplate. Also fixes Docker image builds by including the new HTTP deny wiring.

  • New Features

    • pkg/utils/httpguard: blocks link-local and cloud-metadata by default; pre-checks URL host and revalidates redirects; always validates dials (overrides DialContext, wraps custom DialTLSContext) via net.Dialer.Control; disables inherited HTTP proxy; normalizes trailing-dot FQDNs and IPv6 zone IDs; parser rejects schemes/ports/paths/whitespace.
    • ConfigMap denylist (denyCIDRs, denyHosts, supports *.suffix): loaded at startup via API Reader; hot-reloaded; startup fails closed on missing/invalid; later invalid updates keep last good. Configured via --workflow-http-deny-configmap-name; controller namespace from POD_NAMESPACE (defaults to vela-system).
    • Provider integration (pkg/providers/http): SecureTransport enforces policy; DisableWorkflowHTTP blocks all requests; BlockPrivateHTTPAddresses adds RFC1918/ULA blocking; URL host and each redirect are revalidated. Helm values: workflow.disableWorkflowHTTP, workflow.blockPrivateHTTPAddresses, workflow.httpDeny.configMapName.
    • Validated config template: charts/vela-workflow/config-templates/workflow-http-deny.cue with usage in config-templates/README.md; raw ConfigMap remains supported.
  • Bug Fixes

    • Dockerfiles copy cmd/http_deny.go and build from ./cmd to fix image build failures.

Written for commit b2ce418. Summary will update on new commits.

Review in cubic

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 13 files

Tip: instead of fixing issues one by one fix them all with cubic

Re-trigger cubic

Comment thread pkg/utils/httpguard/transport.go Outdated
Comment thread pkg/utils/httpguard/policy.go
Comment thread pkg/utils/httpguard/policy.go Outdated
Comment thread pkg/utils/httpguard/transport.go Outdated
Comment thread pkg/utils/httpguard/deny_config.go
Comment thread pkg/utils/httpguard/transport.go Outdated
Comment thread pkg/utils/httpguard/deny_source_test.go
@roguepikachu
roguepikachu force-pushed the fix/ssrf-http-guard branch from 3910b2d to 933aca6 Compare July 8, 2026 18:58
@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 27.01754% with 208 lines in your changes missing coverage. Please review.
✅ Project coverage is 24.70%. Comparing base (d7db9c4) to head (b2ce418).
⚠️ Report is 19 commits behind head on main.

Files with missing lines Patch % Lines
pkg/utils/httpguard/deny_config.go 0.00% 68 Missing ⚠️
pkg/utils/httpguard/deny_source.go 24.35% 56 Missing and 3 partials ⚠️
pkg/utils/httpguard/policy.go 38.94% 35 Missing and 23 partials ⚠️
pkg/providers/http/http.go 31.57% 9 Missing and 4 partials ⚠️
pkg/utils/httpguard/transport.go 60.00% 6 Missing and 4 partials ⚠️

❌ Your patch check has failed because the patch coverage (27.01%) is below the target coverage (70.00%). You can increase the patch coverage or adjust the target coverage.

❗ There is a different number of reports uploaded between BASE (d7db9c4) and HEAD (b2ce418). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (d7db9c4) HEAD (b2ce418)
unit-test 1 0
Additional details and impacted files
@@             Coverage Diff             @@
##             main     #235       +/-   ##
===========================================
- Coverage   62.49%   24.70%   -37.80%     
===========================================
  Files          62       68        +6     
  Lines        4415     5510     +1095     
===========================================
- Hits         2759     1361     -1398     
- Misses       1324     3884     +2560     
+ Partials      332      265       -67     
Flag Coverage Δ
e2etests 24.70% <27.01%> (?)
unit-test ?

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

☔ View full report in Codecov by Harness.
📢 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.

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 13 files

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread pkg/utils/httpguard/transport.go
Comment thread pkg/utils/httpguard/policy.go Outdated
Comment thread pkg/utils/httpguard/deny_config.go
Comment thread pkg/utils/httpguard/deny_config.go
@cursor
cursor Bot force-pushed the fix/ssrf-http-guard branch 3 times, most recently from 9acd124 to b77515e Compare July 8, 2026 19:42
@roguepikachu
roguepikachu force-pushed the fix/ssrf-http-guard branch 3 times, most recently from 16f14aa to ba58efb Compare July 10, 2026 11:54

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 3 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread charts/vela-workflow/config-templates/README.md
@roguepikachu
roguepikachu force-pushed the fix/ssrf-http-guard branch from 43b237b to 4436c7d Compare July 17, 2026 06:52
roguepikachu and others added 9 commits July 29, 2026 19:10
Move outbound HTTP guard and gate logic into workflow provider, add disable/private-block feature gates, and expose toggles via the vela-workflow Helm chart.

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Support CIDR/IP/hostname/wildcard deny entries, load and watch deny policy from a namespaced ConfigMap, and enforce host plus dial-time blocks in workflow HTTP provider and chart wiring.

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Cache client is not ready before mgr.Start, so initial denylist load must use the API reader.

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Always dial through Control validation instead of delegating to a preset
DialContext, wrap custom DialTLSContext hooks, reject port-qualified deny
hosts, normalize trailing-dot FQDNs and IPv6 zone IDs, and reset global
deny state in tests.

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Rename unused controlFunc network parameter to satisfy revive, and add
unit tests for denylist reload handlers, policy edge cases, controller
namespace resolution, and BlockPrivateHTTPAddresses HTTP gating.

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Extract configureWorkflowHTTPDeny for cmd tests and cover watchAndReload
informer registration paths so codecov patch clears the 70% threshold.


Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Disable inherited HTTP proxy on guarded transport, copy ExactHosts map in
MergeDeny to avoid mutating caller state, and reject denylist entries
with paths, schemes, ports, or whitespace at parse time.


Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
The HTTP deny wiring was extracted to cmd/http_deny.go for unit tests,
but Dockerfiles only copied cmd/main.go so image builds failed with an
undefined configureWorkflowHTTPDeny symbol.

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Ship a reusable ConfigTemplate so denylist entries can be validated while preserving the existing ConfigMap contract and live reload behavior.

Signed-off-by: roguepikachu <65535504+roguepikachu@users.noreply.github.com>
@roguepikachu
roguepikachu force-pushed the fix/ssrf-http-guard branch from 4436c7d to b2ce418 Compare July 29, 2026 13:44
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