T09 · Insecure Skill Coding Practices
- Location
SKILL.md:16- Finding
Shell Command Injection Through Skill Arguments
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill has a coherent legal-document tracking purpose, but its tool commands and network fetching expose users to command injection, unrestricted URL fetching, and unsafe deletion risks.
Review before installing. Only use this skill in a constrained environment with trusted inputs, because a crafted URL or label may execute unintended shell commands, arbitrary URLs may reach internal services, fetched pages can influence the generated analysis prompt, and removing a URL can permanently delete more snapshot data than intended.
SKILL.md:16Shell Command Injection Through Skill Arguments
handler.js:58Server-Side Request Forgery Through Unrestricted URL Fetching
prompts.js:22Indirect Prompt Injection Through Remote Document Content
storage.js:127Slug Prefix Collisions Cause Overbroad Snapshot Deletion
handler.js:63Unbounded Response Buffering and Ineffective Request Timeout
The code chunk only implements HTML content extraction for likely legal text. It does not retrieve documents from remote sources, store historical snapshots, compare versions, or classify legal changes into the declared categories. While extraction could be a supporting component of a larger ToS diffing system, this chunk’s actual behavior is materially narrower than the declared end-to-end functionality, so the description does not accurately represent what this code actually does.
The code chunk only contains prompt templates and prompt-building functions for legal document comparison. It supports the semantic diffing portion of the description and matches the stated categories closely. However, the declared description also claims the skill fetches Terms of Service documents and stores snapshots, while this code does not perform any network retrieval, persistence, or snapshot management. Because those are material capabilities in the declared purpose and are absent from the supplied code chunk, this is a description-behavior mismatch.
This code chunk supports part of the declared workflow—storing snapshots of document text and tracking URLs—but it does not implement the major advertised capabilities of fetching Terms of Service documents or analyzing differences semantically across legal-risk categories. The actual behavior is limited to local file storage, hashing, retrieval, listing, and deletion of snapshots. Because the declared description presents a broader end-to-end analysis skill while the code only provides storage utilities, the description does not accurately represent what this supplied chunk actually does.
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
function buildAnalysisOutput(oldSnapshot, newSnapshot, label) {
if (!oldSnapshot) {
return prompts.buildFirstSnapshotPrompt(newSnapshot.text, label);
}
if (oldSnapshot.source_hash === newSnapshot.source_hash) {
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
function buildAnalysisOutput(oldSnapshot, newSnapshot, label) {
if (!oldSnapshot) {
return prompts.buildFirstSnapshotPrompt(newSnapshot.text, label);
}
if (oldSnapshot.source_hash === newSnapshot.source_hash) {
The remove command deletes a tracked URL and all associated snapshots immediately, with no confirmation prompt, dry-run mode, or explicit warning. In a skill whose primary value is historical legal document tracking, accidental or scripted invocation can irreversibly destroy audit history and comparison data, undermining integrity and availability of stored records.
The lockfile pins transitive dependency undici to 7.24.7, and the supplied advisory data indicates this version is affected by multiple high-severity issues including HTTP response queue poisoning, information disclosure, and response desynchronization. Because this skill fetches remote Terms of Service documents over HTTP(S), a vulnerable HTTP client in the request path is directly security-relevant and could allow malformed or attacker-controlled responses to corrupt request/response handling or leak data across requests.
The removeUrlData function irreversibly deletes matching snapshot JSON files and removes the registry entry, but provides no confirmation prompt, user-facing log, or explanatory warning. Because this is a destructive operation on stored data, the absence of any disclosure is a clear missing-warning issue.
Without declared permissions the skill's intent is opaque and cannot be validated.
The skill exposes a removal operation that deletes tracked URLs and snapshots, but the manifest provides no warning, confirmation step, or safeguard against accidental destructive use. In a legal-document tracking workflow, loss of historical snapshots can erase auditability and prevent users from proving how terms changed over time.
The code reads the TOS_DATA_DIR environment variable to change where tracked data and snapshots are stored, but there is no user-facing output, comment, or docstring disclosing that storage location can be redirected via environment configuration. This affects where user data is written and could surprise users or operators troubleshooting data handling.
This code creates directories and writes registry data to disk, but there is no confirmation prompt, log/print statement, or explanatory comment/docstring disclosing that persistent local files will be created and updated. Because file writes are a safety-relevant operation for code files, the lack of any visible user warning meets the missing-warning criterion.
The saveSnapshot function persists snapshot metadata and the full text content to local JSON files, which may include user or fetched data, yet the code contains no confirmation, visible disclosure, or explanatory comment/docstring. This is a file-write operation with potential data-retention implications, so it should be clearly disclosed to users.
The dependency uses a caret range instead of an exact version, which allows newer package releases to be installed without explicit review. This creates supply-chain risk because a compromised or breaking upstream release could be pulled into the skill during future installs, especially since this skill fetches and processes untrusted remote web content.
"description": "Fetches and semantically diffs Terms of Service documents",
"main": "handler.js",
"dependencies": {
"cheerio": "^1.0.0",
"node-fetch": "^3.3.0"
},
"engines": {
The dependency is not pinned to an exact version, so installation may resolve to different upstream releases over time. That increases supply-chain exposure if a malicious or vulnerable version of node-fetch is published, though the risk remains limited here because this file only declares the dependency and does not itself contain exploit logic.
"main": "handler.js",
"dependencies": {
"cheerio": "^1.0.0",
"node-fetch": "^3.3.0"
},
"engines": {
"node": ">=18.0.0"
Detected: suspicious.env_credential_access