Back to skill

Security audit

uStack

Security checks for vulnerabilities and agentic risk

Overview

This update-tracking CLI is mostly coherent, but it needs review because crafted inputs or local manifests could make it write outside its workspace or run unintended shell commands.

Install only after reviewing the implementation or applying fixes for identifier validation, manifest validation, and shell-safe git invocation. Use it only on trusted repositories, avoid automated update jobs with elevated permissions, and review generated Markdown before publishing it to a site.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
src/commands/import.js:19
Finding

Path Traversal Through Unvalidated Upstream Identifiers

Content
View full analysis
[--name ]'); console.error('Example: ustack import https://github.com/garrytan/gstack --name gstack'); process.exitCode = 1; return; } if (!upstreamId) { upstreamId = repoUrl.split('/').pop().replace(/\.git$/, ''); } const upstreamDir = getUpstreamDir(cwd, upstreamId); const repoDir = path.join(upstreamDir, 'repo'); ``` ```js // src/lib/fs.js:30-44 export function getUstackDir(cwd) { return path.join(cwd, '.ustack'); } export function getUpstreamDir(cwd, upstreamId) { return path.join(getUstackDir(cwd), 'upstreams', upstreamId); } export function getRunDir(cwd, upstreamId, timestamp) { return path.join(getUstackDir(cwd), 'runs', upstreamId, timestamp); } export function listRunDirs(cwd, upstreamId) { const runsBase = path.join(getUstackDir(cwd), 'runs', upstreamId); if (!fileExists(runsBase)) return []; return fs.readdirSync(runsBase).sort().reverse(); } ``` ```js // src/commands/publish.js:65-67 const siteDir = path.join(cwd, '.ustack', 'site', 'updates', upstreamId); const slugDate = analysis.analyzedAt.split('T')[0]; const sitePagePath = path.join(siteDir, `${slugDate}-${analysis.toShaShort}.md`); writeText(sitePagePath, page); ``` ### Technical Analysis The value supplied through `--name` or as an upstream command identifier is used directly as a filesystem path component. No validation rejects absolute paths, path separators, `.` or `.. ...[truncated 1841 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/lib/git.js:51
Finding

Shell Command Injection Through Manifest-Controlled Git Revisions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/commands/publish.js:92
Finding

Unescaped Upstream Metadata in Website-Ready Markdown and YAML

Content
View full analysis
0) { lines.push('### Notable Commits'); lines.push(''); for (const c of analysis.commits.slice(0, 8)) { lines.push(`- \`${c.shortSha}\` — ${c.subject}`); } ``` ```js // src/commands/publish.js:207 lines.push(`_Analyzed by [uStack](https://agi.security) · ${date} · [${analysis.repoUrl}](${analysis.repoUrl})_`); ``` ### Technical Analysis The generated reports incorporate data controlled by imported repositories or command arguments, including: - Commit subjects - Repository URLs - Upstream identifiers - Changed filenames - README and other documentation content These values are inserted ...[truncated 1963 chars]
Remediation
View remediation
` elements, Markdown links, quotes, newlines, and YAML tags. ]]>
Vulnerability Patterns
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The code supports only a narrow import/sync workflow: it parses a repo URL, clones or updates the upstream repository, gathers tags, detects some key files and high-level structure, writes a manifest, and saves a README snapshot. While this partially aligns with the declared 'import' aspect, it does not implement the broader core claims in the description: tracking/analyzing every change, portability classification, or generating adapted outputs for Claude Code, Codex, OpenClaw, Gemini CLI, Cursor, etc. The primary purpose of this chunk is upstream repository import and metadata capture, so the declared description materially overstates what this code actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The description presents a broad, universal update/compatibility engine for multiple agent ecosystems, including tracking upstream changes and generating adapted outputs for different runtimes. The supplied code chunk is much narrower: it extracts structure from a gstack repository into an intermediate representation by reading local files such as SKILL.md and ARCHITECTURE.md, inferring a workflow graph, install methods, a browser daemon service, and basic portability hints. While portability classification is partially present and the code does analyze one upstream repo format, the primary purpose is a gstack extractor, not a universal cross-platform update engine. Therefore the declared description materially overstates the implemented behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The import command accepts a remote repository URL and clones it locally, but the skill description does not warn users that this performs network access and writes artifacts under .ustack/. In an agent context, hidden side effects reduce informed consent and can lead users to trigger pulls from untrusted repositories, increasing supply-chain and workspace contamination risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The all-in-one update command bundles import, analysis, and publish, which implies network fetches and multiple local writes, but the documentation does not clearly disclose those side effects. In a skill designed for agent workflows and cron usage, this is more dangerous because automated invocation can repeatedly pull remote changes and modify local workspace state without prominent user awareness.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code emits the natural-language label "Host-specific (Claude Code)" in generated analysis output. That hard-codes a specific platform/vendor framing in user-facing text without offering a choice or documenting why that constraint is required, which fits the policy category for natural-language locale/platform specificity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

This extractor assigns a bootstrap command (./setup) and earlier records install steps that tell the user to run setup commands, but the file contains no user-facing warning, confirmation, or disclosure about executing repository-provided scripts. Because running setup scripts can change the system state, this is a safety-relevant operation under the missing-warnings rule for code files.

Content

No source excerpt is available for this finding.