Back to skill

Security audit

backstage companion

Security checks for vulnerabilities and agentic risk

Overview

This workflow skill is disclosed as an admin helper, but it can run project-provided scripts, apply unpinned remote updates, and control the editor in ways that need careful review.

Install only if you control the projects and the upstream backstage repository. Before use, review every global and local check script, treat project-local Markdown checks as untrusted input, avoid invoking it from untrusted repositories, and be aware that the update command can overwrite or delete files in checks/global despite the displayed wording.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
checks.sh:74
Finding

Automatic Execution of Project-Controlled Shell Scripts

Content
View full analysis
/dev/null 2>&1; then echo " ✅ $basename_check" else echo " ❌ $basename_check (failed)" CHECKS_PASS=false fi ``` ### Technical Analysis The check runner automatically executes every shell script under the target project's `backstage/checks/local/` directory. These files are controlled by the project and may therefore be supplied by any contributor with permission to add repository files. There is no script allowlist, integrity manifest, signature verification, content inspection, sandbox, or per-script execution confirmation. The scripts inherit the privileges, environment, filesystem access, network access, and credentials available to the user running the Skill. Redirecting both standard output and standard error to `/dev/null` further reduces transparency by hiding payload output and error messages. ### Attack Path 1. An attacker adds a file such as `backstage/checks/local/health.sh` to a repository. 2. The file contains arbitrary shell commands, such as commands that read credentials, alter sourc ...[truncated 918 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:137
Finding

Project-Controlled Markdown Can Override Agent Instructions

Content
View full analysis
Remediation
View remediation

T03 · Remote Payload Retrieval and Execution

Error
Location
update-backstage.sh:40
Finding

Unpinned Remote Scripts Are Installed and Subsequently Executed

Content
View full analysis
/dev/null || { echo "❌ Failed to clone upstream (offline or repo moved?)" ``` ```bash # Update echo "" echo "🔄 Updating checks/global/..." rsync -av --delete "$TMP_DIR/backstage/backstage/checks/global/" "$BACKSTAGE_DIR/checks/global/" >/dev/null ``` The synchronized global scripts are subsequently executed by `checks.sh`: ```bash # Run global checks (skip if local has same name) if [ -d "$GLOBAL_CHECKS_DIR" ]; then echo " 📋 Global checks:" for check in "$GLOBAL_CHECKS_DIR"/*.sh; do if [ -f "$check" ]; then basename_check=$(basename "$check") # Skip if local overrides (check if basename is in LOCAL_CHECKS string) if echo "$LOCAL_CHECKS" | grep -q " $basename_check "; then echo " ⏭️ $basename_check (local override)" continue fi # Run check CHECK_OUTPUT=$(bash "$check" 2>&1) ``` ### Technical Analysis The updater clones the mutable default branch of `https://github.com/nonlinear/backstage` without pinning an immutable commit or release. It does not verify a release signature, commit signature, cryptographic hash manifest, or trusted publisher key. Files from the clone are copied into a globally trusted checks directory. The check runner later executes every shell script in that directory. Consequently, the effective executable payload can change after the Skill package has been reviewed. Although the updater asks for confirmation, the displayed summary primarily identifies filenames and optional self-authored description c ...[truncated 1368 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
update-backstage.sh:139
Finding

Destructive Synchronization Can Delete Local Check Files

Content
View full analysis
/dev/null ``` ### Technical Analysis The updater invokes `rsync` with `--delete`, causing destination entries that are absent from the remote source to be removed. This is inconsistent with the preceding update message that describes removed upstream files as follows: ```text - $file (will be kept locally unless you delete) ``` The implementation therefore provides a misleading safety expectation. Once the user approves the broad update operation, locally retained or customized files in the selected global checks directory can be deleted. The project directory is selected using the first matching `backstage` directory returned by `find`, increasing the possibility that the operation targets a different matching directory than the user intended. ### Attack Path 1. A project contains local additions or customized files in `backstage/checks/global/`. 2. Those files are absent from the cloned upstream directory. 3. The updater reports that removed files will be kept locally. 4. The user approves the update based on that representation. 5. `rsync --delete` removes destination entries that do not exist upstream. 6. The local files are lost unless recoverable through version control or backups. ### Impact Assessment The direct impact is deletion of files inside the selected `checks/global` destination directory. This may remove local security checks, workflow controls, or uncommitted customizations. The command does not, by itself, demonstrate deletion outside that destination path. However, removal of security checks can weaken later validation and create operational disruption. ]]>
Remediation
View remediation

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:423
Finding

Forced Application Shutdown and Suppression of Completion Reporting

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill includes a remote update workflow that clones from GitHub and rsyncs content into local project directories, yet this is not reflected in the narrow anti-drift description. Remote code/content synchronization into trusted local paths materially increases supply-chain risk, especially when updates affect enforcement scripts later executed locally.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill includes a remote update workflow that clones from GitHub and rsyncs content into local project directories, yet this is not reflected in the narrow anti-drift description. Remote code/content synchronization into trusted local paths materially increases supply-chain risk, especially when updates affect enforcement scripts later executed locally.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill includes a remote update workflow that clones from GitHub and rsyncs content into local project directories, yet this is not reflected in the narrow anti-drift description. Remote code/content synchronization into trusted local paths materially increases supply-chain risk, especially when updates affect enforcement scripts later executed locally.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill includes a remote update workflow that clones from GitHub and rsyncs content into local project directories, yet this is not reflected in the narrow anti-drift description. Remote code/content synchronization into trusted local paths materially increases supply-chain risk, especially when updates affect enforcement scripts later executed locally.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

Trigger phrases such as 'good morning', 'bom dia', 'whatsup', and similar everyday language are overly broad for a skill that can execute checks, modify files, commit, push, fetch remote content, and close applications. Broad natural-language activation creates a high risk of accidental invocation during normal conversation, causing unintended privileged operations.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

Additional examples like 'what's the status', 'wrap up', and 'pause work' are ambiguous and likely to appear in ordinary dialogue. In the context of a privileged skill, ambiguous triggers amplify the chance that the agent interprets casual text as authorization to run shell scripts, alter repositories, or terminate applications.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script explicitly tells the user that files removed upstream will be kept locally unless manually deleted, but then performs rsync -av --delete, which deletes those local files. This is a direct integrity and trust violation: a user can approve the update based on false assurances and lose local files, including custom checks or safeguards, without realizing the script will remove them.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest frames the skill as a parity/health-check tool, but the body documents remote updates, file rewriting, commit/push actions, and application control. Security-sensitive behaviors hidden behind a benign description increase the chance of unsafe invocation and misinformed consent by users and automated tooling.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Quitting Visual Studio Code via osascript is an OS/application-control action unrelated to the stated anti-drift objective and can disrupt active user work. The added instruction to remain silent afterward is especially suspicious because it suppresses visibility after a state-changing action that could cause data loss or hinder user response.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The claim that the skill has no hardcoded paths and works on any project is contradicted by references to fixed absolute locations and global path execution. Misrepresenting environmental assumptions is dangerous because users may deploy it in contexts where it reads or executes from unexpected locations, weakening review and containment.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

md
**Created:** 2026-02-12
**Updated:** 2026-02-18 (v1.0.0 - modular checks/checks)
**Status:** Documentation updated, scripts pending
**Location:** `~/Documents/backstage/skills/backstage/SKILL.md`

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest says this skill is an 'Anti-drift protocol script' triggered by greeting a project to load project context with health checks. In contrast, this file presents itself as a 'Pre-Push Validation' and 'Pre-commit Check' flow, prompting the user about being 'Ready to commit and push' and reporting 'SAFE TO PUSH,' which is a materially different user-facing behavior than passive context loading or parity checking.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script executes every matching .sh file from both a user-global directory and a project-local directory, which is far broader than a passive docs/system parity check. Because this runs during the skill's startup flow, any attacker who can place or modify a script in those locations gains arbitrary code execution in the user's environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill executes arbitrary shell scripts with no confirmation, no warning, and no trust boundary checks, creating silent code-execution behavior. This is amplified by the skill metadata, which frames the feature as a benign parity/health-check utility rather than an execution mechanism, increasing the chance of unsafe use on untrusted repositories.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Running project-local shell scripts from backstage/checks/local means simply opening or using a repository can trigger repository-supplied code. In the context of an agent skill activated by a greeting-style trigger, this is especially dangerous because users may not expect code execution from untrusted project content.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The header says the script syncs local checks/global with upstream, but the implementation uses rsync --delete, which removes local files absent from upstream. This is dangerous because operators may rely on the stated behavior and unintentionally lose local customizations or security controls when running what appears to be a simple update.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill metadata presents this as a docs/system parity health-check helper, but the script actually clones a remote repository and synchronizes local files into the project. That mismatch is security-relevant because users may invoke it expecting read-only inspection, while it performs network access and modifies trusted local content, increasing the chance of unintended supply-chain changes.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

L364 says the README navigation block is the only source of truth for file locations. However, L030, L367, L429, and L486 describe using fixed global paths or filesystem search to locate backstage resources, which contradicts the exclusivity of the README-based mechanism.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The header comments describe the file as a minimal orchestrator whose intelligence lives in checks/, suggesting limited coordination behavior. However, the script contains additional intent-bearing logic in prompt_push() that frames results as 'SAFE TO PUSH' and asks whether to 'commit and push,' which goes beyond merely orchestrating checks.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.