T09 · Insecure Skill Coding Practices
- Location
scripts/scaffold-adapter.sh:87- Finding
Arbitrary Perl Code Execution Through Unsanitized Scaffold Arguments
- Content
View full analysis
Vulnerability Details
File Location:
scripts/scaffold-adapter.sh, lines 87-91
Vulnerability Type: Code injection through dynamically constructed Perl programs
Risk Level: HighVulnerable Code
bash LC_ALL=C perl -0pi -e "s#\Q@webmcp-bridge/example-adapter-template\E#${package_name}#g" "$out_dir/package.json" LC_ALL=C perl -0pi -e "s#\Qadapter-template\E#adapter-${name}#g" "$out_dir/src/index.ts" LC_ALL=C perl -0pi -e "s#\QAdapter Template\E#${display_name}#g" "$out_dir/src/index.ts" LC_ALL=C perl -0pi -e "s#\Qexample.com\E#${host}#g" "$out_dir/src/index.ts" LC_ALL=C perl -0pi -e "s#\Qhttps://example.com\E#${url}#g" "$out_dir/src/index.ts"The affected values are accepted from command-line arguments without validation or safe encoding:
bash --host) [[ $# -ge 2 ]] || fail 'missing value for --host' host="$2" shift 2 ;; --url) [[ $# -ge 2 ]] || fail 'missing value for --url' url="$2" shift 2 ;; --display-name) [[ $# -ge 2 ]] || fail 'missing value for --display-name' display_name="$2" shift 2 ;; --package-name) [[ $# -ge 2 ]] || fail 'missing value for --package-name' package_name="$2" shift 2 ;;Technical Analysis
The script embeds
package_name,display_name,host, andurldirectly into Perl source passed throughperl -e. Shell quoting does not make this safe: although the shell does not recursively evaluate syntax contained in expanded argument values, Perl subsequently parses the expanded value as part of its substitution program.An attacker-controlled value can therefore introduce Perl replacement interpolation constructs or delimiter/modifier syntax. Perl replacements support executable interpolation forms such as
${\ ... }; when the template text is matched, the embedded Perl expression can be evaluated. Because the scaffold templates are expected to contain each searched placeholder, reaching the ...[truncated 2483 chars]- Remediation
View remediation
Remediation Suggestions
Do not construct Perl programs by interpolating untrusted values into
perl -e.-
Pass replacement values through environment variables or positional arguments so they remain data:
bash PACKAGE_NAME="$package_name" \ perl -0pi -e 's/\Q@webmcp-bridge\/example-adapter-template\E/$ENV{PACKAGE_NAME}/g' \ "$out_dir/package.json"Apply the same pattern to
display_name,host, andurl. -
Prefer a structured template-rendering implementation that reads replacements from arguments and performs literal string replacement. For JSON files, use a JSON-aware tool rather than textual substitution.
-
Validate every argument according to its semantic type:
host: require a valid hostname and reject control characters, schemes, paths, and user-info.url: parse as a URL and allow only expected schemes, normallyhttps.package_name: enforce the package manager's package-name grammar.display_name: reject control characters and impose a reasonable length limit.
-
Add regression tests containing Perl metacharacters, substitution delimiters, backslashes, dollar signs, braces, newlines, and
${\...}-style strings. Tests should verify that these values are either rejected or inserted literally and never executed. -
Consider constraining
--dirto the intended repository package directory after canonicalization, particularly when the script may be invoked autonomously by an agent. -
Run scaffolding with the least-privileged account available and without unnecessary secrets in the environment. This limits impact if another injection defect is introduced later.
-
