T09 · Insecure Skill Coding Practices
- Location
scripts/copy_to_onedrive.py:96- Finding
Destination Path Escape Through Unvalidated Subdirectory
- Content
View full analysis
Vulnerability Details
File Location:
scripts/copy_to_onedrive.py, lines 96-100
Vulnerability Type: Unrestricted destination path / path traversal
Risk Level: Mediumpython subdir = args.subdir or cfg.get('ONEDRIVE_SUBDIR') or 'openclaw' onedrive_root_p = Path(onedrive_root).expanduser() dest_dir = onedrive_root_p / subdir outs = []Technical Analysis
The destination subdirectory can originate from the
--subdircommand-line argument or theONEDRIVE_SUBDIRconfiguration value. The code joins this value to the configured OneDrive root without validating whether it is absolute or contains parent-directory components.In
pathlib, joining a path with an absolute second operand discards the first operand. Consequently, a value such as/tmp/outputcausesdest_dirto resolve outside the configured OneDrive root. A relative value containing traversal components, such as../../target, can escape the root as well.The subsequent
copy_one()call creates the destination directory and writes the requested files there. The implementation therefore does not enforce its documented security boundary of copying only beneath${ONEDRIVE_ROOT}/${ONEDRIVE_SUBDIR}.Attack Path
- An attacker or untrusted caller supplies
--subdir /tmp/attacker-target,--subdir ../../target, or places an equivalent value inconfig.env. - The script constructs
dest_dirwithout validating or resolving it against the configured OneDrive root. - For an absolute value,
pathlibdiscardsonedrive_root_p; for a traversal value, the destination escapes through parent directories. copy_one()creates the escaped destination directory if necessary.- The selected source files are copied to the attacker-selected location.
Impact Assessment
Exploitation permits directory creation and file placement anywhere writable by the account running the Skill, rather than only within the configured OneDrive ...[truncated 347 chars]
- An attacker or untrusted caller supplies
- Remediation
View remediation
Remediation Suggestions
-
Reject absolute
subdirvalues withPath(subdir).is_absolute(). -
Reject
.and..path components where they could alter the intended destination. -
Resolve both paths and verify that the destination remains beneath the configured root:
python root = Path(onedrive_root).expanduser().resolve() requested = Path(subdir) if requested.is_absolute() or '..' in requested.parts: raise SystemExit('ONEDRIVE_SUBDIR must be a safe relative path') dest_dir = (root / requested).resolve() try: dest_dir.relative_to(root) except ValueError: raise SystemExit('Destination must remain within ONEDRIVE_ROOT') -
Apply the same validation regardless of whether the value originates from command-line arguments or configuration.
-
If nested subdirectories are unnecessary, restrict the value to a single safe directory name.
-
