Back to skill

Security audit

Nightly Build

Security checks for vulnerabilities and agentic risk

Overview

The skill is not clearly malicious, but it needs Review because it encourages unattended nightly maintenance with broad update and cleanup authority and contains misleading audit reporting code.

Only install this if you are comfortable with a scheduled agent running maintenance while unattended. Before enabling cron, restrict exactly which repos and paths can be updated or cleaned, disable or review any auto-update behavior, fix the npm audit fail-open reporting, and adjust the timezone to your environment.

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
scripts/nightly.ts:21
Finding
Failed dependency audits are incorrectly reported as secure## Vulnerability Details **File Location**: `scripts/nightly.ts`, lines 21–60 **Vulnerability Type**: Improper error handling and false security reporting **Risk Level**: Medium ```ts function runCmd(cmd: string, cwd: string = WORKSPACE_DIR): string { try { log(`Running: ${cmd} in ${cwd}`); const output = execSync(cmd, { cwd, encoding: 'utf-8', timeout: 60000 }); // 60s timeout return output.trim(); } catch (err: any) { const errorMsg = `Command failed: ${cmd}\nError: ${err.message}`; log(errorMsg); return `ERROR: ${errorMsg}`; } } // --- TASKS --- // 1. Skill Audit (npm audit) function auditSkills(): string { let report = "### 📦 Skill Audit\n\n"; if (!fs.existsSync(SKILLS_DIR)) { return report + "No skills directory found.\n"; } const skills = fs.readdirSync(SKILLS_DIR); let vulnerableCount = 0; for (const skill of skills) { const skillPath = path.join(SKILLS_DIR, skill); if (fs.existsSync(path.join(skillPath, 'package.json'))) { try { // Just check, don't fix automatically yet runCmd('npm audit --audit-level=high', skillPath); report += `- ✅ ${skill}: Secure\n`; } catch (e) { report += `- ⚠️ ${skill}: High vulnerabilities found!\n`; vulnerableCount++; } } } if (vulnerableCount === 0) report += "\nAll skills are clean.\n"; return report; } ``` ### Technical Analysis `execSync` throws when `npm audit --audit-level=high` exits with a nonzero status. This can occur when high-severity vulnerabilities are detected, the audit service cannot be reached, package metadata is invalid, or the command otherwise fails. The `runCmd` helper catches every such exception and converts it into an ordinary string beginning with `ERROR:`. Consequently, the `try/catch` in `auditSkills` never receives the exception. It unconditionally appends the `Secure` result without inspecting the returned value. The vulnerability counter remains zero, causing the ...[truncated 1737 chars]
Remediation
## Remediation Suggestions 1. Return a structured command result containing standard output, standard error, and exit status, or allow `execSync` exceptions to propagate to the caller. 2. Only report a skill as secure after `npm audit` completes successfully with a verified zero exit code. 3. Distinguish among these outcomes: - Audit completed with no matching vulnerabilities. - Audit completed and found vulnerabilities. - Audit could not be completed because of network, registry, timeout, configuration, or execution errors. 4. Treat audit execution failures as an unknown or failed state rather than a secure state. 5. Include enough sanitized diagnostic information in the report to support investigation without exposing credentials or sensitive environment data. 6. Add automated tests covering a zero exit status, a vulnerability-related nonzero status, a timeout, a missing executable, and a registry/network failure. A suitable design is: ```ts interface CommandResult { ok: boolean; output: string; error?: string; } function runCmd(cmd: string, cwd: string = WORKSPACE_DIR): CommandResult { try { const output = execSync(cmd, { cwd, encoding: 'utf-8', timeout: 60000 }); return { ok: true, output: output.trim() }; } catch (err: any) { return { ok: false, output: err.stdout?.toString().trim() || '', error: err.stderr?.toString().trim() || err.message }; } } const result = runCmd('npm audit --audit-level=high', skillPath); if (result.ok) { report += `- ✅ ${skill}: No high-severity vulnerabilities reported\n`; } else { report += `- ⚠️ ${skill}: Audit found vulnerabilities or could not complete\n`; vulnerableCount++; } ``` For more precise reporting, invoke `npm audit --json`, parse its structured output, and separately classify confirmed vulnerabilities and operational audit failures.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (9)

Self-Modification

High
Category
Rogue Agent
Content
- `nightly report` — Show the last nightly build report.
- `nightly run` — Trigger a manual run (for testing).
- `nightly config` — Configure tasks (update skills, check disk, etc.).

## Tasks
Confidence
92% confidence
Finding
The skill explicitly includes auto-update behavior that pulls latest changes from git repositories and mentions updating skills, which is a form of self-modification or supply-chain modification. Running this automatically and unattended can introduce unreviewed code, malicious upstream changes, or breaking updates into the agent environment, significantly increasing compromise risk.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill advertises cleanup and maintenance actions like removing temporary files, old logs, and pulling latest changes, but it does not warn users that it can modify the system or delete data. In an automated nightly context, these changes may occur unattended, increasing the chance of accidental data loss, service disruption, or unsafe cleanup behavior if the scope is too broad.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script performs a destructive filesystem operation by deleting `.log` files older than 7 days with `fs.unlinkSync`, but there is no prior warning, confirmation prompt, or explanatory comment/docstring informing users that cleanup will remove files. The deletion is only reported after it occurs, which does not satisfy a pre-action disclosure for a potentially destructive operation.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The report date and time are explicitly formatted using the `zh-CN` locale and `Asia/Shanghai` timezone, which imposes a specific language/locale setting on all users. There is no indication that this is optional, configurable, or justified as a region-specific tool.

Natural-Language Policy Violations

Low
Confidence
96% confidence
Finding
The example configuration specifies `"tz": "Asia/Shanghai"`, which imposes a specific locale setting in natural-language/config guidance. There is no indication that this timezone is optional, user-selectable, or required for a region-specific use case.

Missing User Warnings

Low
Confidence
85% confidence
Finding
The script appends operational data to a log file and later writes a generated report to disk, but there is no confirmation prompt, cautionary comment, or user-facing disclosure that local files will be created/modified. Because this is a code file, file writes that affect user workspace state should include some visible warning unless clearly documented as expected behavior.

Missing User Warnings

Low
Confidence
82% confidence
Finding
The helper executes shell commands synchronously and is used for git, npm, df, and uptime operations, but the script only logs command execution after starting rather than warning users beforehand about subprocess execution. This meets the missing-warning criterion for code files because subprocess execution can affect system state or expose environment-specific information.

Intent-Code Divergence

Low
Confidence
78% confidence
Finding
The inline comment on L049 frames the behavior as a passive check, but L050 executes `npm audit` via a shell command, which is an active operation with process-spawning side effects. While it does not auto-remediate vulnerabilities, the comment understates that code execution is occurring, creating a mild intent/documentation mismatch.

Missing User Warnings

Low
Confidence
89% confidence
Finding
The npm audit command typically contacts package registry services, and git remote update contacts configured remotes, but the script does not disclose to the user that it may perform network activity. For code files, outbound operations that transmit repository or dependency context should have some visible warning when not otherwise documented.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/nightly.mjs:23

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/nightly.ts:24