Conversation
The /dashboard/api/data/resolver route accepted any HTTP URL and proxied the response verbatim. Any authenticated user could reach IMDS credential endpoints, loopback addresses, and in-cluster services. Private/loopback IP ranges are now always rejected (127.x, 10.x, 172.16-31.x, 192.168.x, 169.254.x, localhost). When the operator configures spec.devEnvironments.allowedSources.urls, the request URL must also match the allowlist. Redirects are disabled to prevent bypass via 302. Fixes: https://redhat.atlassian.net/browse/CRW-11948 Assisted-by: Claude Sonnet 4.6 Signed-off-by: Oleksii Orel <oorel@redhat.com>
Replace the private-IP example URL with a public devfile URL so Swagger UI does not advertise a request pattern that is now blocked by the SSRF fix. Assisted-by: Claude Sonnet 4.6 Signed-off-by: Oleksii Orel <oorel@redhat.com>
IPv4-mapped IPv6 addresses like [::ffff:169.254.169.254] resolve to their embedded IPv4 address at the OS level but were not caught by the hostname check introduced in the previous commit. Adds isPrivateOctets() helper and a [::ffff:XXXX:YYYY] pattern match in isPrivateHostname() to decode the embedded first two octets and apply the same private-range check. Also adds a test for the 400 path (malformed URL) and a comment in isUrlAllowed() acknowledging that non-wildcard URL chars are not regex-escaped, matching the existing frontend isSourceAllowed() behavior. Assisted-by: Claude Sonnet 4.6 Signed-off-by: Oleksii Orel <oorel@redhat.com>
|
Docker image build succeeded: quay.io/eclipse/che-dashboard:pr-1655 (linux/amd64, linux/arm64, linux/s390x) kubectl patch commandkubectl patch -n eclipse-che "checluster/eclipse-che" --type=json -p="[{"op": "replace", "path": "/spec/components/dashboard/deployment", "value": {containers: [{image: "quay.io/eclipse/che-dashboard:pr-1655", name: che-dashboard}]}}]" |
1 similar comment
|
Docker image build succeeded: quay.io/eclipse/che-dashboard:pr-1655 (linux/amd64, linux/arm64, linux/s390x) kubectl patch commandkubectl patch -n eclipse-che "checluster/eclipse-che" --type=json -p="[{"op": "replace", "path": "/spec/components/dashboard/deployment", "value": {containers: [{image: "quay.io/eclipse/che-dashboard:pr-1655", name: che-dashboard}]}}]" |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: olexii4, svor The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1655 +/- ##
==========================================
- Coverage 92.56% 92.56% -0.01%
==========================================
Files 596 596
Lines 61908 61995 +87
Branches 4874 4898 +24
==========================================
+ Hits 57305 57384 +79
- Misses 4541 4549 +8
Partials 62 62 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
What does this PR do?
Fixes an SSRF vulnerability in
POST /dashboard/api/data/resolverthat let any authenticated user proxy requests to internal addresses.Root Cause
The route passed the caller-supplied URL directly to
axios.get()with no host filtering. The operator allowlist (spec.devEnvironments.allowedSources.urls) existed inserverConfigApibut was never checked here, so loopback addresses, RFC-1918 ranges, and the cloud IMDS endpoint (169.254.169.254) were all reachable.Fix
Two guards added to
dataResolver.ts:127.x,localhost,::1,169.254.x,10.x,172.16–31.x,192.168.xwith 403 before making any outbound call.spec.devEnvironments.allowedSources.urlsis set, the URL must match an entry (exact or wildcard). Empty list keeps the existing open behavior.maxRedirects: 0prevents bypass via redirect from an allowed host.Also updated the Swagger example URL, which pointed to a private address and would now always return 403.
What issues does this PR fix or reference?
fixes https://redhat.atlassian.net/browse/CRW-11948
Is it tested? How?
Manual via Swagger:
https://<che-host>/dashboard/swagger→ Data Resolver → POST /dashboard/api/data/resolver → Try it out.{ "url": "http://127.0.0.1:8080/dashboard/devfile-registry/devfiles/index.json" }{ "url": "https://raw.githubusercontent.com/devfile-samples/devfile-sample-python-basic/main/devfile.yaml" }Release Notes
Fixed an SSRF vulnerability in the data resolver endpoint that allowed authenticated users to reach internal network addresses.
Docs PR
N/A