Back to skill

Security audit

Polling Best Practices (J-Claw)

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a disclosed polling helper, but it gives agents broad background shell-execution authority with weak scoping and an unsafe executable template.

Review before installing. Use this only for trusted, user-confirmed polling tasks, avoid upstream auto-starts, replace eval-based template logic with fixed commands or allowlisted parsers, and ensure every background job has a clear timeout, owner, log location, and cancellation path.

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
scripts/poll-template.sh:17
Finding

Arbitrary Shell Command Execution Through Unsafe eval Usage

Content
View full analysis

Vulnerability Details

File Location: scripts/poll-template.sh, lines 17–25, 119, and 127
Vulnerability Type: Shell command injection
Risk Level: High

Vulnerable Code

bash
# Poll command — must return within seconds and produce parseable output
POLL_COMMAND='echo "Replace this with the actual status check command"'

# Output parsing: extract a value from POLL_COMMAND output
#   e.g., for JSON output '{"status": "completed"}', use:
#     jq -r '.status' <<< "$OUTPUT"
#   e.g., for plain text, use:
#     grep -o 'status: [a-z]*' | awk '{print $2}'
PARSE_OUTPUT='jq -r ".status" <<< "$OUTPUT"'
bash
OUTPUT=$(eval "$POLL_COMMAND" 2>&1) || {
bash
PARSED=$(eval "$PARSE_OUTPUT" <<< "$OUTPUT" 2>/dev/null) || PARSED="parse_error"

Technical Analysis

The template stores the polling operation and parsing logic as shell command strings, then executes both strings with eval. Unlike direct command invocation, eval reparses its argument as shell source code. Consequently, shell metacharacters, command substitutions, redirections, pipelines, and additional commands contained in either configured value are interpreted and executed.

The template instructs an agent to replace these values for each polling task but does not require allowlisting, validation, fixed parser selection, or safe argument-array construction. If an untrusted task request can influence POLL_COMMAND or PARSE_OUTPUT, the resulting generated polling script becomes an arbitrary command-execution channel.

Using quoted variables around eval does not prevent injection because reparsing is the intended behavior of eval.

Attack Path

  1. An attacker requests polling of a status command or output rule containing embedded shell syntax.
  2. The agent incorporates the attacker-influenced text into POLL_COMMAND or PARSE_OUTPUT.
  3. Following the documented workflow, the generated polling script is launched in the back ...[truncated 1063 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove both uses of eval.
  2. Represent executable commands as Bash arrays so arguments are not reparsed as shell syntax:
bash
POLL_COMMAND=(status-tool status --id "$TASK_ID")

if ! OUTPUT=$("${POLL_COMMAND[@]}" 2>&1); then
  log "Polling command failed"
  save_progress "$POLL_COUNT" "command_failed"
  sleep "$POLL_INTERVAL"
  continue
fi
  1. Implement parsing as a fixed function rather than a configurable shell expression:
bash
parse_status() {
  jq -er '.status | strings' <<< "$1"
}

if ! PARSED=$(parse_status "$OUTPUT" 2>/dev/null); then
  PARSED="parse_error"
fi
  1. If multiple polling tools or parsing formats must be supported, select them through a strict allowlist of identifiers and dispatch to predefined functions. Do not accept arbitrary command text.
  2. Validate all externally influenced identifiers, paths, status values, and arguments according to narrow expected formats.
  3. Reject shell control syntax in legacy string-based configurations, including command substitutions, separators, redirections, and newline characters. This should be defense in depth rather than a substitute for eliminating eval.
  4. Execute polling jobs with least privilege, a restricted environment, minimal filesystem permissions, and only the network access required for the intended status endpoint.
  5. Add security tests demonstrating that values containing shell metacharacters are treated as literal arguments and cannot create files or execute secondary commands.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (7)

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill advertises itself as guidance-only and says it does not install scripts or tools, but the body instructs the agent to create task directories, write poll.sh, and run a persistent background process. This mismatch can bypass operator expectations and policy controls, causing the agent to perform durable actions in the environment under the guise of documentation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The same guidance-only representation conflicts with concrete instructions to generate and execute poll.sh in the runtime environment. A deceptive or inaccurate manifest increases the chance that the skill is invoked in contexts that prohibit persistence or code generation, undermining trust and safety review.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
88% confidence
Finding

Allowing confirmation to be skipped when triggered by an upstream skill enables autonomous execution based solely on machine-provided parameters, including polling targets, follow-on commands, and notification actions. If the upstream trigger is wrong, compromised, or prompt-injected, the agent may launch background monitoring and downstream actions without fresh human consent.

Content

Scanner excerpt · SKILL.md (reported line 112)May include surrounding context.

直接回复修改项,或"确认"以默认参数启动。

text

**Do not begin polling until the user confirms.** If triggered by an upstream skill (agent mode), skip confirmation and use the parameters from the trigger message.

---

Session Persistence

Medium
Category
Rogue Agent
Confidence
94% confidence
Finding

Using nohup to launch poll.sh creates a process that persists beyond the current session, enabling unattended execution, repeated command invocation, and user messaging after the original context is gone. Persistence magnifies the impact of any bad command, bad parse rule, leaked identifier, or malicious upstream parameter because it continues operating without active supervision.

Content

Scanner excerpt · SKILL.md (reported line 312)May include surrounding context.

bash
# In the task's temp dir:
nohup bash poll.sh > /dev/null 2>&1 &
echo "Polling started in background (PID: $!)"

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script sends a Chinese-language failure message directly to the user, which imposes a specific language choice in user-facing output. The file does not offer language selection or document that the skill is intended only for a Chinese-speaking or region-specific context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The timeout notification is sent in Chinese, forcing a language choice on the recipient. No language preference, opt-in, or region-specific justification is present in this file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The completion message is delivered to the user in Chinese only, which violates the language/locale policy when no user choice or explicit locale limitation is provided. This is a natural-language policy issue independent of the script's functional behavior.

Content

No source excerpt is available for this finding.