T09 · Insecure Skill Coding Practices
- Location
scripts/run-tests.sh:150- Finding
Arbitrary Shell Command Injection Through eval-Based Command Construction
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches its Newman API-testing purpose, but its bundled runner can execute injected shell input and its installation/reporting examples carry under-scoped supply-chain and data-exposure risks.
Review before installing. Prefer a pinned release or verified package, install Newman locally with locked dependencies, and do not run scripts/run-tests.sh with untrusted arguments until the eval-based command construction is fixed. Confirm target APIs before running tests, especially production or mutating collections, and restrict/redact Newman reports and webhook notifications because they may contain sensitive API details.
scripts/run-tests.sh:150Arbitrary Shell Command Injection Through eval-Based Command Construction
README.md:48Mutable and Unverified Remote Skill Retrieval
scripts/install-newman.sh:12Unpinned npm Packages Installed Globally or Into the Current Project
scripts/security-audit.sh:15Security Audit Exits After the First Critical Finding
This is a clear mismatch. The declared purpose says the skill is for automated API testing using Newman to run Postman collections, but the code never calls Newman, never executes requests, and never performs test runs. Its primary function is security auditing of collection/environment files through grep-based pattern checks. That is a materially different purpose and capability from API test execution. While both relate to Postman artifacts, the actual behavior is a static security scanner, not an automated collection runner.
Referenced artifact was not completely inspected
- **Advanced Patterns**: See `references/advanced-patterns.md`
The README includes a GitHub Actions workflow that generates and uploads Newman HTML/XML reports as artifacts, but it does not warn that these reports can include request/response bodies, headers, environment-derived values, and other sensitive API data. In an API-testing skill, this is especially relevant because test runs commonly exercise authenticated endpoints and may capture tokens, PII, or internal service details that become broadly accessible to CI users or retained in artifact storage.
The skill describes workflows that inherently perform network activity through Newman, but it does not declare any explicit tool scope such as permissions or allowed-tools. That gap weakens governance and review because an agent could invoke network-capable behavior without clear policy boundaries, making unintended outbound requests or data exposure harder to control.
The invocation description is broad enough to trigger on generic API-testing requests without clearly limiting what systems, collections, environments, or targets may be exercised. In an agent setting, overbroad routing can cause the skill to be selected for sensitive or production-facing tasks, increasing the chance of unreviewed network actions, use of dangerous flags, or execution against unintended endpoints.
The Slack reporter example transmits test results to an external webhook, which can leak internal API metadata, endpoint names, failure details, and execution status outside the local environment. In an API-testing skill, outbound reporting is legitimate, but the lack of any warning or guardrails about external transmission, webhook trust, and redaction makes accidental data disclosure more likely.
The signing example reads a secret from environment storage and uses it in request-generation logic without cautionary guidance on credential handling. While this is common for authenticated API testing, users may copy the pattern into insecure environments, logs, shared collections, or CI jobs where secrets can be exposed or mismanaged.
The encrypted environment example processes secret-bearing files and writes a new encrypted file, but does not warn about residual plaintext exposure in source files, shell history, working directories, backups, or version control. This can create a false sense of safety where users believe encryption alone eliminates handling risk, even though plaintext secrets still exist during processing.
The decryption example decrypts an API key in-process and injects it into an Authorization header, increasing the risk of credential exposure through memory inspection, debugging output, collection exports, proxying, or requests sent to unintended endpoints. In a Newman/Postman context this is operationally plausible, but the missing warning about plaintext lifetime and transmission risk makes misuse more dangerous.
Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.
Using npx newman --version can cause npx to resolve and execute a package version that is not explicitly pinned if the local dependency is absent, stale, or manipulated through registry/configuration state. In an installation script, this creates unnecessary supply-chain risk because command execution may depend on whatever package version npx selects at runtime rather than a deterministic, locked binary.
The script constructs a shell command string from user-controlled inputs such as collection path, environment path, output directory, reporters, iterations, and timeout, then executes it with eval. eval causes the shell to re-parse the string, so crafted arguments containing command substitutions or shell metacharacters can break out of the intended Newman invocation and execute arbitrary commands. In a testing skill where users are expected to supply file paths and options, this significantly increases exploitability.
The installation section recommends running a global install script and npm install -g, both of which make system-wide changes. While the commands are shown as installation steps, the document does not explicitly warn that they will modify the user's global environment or may require elevated privileges.
Detected: suspicious.exposed_secret_literal