T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/init_master.py:23
- Finding
- User-Controlled Path Traversal and File Overwrite## Vulnerability Details **File Location**: `scripts/init_master.py`, lines 23–27 **Vulnerability Type**: Path traversal leading to arbitrary file creation or overwrite **Risk Level**: Medium ### Vulnerable Code ```python config_dir = Path.home() / ".zhua" / "distributed" config_dir.mkdir(parents=True, exist_ok=True) config_file = config_dir / f"{name}.json" with open(config_file, "w") as f: json.dump(config, f, indent=2, ensure_ascii=False) ``` The value reaching this code is supplied directly through the command-line interface: ```python parser.add_argument("--name", type=str, default="zhua-master", help="实例名称") args = parser.parse_args() init_master(args.name) ``` ### Technical Analysis The user-controlled `name` value is incorporated directly into a filesystem path without validation or normalization. Python's `pathlib` does not prevent path components such as `../` from escaping the intended `~/.zhua/distributed` directory. For example, a name of `../../.config/application/settings` produces a path equivalent to: ```text ~/.zhua/distributed/../../.config/application/settings.json ``` This resolves outside the intended configuration directory. The file is then opened with mode `w`, which creates a missing file or truncates an existing file. The operation also follows a symbolic link if the selected destination is a symlink. The fixed `.json` suffix restricts the set of practical targets, but does not prevent overwriting writable JSON files or creating files in writable directories. No check confirms that the resolved destination remains beneath `~/.zhua/distributed`. ### Attack Path 1. An attacker or untrusted automation controls the `--name` argument. 2. The attacker supplies a traversal value, for example: ```bash python3 scripts/init_master.py \ --name '../../.config/application/settings' ``` 3. The script concatenates the value with the configuration d ...[truncated 1359 chars]
- Remediation
- ## Remediation Suggestions 1. Enforce a strict allowlist for instance names. If names are identifiers rather than paths, accept only a small safe character set: ```python import re if not re.fullmatch(r"[A-Za-z0-9_-]+", name): raise ValueError( "Instance name may contain only letters, digits, underscores, and hyphens" ) ``` 2. Resolve both the base directory and destination, then verify containment before writing: ```python config_dir = (Path.home() / ".zhua" / "distributed").resolve() config_dir.mkdir(parents=True, exist_ok=True) config_file = (config_dir / f"{name}.json").resolve() if config_file.parent != config_dir: raise ValueError("Invalid instance name") ``` 3. If overwriting existing configurations is not required, use exclusive creation mode (`"x"`) instead of `"w"` to prevent silent truncation. 4. Defend against symbolic-link targets. On supported platforms, open files using low-level flags such as `O_NOFOLLOW`, verify the opened file with `fstat`, and then write through the validated descriptor. 5. Create configuration files with restrictive permissions appropriate for their contents, such as mode `0600`, and use an atomic temporary-file-plus-rename strategy for legitimate updates. 6. Add tests covering `../`, absolute-path-like values, embedded separators, symlink destinations, existing files, and valid identifier names.
