T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/render-command-skeleton.sh:49
- Finding
- PHP Code Injection Through Unsanitized Command and Class Names<![CDATA[ ## Vulnerability Details **File Location**: `scripts/render-command-skeleton.sh`, lines 49–93 **Vulnerability Type**: Generated-code injection caused by unsafe interpolation **Risk Level**: Medium ### Vulnerable Code ```bash read -r -d '' TEMPLATE <<EOF || true <?php /** * WP-CLI command skeleton for ${COMMAND_NAME}. */ class ${CLASS_NAME} { /** * Show a status report. * * ## OPTIONS * * [--format=<format>] * : Render format. * --- * default: table * options: * - table * - json * - csv * - yaml * --- * * ## EXAMPLES * * wp ${COMMAND_NAME} status * wp ${COMMAND_NAME} status --format=json * * @when after_wp_load */ public function status( \$args, \$assoc_args ) { \$items = [ [ 'key' => 'example', 'value' => 'ok', ], ]; \$format = \WP_CLI\Utils\get_flag_value( \$assoc_args, 'format', 'table' ); \WP_CLI\Utils\format_items( \$format, \$items, [ 'key', 'value' ] ); \WP_CLI::success( 'Status generated.' ); } } WP_CLI::add_command( '${COMMAND_NAME}', '${CLASS_NAME}' ); EOF ``` ### Technical Analysis The values supplied through `--command` and `--class` are inserted directly into a PHP source-code template. No validation ensures that `CLASS_NAME` is a valid PHP identifier, and no PHP-string escaping is applied before either value is placed inside single-quoted arguments to `WP_CLI::add_command()`. The shell uses quoted expansions when processing arguments and writing the output, so this is not shell command injection. The vulnerability instead affects the generated PHP artifact. An attacker-controlled value can introduce PHP syntax, terminate a quoted string or documentation comment, and append additional PHP statements. Because the generated result is intended to become a WP-CLI command file, malicious syntax can execu ...[truncated 1768 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Validate class names before rendering: - Require a valid PHP class identifier. - If namespaces are supported, validate each namespace component separately. - Reject whitespace, quotes, comment delimiters, control characters, and other PHP syntax. Example non-namespaced validation: ```bash if [[ ! "$CLASS_NAME" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]]; then echo "invalid PHP class name" >&2 exit 1 fi ``` 2. Validate WP-CLI command names using a strict allowlist: - Accept only expected command-token characters. - Validate each space-separated token independently. - Reject quotes, backslashes, PHP delimiters, newlines, and comment delimiters. For example, command tokens could be restricted to lowercase letters, digits, underscores, and hyphens. 3. Encode values placed into PHP string literals: - Do not rely only on shell quoting. - Generate PHP string literals using a dedicated escaping routine that safely handles backslashes, quotes, newlines, and control characters. - Prefer a generator implementation in PHP using a well-tested literal-encoding function where practical. 4. Avoid inserting untrusted values into PHP comments: - Sanitize or encode `*/` and control characters. - Alternatively, omit user-supplied values from generated documentation comments. 5. Add automated adversarial-input tests covering: - Single and double quotes. - Backslashes. - Newline and carriage-return characters. - `/*`, `*/`, `<?php`, and `?>`. - Semicolons, braces, parentheses, and namespace separators. - Invalid class identifiers and multi-token command names. 6. After generation, run `php -l` on the output as a secondary syntax check. This is defense in depth and must not replace strict validation and encoding. ]]>
