Security Vulnerability Report
中文
CVE-2026-41688 CVSS 7.7 HIGH

CVE-2026-41688

Published: 2026-05-07 15:16:09
Last Modified: 2026-05-07 15:45:06

Description

Wallos is an open-source, self-hostable personal subscription tracker. In versions 4.8.4 and prior, the incomplete SSRF fix in Wallos validates webhook URLs via gethostbyname() but passes the original hostname to cURL without CURLOPT_RESOLVE pinning on 10 of 11 outbound HTTP endpoints, leaving a DNS rebinding TOCTOU window. At time of publication, there are no publicly available patches.

CVSS Details

CVSS Score
7.7
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N

Configurations (Affected Products)

No configuration data available.

Wallos <= 4.8.4

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# Conceptual PoC demonstrating the DNS Rebinding attack vector # Attacker needs to control the DNS server for 'evil.com' import socket import time # Simulation of the vulnerable backend logic def vulnerable_backend_logic(target_domain): print(f"[Backend] Processing webhook for: {target_domain}") # Step 1: Time-of-Check (TOC) # Using gethostbyname() to validate the IP try: initial_ip = socket.gethostbyname(target_domain) print(f"[Backend] Validation check: {target_domain} resolves to {initial_ip}") # Check if IP is private (simplified check) if initial_ip.startswith("127.") or initial_ip.startswith("192.168."): print("[Backend] Validation Failed: Private IP detected.") return print("[Backend] Validation Passed: Public IP allowed.") except socket.gaierror: print("[Backend] DNS resolution failed.") return # TIMING WINDOW: Attacker switches DNS record here (e.g., to 127.0.0.1) # In a real attack, this is where the race condition happens. print("[Simulated Delay] ... Attacker switches DNS record ...") time.sleep(1) # Forcing a delay to simulate the gap # Step 2: Time-of-Use (TOU) # Vulnerable code passes 'target_domain' to cURL without CURLOPT_RESOLVE # Here we simulate the cURL request by resolving again try: # In the real vulnerability, cURL might resolve again or use a different cache final_ip = socket.gethostbyname(target_domain) print(f"[Backend] cURL Request sent to: {final_ip}") if final_ip != initial_ip: print(f"[EXPLOIT SUCCESS] DNS Rebinding occurred! Request hit {final_ip} instead of {initial_ip}") else: print("[Safe] IP remained consistent.") except socket.gaierror: print("[Backend] DNS resolution failed during request.") # To test this, one would need to manipulate the local hosts file or run a custom DNS server # that changes the response between the two gethostbyname calls. if __name__ == "__main__": # This is a demonstration of the logic gap, not a functional exploit against a live target # without a controlled DNS environment. pass

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-41688", "sourceIdentifier": "[email protected]", "published": "2026-05-07T15:16:09.253", "lastModified": "2026-05-07T15:45:05.947", "vulnStatus": "Deferred", "cveTags": [], "descriptions": [{"lang": "en", "value": "Wallos is an open-source, self-hostable personal subscription tracker. In versions 4.8.4 and prior, the incomplete SSRF fix in Wallos validates webhook URLs via gethostbyname() but passes the original hostname to cURL without CURLOPT_RESOLVE pinning on 10 of 11 outbound HTTP endpoints, leaving a DNS rebinding TOCTOU window. At time of publication, there are no publicly available patches."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N", "baseScore": 7.7, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "CHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 3.1, "impactScore": 4.0}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-918"}]}], "references": [{"url": "https://github.com/ellite/Wallos/commit/e87387f0ebb540cd33e6dfda7181db9db650ecef", "source": "[email protected]"}, {"url": "https://github.com/ellite/Wallos/security/advisories/GHSA-h4g7-xv3v-q73g", "source": "[email protected]"}]}}