T09 · Insecure Skill Coding Practices
- Location
scripts/build_trip_plan.py:77- Finding
Markdown Content Injection Through Insufficiently Validated Image URLs and Currency Values
- Content
View full analysis
str: value = (raw or "").strip() parsed = urlparse(value) if parsed.scheme != "https" or not parsed.netloc: raise ValueError(f"--{field_name} only accepts valid HTTPS URLs.") if parsed.username or parsed.password: raise ValueError(f"--{field_name} cannot include URL credentials.") if "\n" in value or "\r" in value: raise ValueError(f"--{field_name} contains invalid newline characters.") return value ``` ```python def format_currency(amount: int, currency: str) -> str: return f"{currency} {amount:,}" ``` ```python def build_gallery(destination: str, image_urls: list[str]) -> str: if not image_urls: return "\n".join( [ "- Add at least 3 trusted HTTPS image URLs for this destination.", "- Prefer official tourism boards, museums, or your own photos.", ] ) lines = [] for idx, url in enumerate(image_urls, start=1): lines.append(f"") return "\n".join(lines) ``` ```python cover = ( f"" if args.cover_image else "Add one trusted HTTPS cover image URL." ) ``` ```python parser.add_argument( "--currency", default="CNY", help="Currency code shown in budget table (default: CNY).", ) ``` ```python if args.cover_image: args.cover_image = validate_https_url(args.cover_image, "cover-image") if args.image_url: args.image_url = [validate_https_url(url, "image-url") for url in args.image_url] ``` ### Technical Analysis The URL validator checks only that a value has an HTTPS ...[truncated 2895 chars]- Remediation
View remediation
str: value = (raw or "").strip().upper() if not re.fullmatch(r"[A-Z]{3}", value): raise ValueError("--currency must be a three-letter ISO-style currency code.") return value ``` 2. Validate image URLs for their specific Markdown context. Reject characters that can terminate or restructure a Markdown destination, including unencoded parentheses, whitespace, backslashes, and control characters. 3. Reconstruct accepted URLs from parsed components instead of returning the original untrusted string. 4. Percent-encode path, query, and fragment components where appropriate. Do not encode the URL as one opaque string because doing so can damage the scheme and host. 5. Consider using angle-bracket Markdown destinations if supported by the target renderer, while still rejecting angle brackets and control characters: ```markdown ![Caption]() ``` 6. If generated Markdown will be rendered as HTML, configure the renderer to disable raw HTML and restrict remote resource loading. 7. Add regression tests covering closing parentheses, spaces, backslashes, pipes, newlines, embedded HTML, and attempts to append secondary Markdown links or images. ]]>
