T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/list_openapi_meta_apis.py:32
- Finding
- Path Traversal Through Unsanitized Output Filenames<![CDATA[ ## Vulnerability Details **File Location**: `scripts/list_openapi_meta_apis.py`, lines 32–33 and 57–69 **Vulnerability Type**: Path traversal and arbitrary file placement **Risk Level**: Medium ### Vulnerable Code ```python parser.add_argument("--product-code", default=DEFAULT_PRODUCT_CODE) parser.add_argument("--version", default=DEFAULT_VERSION) ``` ```python json_file = output_dir / f"{args.product_code}_{args.version}_api_docs.json" md_file = output_dir / f"{args.product_code}_{args.version}_api_list.md" json_file.write_text( json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8", ) md_lines = [ f"# {args.product_code} {args.version} API List", "", f"- Source: {url}", f"- API count: {len(api_names)}", "", ] md_lines.extend([f"- `{name}`" for name in api_names]) md_file.write_text("\n".join(md_lines) + "\n", encoding="utf-8") ``` ### Technical Analysis The `--product-code` and `--version` arguments are controlled by the script caller. Their raw values are interpolated into output filenames without character validation, filename sanitization, or verification that the resolved destination remains beneath the configured output directory. Values containing path separators or `..` components can therefore influence path resolution. The `pathlib.Path` `/` operator does not automatically prevent traversal outside a base directory. If the metadata request succeeds and the resulting destination's parent directory exists, `write_text()` may create or overwrite a file outside `output/alicloud-ai-pai-aiworkspace/`. The fixed `_api_docs.json` and `_api_list.md` suffixes constrain the names of reachable files, but they do not enforce containment within the intended output directory. ### Attack Path 1. An attacker, untrusted automation workflow, or manipulated invocation supplies a traversal-bearing value through `--product-code` or `--version`. 2. The supplied value is included in the request path sent to the fi ...[truncated 1497 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Validate both identifiers against a strict allowlist appropriate for Alibaba Cloud product codes and API versions: ```python import re SAFE_IDENTIFIER = re.compile(r"^[A-Za-z0-9._-]+$") def validate_identifier(value: str, name: str) -> str: if not SAFE_IDENTIFIER.fullmatch(value): raise ValueError(f"Invalid {name}: only letters, digits, '.', '_', and '-' are allowed") return value ``` 2. Validate the arguments before using them in either URLs or filenames: ```python product_code = validate_identifier(args.product_code, "product code") version = validate_identifier(args.version, "version") ``` 3. Resolve each output destination and enforce containment beneath the resolved output directory: ```python output_root = pathlib.Path(args.output_dir).resolve() output_root.mkdir(parents=True, exist_ok=True) json_file = ( output_root / f"{product_code}_{version}_api_docs.json" ).resolve() md_file = ( output_root / f"{product_code}_{version}_api_list.md" ).resolve() for destination in (json_file, md_file): if output_root not in destination.parents: raise ValueError("Output path escapes the configured output directory") ``` 4. Consider rejecting path separators explicitly even when additional validation is present. 5. Add regression tests covering `../`, absolute paths, platform-specific separators, encoded separators, empty values, and unexpectedly long identifiers. 6. Run the Skill under an account with minimal filesystem permissions so that a validation failure cannot become a broader workspace overwrite. ]]>
