T09 · Insecure Skill Coding Practices
Error
- Location
- checks.sh:74
- Finding
- Automatic Execution of Project-Controlled Shell Scripts<![CDATA[ ## Vulnerability Details **File Location**: `checks.sh`, lines 23-35 and 74-85 **Vulnerability Type**: Arbitrary execution of untrusted project scripts **Risk Level**: Critical ### Code Snippet ```bash LOCAL_CHECKS_DIR="backstage/checks/local" # Collect local check basenames (for override detection) LOCAL_CHECKS="" if [ -d "$LOCAL_CHECKS_DIR" ]; then for check in "$LOCAL_CHECKS_DIR"/*.sh; do if [ -f "$check" ]; then basename_check=$(basename "$check") LOCAL_CHECKS="$LOCAL_CHECKS $basename_check " fi done fi ``` ```bash # Run local checks (always run, overrides global if same name) if [ -d "$LOCAL_CHECKS_DIR" ]; then echo " 📋 Local checks:" for check in "$LOCAL_CHECKS_DIR"/*.sh; do if [ -f "$check" ]; then basename_check=$(basename "$check") # Run check if bash "$check" >/dev/null 2>&1; then echo " ✅ $basename_check" else echo " ❌ $basename_check (failed)" CHECKS_PASS=false fi ``` ### Technical Analysis The check runner automatically executes every shell script under the target project's `backstage/checks/local/` directory. These files are controlled by the project and may therefore be supplied by any contributor with permission to add repository files. There is no script allowlist, integrity manifest, signature verification, content inspection, sandbox, or per-script execution confirmation. The scripts inherit the privileges, environment, filesystem access, network access, and credentials available to the user running the Skill. Redirecting both standard output and standard error to `/dev/null` further reduces transparency by hiding payload output and error messages. ### Attack Path 1. An attacker adds a file such as `backstage/checks/local/health.sh` to a repository. 2. The file contains arbitrary shell commands, such as commands that read credentials, alter sourc ...[truncated 918 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not automatically execute shell scripts supplied by the current project. 2. Replace executable checks with a narrowly defined declarative validation format. 3. If shell checks are unavoidable, maintain a trusted manifest containing approved paths and cryptographic hashes. 4. Display each script's path, content, and relevant version-control diff before requesting explicit execution approval. 5. Require approval separately for each newly added or modified script. 6. Execute approved checks in an isolated environment with: - Read-only project access where possible - No home-directory access - No inherited secrets or credentials - Network access disabled by default - Resource and execution-time limits 7. Do not suppress script output. Capture and clearly attribute stdout, stderr, and exit status. 8. Reject symlinks and verify that every resolved script path remains inside the intended checks directory. ]]>
