Back to skill

Security audit

Deploydevnlu

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real deployment tool, but it can make live infrastructure changes from Slack text with weak validation and no clear approval gate.

Review before installing. Only use this in a tightly controlled workspace where Slack callers are authorized to deploy, the SSH key is least-privileged, and accidental deployments are acceptable. The skill should add an exact allowlist for environments, avoid shell interpolation, map each environment to explicit infrastructure, and require confirmation before running kubectl.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
index.js:16
Finding
Shell Command Injection Through Unvalidated NLU Output<![CDATA[ ## Vulnerability Details **File Location**: `index.js:16-33` and `index.js:48` **Vulnerability Type**: OS command injection through unsafe shell interpolation **Risk Level**: High ### Vulnerable Code ```js const message = params.slack_text || ""; // ---- Step 0: 调用 LLM/NLU 解析环境 ---- let env = "dev"; // 默认环境 try { const parsed = await context.nlpParse(message, { instructions: ` 从以下自然语言消息中识别目标部署环境: 可能的值:production, staging, dev 输出 JSON 格式:{"environment":"production"} 或 {"environment":"staging"} 或 {"environment":"dev"} 示例: - "帮我把最新代码推到生产环境" -> production - "先部署到测试服务器" -> staging - "开发环境更新" -> dev ` }); if (parsed && parsed.environment) { env = parsed.environment; } } catch (err) { context.log("NLU 解析失败,使用默认 dev 环境:", err); } context.log(`解析到部署环境: ${env}`); ``` ```js output = await runCommand(`ssh supplywhy-dev-master "sed -i 's|590183820143.dkr.ecr.us-west-2.amazonaws.com/genie:.*|590183820143.dkr.ecr.us-west-2.amazonaws.com/genie:${env}|' genie/deployment.yaml"`); ``` The interpolated command is ultimately executed through `child_process.exec`: ```js const { exec } = require("child_process"); // 执行 shell 命令工具 async function runCommand(command) { return new Promise((resolve, reject) => { exec(command, (err, stdout, stderr) => { if (err) return reject(stderr || err); resolve(stdout); }); }); } ``` ### Technical Analysis The Slack-controlled value `params.slack_text` is submitted to `context.nlpParse`. The returned `parsed.environment` value is assigned directly to `env` without checking its type or enforcing the documented allowlist of `production`, `staging`, and `dev`. Instructions given to an LLM do not constitute a security boundary. Crafted natural-language input may cause the parser to return an unexpected string containing shell syntax. That string is interpolated into a nested local and remote she ...[truncated 2497 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Enforce an exact runtime allowlist** Treat the NLU output as untrusted and accept only literal supported values: ```js const allowedEnvironments = new Set(["production", "staging", "dev"]); const candidate = parsed?.environment; if (typeof candidate !== "string" || !allowedEnvironments.has(candidate)) { throw new Error("Invalid deployment environment"); } env = candidate; ``` 2. **Avoid shell-based command composition** Replace `child_process.exec` with `execFile` or `spawn` using fixed argument arrays. Do not place untrusted data inside a shell command string. 3. **Use fixed deployment mappings** Map each validated environment to predetermined image tags, hosts, namespaces, and deployment files. Do not allow an LLM response to supply arbitrary command fragments or infrastructure identifiers. ```js const deployments = Object.freeze({ dev: { imageTag: "dev", host: "supplywhy-dev-master" }, staging: { imageTag: "staging", host: "supplywhy-staging-master" }, production: { imageTag: "production", host: "supplywhy-production-master" } }); ``` 4. **Move remote deployment logic into a constrained script** Install a reviewed remote script that accepts only one validated environment argument. Grant the SSH account permission to invoke only that script, rather than providing unrestricted shell access. 5. **Apply least privilege** Restrict the SSH key and remote account to the minimum commands and files required for deployment. Limit Kubernetes RBAC permissions to the specific namespace and resources managed by this Skill. 6. **Require authorization for sensitive environments** Verify the Slack caller's identity and permissions. Production deployments should require explicit authorization or an approval workflow rather than relying solely on natural-language classification. 7. **Align implementation with documentation** `SKILL.md` describes an o ...[truncated 213 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (5)

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
The skill directly executes shell commands, adds an SSH key, connects to a remote host, edits deployment manifests, and applies Kubernetes changes, yet there is no manifest or in-code authorization boundary justifying these privileged deployment capabilities. In an agent setting, this creates a powerful remote-operation surface that can be triggered from user-controlled input and is especially risky because the skill’s stated context is absent, so the capability exposure is broader than necessary and could enable unauthorized infrastructure changes.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
The code claims to support production, staging, and dev based on NLP parsing, but all commands use the same dev SSH key and the same dev host while interpolating the parsed environment into the image tag. This mismatch can mislead operators into believing they are deploying safely to one environment while actually mutating the dev cluster/host, causing cross-environment confusion, accidental rollouts, and unsafe change management.

Missing User Warnings

High
Confidence
95% confidence
Finding
The skill performs deployment and cluster-modifying operations immediately after parsing a natural-language message, without any explicit confirmation, preview, or safety interlock. Because the trigger is free-form Slack text interpreted by NLP, benign, ambiguous, or manipulated messages could cause unintended infrastructure changes, making the operational risk significantly higher in this context.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill instructs the agent to load a specific private SSH key into the local ssh-agent, which is a credential-handling action with security implications and no guardrails around provenance, scope, or user confirmation. In an agent context, this can expose privileged infrastructure access to unintended workflows or enable lateral movement if the key is sensitive or the environment is shared/compromised.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The skill remotely edits a deployment manifest and applies it to Kubernetes on a live remote environment over SSH, but does not provide a clear safety warning, approval gate, or environmental safeguards. In practice, this enables direct operational changes from natural-language invocation, increasing the risk of unauthorized deployment changes, service disruption, or supply-chain abuse if arguments or context are manipulated.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
index.js:6