T09 · Insecure Skill Coding Practices
- Location
scripts/sync.py:35- Finding
Overlapping synchronization paths can cause source-file deletion
- Content
View full analysis
Vulnerability Details
File Location:
scripts/sync.py, lines 35–50, 61–68, 93–96, and 130–140
Vulnerability Type: Missing source and destination path-separation validation
Risk Level: HighVulnerable Code
python def sync_mirror(source, target, exclude=None, dry_run=True, delete=False): source_path = Path(source) target_path = Path(target) exclude = exclude or [] if not source_path.exists(): print(f"Error: source directory does not exist: {source}") return target_path.mkdir(parents=True, exist_ok=True) stats = {'copied': 0, 'updated': 0, 'deleted': 0, 'skipped': 0} source_files = {} for file_path in source_path.rglob('*'): if file_path.is_symlink(): continue if file_path.is_file() and not should_exclude( file_path, exclude, base_path=source_path): rel_path = file_path.relative_to(source_path) source_files[rel_path] = file_path target_files = {} for file_path in target_path.rglob('*'): if file_path.is_symlink(): continue if file_path.is_file() and not should_exclude( file_path, exclude, base_path=target_path): rel_path = file_path.relative_to(target_path) target_files[rel_path] = file_pathpython if delete: for rel_path, tgt_file in target_files.items(): if rel_path not in source_files: actions.append(('delete', None, tgt_file))python for action, src, tgt in actions: try: tgt.parent.mkdir(parents=True, exist_ok=True) if action == 'copy': shutil.copy2(src, tgt) stats['copied'] += 1 elif action == 'update': shutil.copy2(src, tgt) stats['updated'] += 1 elif action == 'delete': tgt.unl ...[truncated 2756 chars]- Remediation
View remediation
Remediation Suggestions
-
Canonicalize both paths before creating or scanning the target:
python source_path = Path(source).expanduser().resolve(strict=True) target_path = Path(target).expanduser().resolve(strict=False) -
Reject identical and overlapping paths:
python if source_path == target_path: raise ValueError("Source and target must be different directories") if source_path in target_path.parents or target_path in source_path.parents: raise ValueError("Source and target directories must not overlap") -
Revalidate every destination immediately before copying, updating, or deleting. Ensure the resolved path remains beneath the intended target root:
python resolved_target = tgt.resolve(strict=False) if resolved_target != target_path and target_path not in resolved_target.parents: raise ValueError(f"Target escapes synchronization root: {tgt}") -
Do not create the target until path-overlap validation succeeds.
-
For deletion mode, produce a complete deletion manifest rather than truncating the preview to the first twenty operations. Require a separate explicit confirmation for deletions.
-
Add automated tests for equal paths, source-inside-target, target-inside-source, relative paths,
..components, and overlapping paths reached through symlinks.
-
