T09 · Insecure Skill Coding Practices
- Location
scripts/cli-builder.sh:165- Finding
Executable Code Injection Through Unsanitized Template Parameters
- Content
View full analysis
Vulnerability Details
File Location:
scripts/cli-builder.sh, lines 165-170
Vulnerability Type: Code injection in generated source code
Risk Level: MediumThe
commandgenerator embeds caller-controlled command names and descriptions directly into Python source code without validating identifiers or escaping string literals.python print('sub = subparsers.add_parser("{}", help="{}")'.format(cmd, desc)) print('sub.add_argument("--flag", type=str, help="Flag description")') print('sub.set_defaults(func=handle_{})'.format(cmd.replace("-", "_"))) print("") print("def handle_{}(args):".format(cmd.replace("-", "_"))) print(' """{}"""'.format(desc))Technical Analysis
The
cmdanddescvariables originate from command-line arguments and are transferred through environment variables before being interpolated into executable source templates. Replacing hyphens incmddoes not make it a valid or safe Python identifier, whiledescreceives no escaping at all.An attacker can close the generated string literal and append arbitrary Python statements. For example, a description resembling:
text "); __import__("os").system("id"); #causes the generator to emit code equivalent to:
python sub = subparsers.add_parser("serve", help=""); __import__("os").system("id"); #")The injected statement executes when the generated Python program reaches that line. Similar unsafe interpolation patterns also occur elsewhere in the same script for generated JavaScript, Bash, Go, argument definitions, and interactive prompts.
The generator only prints templates and does not automatically execute the generated payload. Exploitation therefore depends on a user copying, saving, or otherwise using the generated output as executable source code. This remains significant because
SKILL.mdexplicitly describes the output as “copy-paste ready.”Attack Path
- An attacker supplies a c ...[truncated 1161 chars]
- Remediation
View remediation
Remediation Suggestions
- Validate command names and generated identifiers using strict, language-specific allowlists. For Python identifiers, require a pattern such as
^[A-Za-z_][A-Za-z0-9_]*$after intentional normalization. - Serialize user-controlled string literals rather than placing them between manually constructed quotes. For Python output, use
repr()or another trusted literal encoder. - Use an appropriate serializer for each target language, such as
json.dumps()for JavaScript string values. Do not reuse one language's escaping rules for another language. - For Bash output, strictly validate names used as variables or case patterns and safely quote all data values. Reject shell metacharacters rather than attempting incomplete substitutions.
- Keep identifiers and textual literals as separate template types. Identifiers should be validated; literals should be encoded.
- Reject embedded line breaks, control characters, braces, quotes, command substitutions, and statement separators where they are not explicitly supported.
- Add regression tests with adversarial values containing quotes, backslashes, newlines, semicolons, shell substitutions, comment markers, and invalid identifiers.
- Do not characterize generated output as “copy-paste ready” until every supported language path applies correct validation and escaping.
- Validate command names and generated identifiers using strict, language-specific allowlists. For Python identifiers, require a pattern such as
