T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/gateway-create.sh:4
- Finding
- Persistent Command Injection Through Unvalidated Port Input<![CDATA[ ## Vulnerability Details **File Location**: `scripts/gateway-create.sh:4-5, 33-37, 55-57, 65-108` **Vulnerability Type**: Shell command injection through generated LaunchAgent content **Risk Level**: Critical ### Vulnerable Code ```bash INSTANCE_NAME="$1" PORT="$2" CHANNEL="$3" ``` ```bash # 1. Check whether the port is occupied if lsof -i :$PORT > /dev/null 2>&1; then echo "Port $PORT is already occupied" exit 1 fi ``` ```bash # 4. Modify the port if [ -f "$CONFIG_DIR/openclaw.json" ]; then cat "$CONFIG_DIR/openclaw.json" | jq ".gateway.port = $PORT" > "$CONFIG_DIR/openclaw.json.tmp" && mv "$CONFIG_DIR/openclaw.json.tmp" "$CONFIG_DIR/openclaw.json" fi ``` ```bash # 6. Create LaunchAgent plist cat > "$PLIST_FILE" << PLISTEOF <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>ai.openclaw.gateway-$INSTANCE_NAME</string> <key>Comment</key> <string>OpenClaw Gateway - $INSTANCE_NAME (port $PORT)</string> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>ThrottleInterval</key> <integer>1</integer> <key>Umask</key> <integer>63</integer> <key>ProgramArguments</key> <array> <string>$NODE_PATH</string> <string>-e</string> <string>require('child_process').execSync('openclaw gateway --port $PORT', {cwd: '$CONFIG_DIR', stdio: 'inherit', env: {...process.env, OPENCLAW_HOME: '$CONFIG_DIR'}})</string> </array> <key>StandardOutPath</key> <string>$CONFIG_DIR/logs/gateway.log</string> <key>StandardErrorPath</key> <string>$CONFIG_DIR/logs/gateway.err.log</string> <key>EnvironmentVariables</key> <dict> <key>HOME</key> <string>$HOME</string> <key>OPENCLAW_HOME</key> <string>$CONFIG_DIR</string> <key>OPENCLAW_GATEWAY_PORT</key> <string>$PORT</string> ...[truncated 2287 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Validate the port before any use: ```bash if ! [[ "$PORT" =~ ^[0-9]+$ ]] || (( PORT < 1 || PORT > 65535 )); then echo "Invalid port: expected an integer from 1 to 65535" >&2 exit 1 fi ``` 2. Restrict instance names to a conservative allowlist: ```bash if ! [[ "$INSTANCE_NAME" =~ ^[A-Za-z0-9_-]+$ ]]; then echo "Invalid instance name" >&2 exit 1 fi ``` 3. Do not invoke OpenClaw through Node `execSync()` or another shell. Put the executable and each argument into separate `ProgramArguments` entries: ```xml <key>ProgramArguments</key> <array> <string>/absolute/path/to/openclaw</string> <string>gateway</string> <string>--port</string> <string>18899</string> </array> ``` 4. Resolve the absolute path of the real `openclaw` executable and reject unexpected or writable replacements. 5. Generate plist files with an XML-aware mechanism rather than unescaped heredoc interpolation. 6. Validate the plist with `plutil -lint` before loading it. 7. Make auto-start an explicit opt-in operation. Creation should not silently imply persistent startup unless the user specifically requests it. ]]>
