Back to skill

Security audit

DevTeam Command

Security checks for vulnerabilities and agentic risk

Overview

This skill appears intended to run a coding-agent pipeline, but it is too broadly scoped for a long-running workflow that can modify code.

Use this only when you explicitly want a full multi-agent coding workflow for a clearly scoped repository task. Avoid concurrent runs, review all code changes manually, and do not rely on the advertised fixer or docs outputs unless you confirm they were actually produced.

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

Warning
Location
index.ts:52
Finding
Subagent Status Confusion Caused by Reusable Labels<![CDATA[ ## Vulnerability Details **File Location**: `index.ts`, lines 52–67 **Vulnerability Type**: Improper subagent identity validation **Risk Level**: Medium ### Vulnerable Code ```typescript const status = await subagents({ action: 'list', recentMinutes: 60, }) const agent = status.recent?.find((a: any) => a.label === label && a.status === 'done' ) if (agent) { console.log(`✅ ${label} completed`) return agent } const failed = status.recent?.find((a: any) => a.label === label && a.status === 'failed' ) ``` ### Technical Analysis `sessions_spawn` returns a unique `childSessionKey`, but the pipeline does not use that identifier while waiting for completion. Instead, `waitForAgent` searches every subagent reported within the preceding 60 minutes and accepts the first session whose reusable label and status match. The pipeline repeatedly uses predictable labels such as `planner`, `pm`, `coder`, `tester`, `fixer`, and `reporter`. Consequently, a stale session or a concurrently running pipeline with the same label can satisfy the lookup. The waiting code may then treat an unrelated session as the stage it just spawned. This is a time-of-check and identity-confusion flaw. The code verifies a mutable, non-unique display label rather than the immutable identifier returned when the relevant subagent was created. ### Attack Path 1. An attacker with the ability to start subagents in the same observable environment, or another concurrent pipeline invocation, starts an agent using a predictable label such as `planner`. 2. That unrelated agent reaches the `done` or `failed` state while remaining within the `recentMinutes: 60` query window. 3. A victim invokes `spawnDevTeam`, which starts its own agent with the same label. 4. `waitForAgent` lists recent subagents and searches only by label and status. 5. The unrelated agent is selected before the victim's newly spawned agent has completed. 6. The pipeline incorrectly advances to the next stage or t ...[truncated 1081 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Capture the `childSessionKey` returned by `sessions_spawn` and pass it directly to `waitForAgent`. 2. Match status records using that immutable session key rather than the human-readable label. 3. If the status API cannot filter by session key, generate invocation-scoped, cryptographically unpredictable labels and verify all available identity fields. 4. Avoid searching a broad 60-minute global session window when waiting for one known child session. 5. Record the expected session identifier, creation time, pipeline invocation ID, and role, then validate all of them before accepting a terminal status. 6. Add concurrency tests that launch multiple pipelines with identical role names and confirm that each pipeline waits only for its own children. 7. Reject ambiguous results instead of selecting the first matching label. A hardened design would resemble: ```typescript async function spawnAgent(agent: DevTeamAgent) { return sessions_spawn({ label: agent.label, task: agent.task, model: agent.model, mode: 'run', runtime: 'subagent', }) } async function waitForAgent(childSessionKey: string, timeout: number) { const startTime = Date.now() while (Date.now() - startTime < timeout) { const status = await subagents({ action: 'list', recentMinutes: 60, }) const agent = status.recent?.find( (candidate: any) => candidate.childSessionKey === childSessionKey ) if (agent?.status === 'done') { return agent } if (agent?.status === 'failed') { throw new Error(`Subagent ${childSessionKey} failed`) } await new Promise(resolve => setTimeout(resolve, 30000)) } throw new Error(`Subagent ${childSessionKey} timed out`) } ``` Each pipeline stage should call `waitForAgent` with the exact identifier returned by its corresponding `spawnAgent` call. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Vague Triggers

Medium
Confidence
97% confidence
Finding
The description says the skill can be used 'anytime' and 'for any coding task,' which creates an overly broad activation scope. In agent environments, this can cause unintended invocation on general development requests, expanding access to multi-step automation when the user may not have explicitly requested it.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The 'Call Anytime' quick-start phrasing reinforces ambiguous triggering and lacks boundaries around when the pipeline should run. This increases the chance that an orchestrator or downstream agent interprets ordinary coding discussion as authorization to launch a costly or privileged workflow.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The skill sends multiple natural-language task prompts in Vietnamese (for planner, PM, coder, tester, fixer, and reporter) while the surrounding interface and usage example are in English. This imposes a specific language on downstream agent behavior without user opt-in or justification, which matches the language/locale policy violation criteria.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The pipeline claims it will run a fixer stage when the tester finds bugs, but getAgentOutput() always returns null, making the fixer branch unreachable. This creates a false sense of automated remediation and can leave known defects unaddressed while still reporting the pipeline as complete.

Vague Triggers

Low
Confidence
88% confidence
Finding
The reuse section encourages repeated invocation 'anytime' without contextual or authorization constraints. While not directly malicious, it normalizes unconditional reuse and can contribute to accidental executions, unnecessary resource consumption, or workflow sprawl.

Intent-Code Divergence

Low
Confidence
87% confidence
Finding
The success message instructs users to check docs/ for PLAN.md, TASKS.md, BUGS.md, and RELEASE.md, but this code never creates, reads, or confirms those artifacts exist. That mismatch can mislead operators into trusting outputs that were never produced, reducing auditability and masking pipeline failures.

Static analysis

No suspicious patterns detected.