CVE-2026-31881

7.7 HIGH

📋 TL;DR

CVE-2026-31881 allows unauthenticated attackers to reset the admin password in Runtipi homeserver orchestrator during a 15-minute password reset window, leading to full account takeover. This affects all Runtipi instances running versions before 4.8.0 where the password reset feature is enabled.

💻 Affected Systems

Products:
  • Runtipi
Versions: All versions prior to 4.8.0
Operating Systems: Linux
Default Config Vulnerable: ⚠️ Yes
Notes: Vulnerability exists when password reset functionality is available (default configuration).

⚠️ Manual Verification Required

This CVE does not have specific version information in our database, so automatic vulnerability detection cannot determine if your system is affected.

Why? The CVE database entry doesn't specify which versions are vulnerable (no version ranges provided by the vendor/NVD).

🔒 Custom verification scripts are available for registered users. Sign up free to download automated test scripts.

Recommended Actions:
  1. Review the CVE details at NVD
  2. Check vendor security advisories for your specific version
  3. Test if the vulnerability is exploitable in your environment
  4. Consider updating to the latest version as a precaution

⚠️ Risk & Real-World Impact

🔴

Worst Case

Complete compromise of the Runtipi instance with admin privileges, allowing attacker to deploy malicious apps, access all hosted services, and potentially pivot to other systems.

🟠

Likely Case

Unauthenticated attacker gains admin access to the Runtipi dashboard, can modify configurations, deploy/remove applications, and access sensitive data.

🟢

If Mitigated

If proper network segmentation and authentication controls are in place, impact is limited to the Runtipi instance itself.

🌐 Internet-Facing: HIGH
🏢 Internal Only: MEDIUM

🎯 Exploit Status

Public PoC: ✅ No
Weaponized: LIKELY
Unauthenticated Exploit: ⚠️ Yes
Complexity: LOW

Exploitation requires attacker to time their attack during the 15-minute reset window when a legitimate password reset request is active.

🛠️ Fix & Mitigation

✅ Official Fix

Patch Version: 4.8.0

Vendor Advisory: https://github.com/runtipi/runtipi/security/advisories/GHSA-96fm-whrc-cwg3

Restart Required: Yes

Instructions:

1. Backup your Runtipi configuration and data. 2. Update to version 4.8.0 or later using the update command in your Runtipi installation. 3. Restart the Runtipi service.

🔧 Temporary Workarounds

Disable password reset endpoint

linux

Temporarily block access to the vulnerable endpoint via firewall or reverse proxy rules

iptables -A INPUT -p tcp --dport 80 -m string --string "/api/auth/reset-password" --algo bm -j DROP
iptables -A INPUT -p tcp --dport 443 -m string --string "/api/auth/reset-password" --algo bm -j DROP

Network isolation

linux

Restrict access to Runtipi management interface to trusted IP addresses only

iptables -A INPUT -p tcp --dport 80 -s TRUSTED_IP -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -s TRUSTED_IP -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j DROP
iptables -A INPUT -p tcp --dport 443 -j DROP

🧯 If You Can't Patch

  • Disable password reset functionality entirely in Runtipi configuration
  • Implement network-level authentication (VPN, IP whitelisting) for Runtipi management interface

🔍 How to Verify

Check if Vulnerable:

Check if Runtipi version is below 4.8.0 and password reset endpoint is accessible without authentication

Check Version:

docker exec runtipi-app cat /app/package.json | grep version

Verify Fix Applied:

Confirm version is 4.8.0 or higher and test that password reset endpoint now requires proper authentication

📡 Detection & Monitoring

Log Indicators:

  • Multiple failed password reset attempts from same IP
  • Successful password reset from unexpected IP addresses
  • Admin login from new/unexpected IP addresses

Network Indicators:

  • POST requests to /api/auth/reset-password endpoint from external IPs
  • Unusual spike in traffic to authentication endpoints

SIEM Query:

source="runtipi" AND (uri_path="/api/auth/reset-password" OR event_type="password_reset")

🔗 References

📤 Share & Export