Back to skill

Security audit

Shopify Manager

Security checks for vulnerabilities and agentic risk

Overview

This Shopify skill is mostly purpose-aligned, but it has real safety gaps around live store changes, theme permissions, and local logging of sensitive customer data.

Review carefully before installing. Use a least-privilege Shopify app token, prefer environment variables over committing a config file, avoid granting theme or refund scopes unless needed, and treat audit logs as sensitive customer data. Do not rely on dry-run alone for theme operations in this version; verify code changes or keep theme-write permissions disabled at the Shopify token level.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
src/operations/themes.py:31
Finding

Dry-run mode does not prevent destructive theme operations

Content
View full analysis
Dict: """Create a duplicate of a theme for safe editing.""" source_theme = None themes = self.get_themes() for t in themes: if t['id'] == theme_id: source_theme = t break if not source_theme: raise ValueError(f"Theme not found: {theme_id}") new_name = name or f"{source_theme.get('name')} - AI Edit {self._timestamp()}" # Duplicate the theme new_theme = self.client.duplicate_theme(theme_id, new_name) self._working_theme_id = new_theme.get('id') # Audit log self.audit.log_change('theme', new_theme.get('id'), 'duplicate', {'source_theme_id': theme_id}, new_theme) return new_theme ``` ```python def publish_theme(self, theme_id: int, force: bool = False) -> Dict: """Publish a theme (make it live).""" themes = self.get_themes() theme = None for t in themes: if t['id'] == theme_id: theme = t break if not theme: raise ValueError(f"Theme not found: {theme_id}") if theme.get('role') == 'main': return {'message': 'Theme is already live'} # Require strong confirmation for publishing if not force: print(f"\n{'='*60}") print("⚠️ PUBLISH THEME - THIS WILL MAKE CHANGES LIVE") print(f"{'='*60}") print(f"Theme: {theme.get('name')}") print(f"Theme ID: {theme_id}") print(f"\nThis will replace your current live theme.") print("All visitors to your store will see these changes immediately.") print(f"\n{'='*60}") print("Type 'publish' to proceed, or anything else to cancel:") ...[truncated 3200 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/operations/theme_settings.py:28
Finding

Theme-edit permission restrictions are bypassed by multiple mutation paths

Content
View full analysis
Dict: """Update theme settings.""" # Check if this is the live theme themes = self.client.get_themes() is_live = any(t['id'] == theme_id and t.get('role') == 'main' for t in themes) if is_live: raise ValueError( "Cannot edit live theme settings directly! " "Use 'shopify themes copy' first, then edit the copy." ) # Get current settings for backup current_settings = self.get_theme_settings(theme_id) self.safety.backup_state('theme_settings', theme_id, current_settings) # Merge new settings new_settings = self._deep_merge(current_settings, settings) # Preview changes changes = [{ 'action': f"Update theme settings for theme {theme_id}", 'details': f"Updating {len(settings)} setting groups", }] self.safety.preview_changes("Theme Settings Update", changes) if self.safety.is_dry_run(): return {'dry_run': True, 'theme_id': theme_id, 'settings': new_settings} # Save settings content = json.dumps(new_settings, indent=2) result = self.client.update_theme_asset(theme_id, 'config/settings_data.json', content) # Audit log self.audit.log_change('theme_settings', theme_id, 'update', current_settings, new_settings) return result ``` ```python def upload_theme_asset(self, theme_id: int, asset_key: str, file_path: str, force: bool = False) -> Dict: """Upload a file as a theme asset.""" path = Path(file_path) if not path.exists(): raise FileNotFound ...[truncated 3418 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/operations/orders.py:83
Finding

Audit logs persist complete Shopify order and customer records in plaintext

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unpinned dependencies allow non-reproducible package installation

Content
View full analysis
=2.31.0 pyyaml>=6.0.1 python-dateutil>=2.8.2 click>=8.1.7 colorama>=0.4.6 ``` ```bash # Install dependencies echo " Installing dependencies..." pip install -q -r requirements.txt ``` ### Technical Analysis All dependencies use open-ended lower-bound constraints. A future package version satisfying these constraints can be selected during installation even though it was not present during this audit. The setup process does not use a lock file, package hashes, an isolated virtual environment, or an explicitly trusted package index. The listed package names are conventional, and the audit found no evidence of typosquatting, a malicious package, or a suspicious external source. The risk is instead that installation is not reproducible and implicitly trusts future releases and the active Python package index configuration. Because Python package installation can execute package build and installation logic, compromise of a permitted future release or package-index resolution path could result in code execution during setup. ### Attack Path 1. A future dependency release is compromised, malicious, or unexpectedly incompatible, or package resolution is influenced through the active package-index configuration. 2. A user runs `setup.sh`. 3. `pip` selects any release satisfying the open-ended `>=` constraint. 4. Package installation or import executes code that was not included in the audited project version. 5. That code runs with the privileges of the user installing or invoking the Skill. This is a supply-chain exposure scenario; no currently malicious dependency was identified. ### Impact Assessment If dependency resolution is compromised, third-party code can execute with the installing user's local privileges. It could potentially ...[truncated 370 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (32)

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The documentation directly guides users to obtain and use a Shopify access token for a skill that can perform high-impact administrative actions. In context, this is more dangerous because the skill manages products, orders, content, files, and themes; compromise of the token would enable broad store takeover or abuse.

Content

Scanner excerpt · README.md (reported line 135)May include surrounding context.

allow_theme_edits: true

text

**Getting your access token:**
1. Go to Shopify Admin → Settings → Apps and sales channels
2. Click "Develop apps" → "Create an app"
3. Name it "AI Store Manager"

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The description emphasizes an AI-powered natural-language Shopify manager, but the code is primarily a conventional command-line admin tool with many concrete Shopify store management capabilities exposed as explicit subcommands. The 'ask' command does not actually implement AI-powered management; it mostly routes based on keywords and prints placeholders such as 'would use LLM' or 'not yet implemented.' At the same time, the code includes broad operational capabilities not reflected in the description, especially theme, media, metafield, and configuration management. This is a material description/behavior mismatch: the real primary purpose is a multi-function Shopify CLI, not mainly an AI natural-language interface.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The code clearly performs Shopify store management tasks, so it is broadly within the declared domain. However, the description is high-level and emphasizes 'AI-powered' natural-language store management, while this code chunk specifically provides direct product CRUD and inventory adjustment operations with safety controls. More importantly, the declared permissions are empty, yet the code can create, update, delete products and modify inventory—material write capabilities to Shopify resources. That is an undeclared capability/resource access mismatch under the evaluation criteria. The safety, preview, backup, and audit features are supportive, but the destructive and modifying operations are significant enough that the declaration does not accurately represent the actual behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The description claims broad AI-powered Shopify store management through natural language prompts, but this code chunk is narrowly focused on theme operations. Its core behavior is operational theme administration and asset editing, including publishing and deletion, with safety/audit wrappers. The only AI-related function is a placeholder content generator that does not actually integrate an LLM. This makes the declared purpose materially misleading: the code is not general store management, not meaningfully AI-powered, and not centered on natural-language prompt handling. The mismatch is therefore substantive.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The example configuration embeds an access_token field directly in a YAML file, which normalizes storage of highly privileged admin credentials in plaintext workspace files. In shared workspaces, backups, or accidentally committed repositories, this can lead to compromise of the Shopify store and full administrative API abuse.

Content

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

yaml
store:
  domain: "your-store.myshopify.com"
  access_token: "shpat_xxxxxxxxxxxxxxxx"  # Admin API access token
  api_version: "2024-01"

defaults:

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

max_products_per_bulk: 50

text

### Getting Your Access Token

1. Go to your Shopify Admin → Settings → Apps and sales channels
2. Click "Develop apps" → "Create an app"

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
## Security Notes

- Store access tokens securely (in `.env` or config, never commit)
- Use minimal required API scopes
- Enable dry-run mode when testing
- Review all changes before executing

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
store:
  domain: "your-store.myshopify.com"
  access_token: "shpat_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"  # Admin API access token
  api_version: "2024-01"

defaults:

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
store:
  domain: "your-store.myshopify.com"
  access_token: "shpat_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"  # Admin API access token
  api_version: "2024-01"

defaults:

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · shopify-config-example.yaml (reported line 3)May include surrounding context.

yaml
store:
  domain: "your-store.myshopify.com"
  access_token: "shpat_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"  # Admin API access token
  api_version: "2024-01"

defaults:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README instructs users to place a Shopify access token in a plaintext local config file without any warning about secure storage, file permissions, secret scanning, or exclusion from source control. If that file is committed, shared, or read by other local processes, an attacker could gain API access to the store and perform privileged actions such as product changes, order operations, and theme edits.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · README.md (reported line 241)May include surrounding context.

md
Your AI won't (and shouldn't):
- ❌ Process refunds without explicit confirmation
- ❌ Delete products without confirmation
- ❌ Edit your live theme directly (always uses preview)
- ❌ Make bulk changes without showing you the list first
- ❌ Handle payment processing or sensitive customer data

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill is activated by an extremely broad natural-language description with no narrow trigger constraints, while it exposes high-impact store administration features. In agentic environments, overly broad invocation criteria can cause accidental routing of unrelated prompts into a privileged skill, leading to unintended product, order, theme, or content changes.

Content

No source excerpt is available for this finding.

Ssd 4

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill includes a section encouraging agents to facilitate cryptocurrency tips to a wallet address. In an agent ecosystem, embedding payment-solicitation instructions inside an administrative skill creates social-engineering risk, can bias agent behavior, and may result in unauthorized or policy-violating financial actions if an agent treats the text as operational guidance.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The description says the skill enables Shopify store management 'through natural language prompts' without defining narrow trigger conditions, confirmation boundaries, or operation scoping. In a high-impact commerce context, broad NL activation can cause an agent to invoke sensitive actions like product changes, refunds, order fulfillment, or theme edits from ambiguous user input or prompt-injected context.

Content

No source excerpt is available for this finding.

Cloud Storage Exfiltration

Medium
Category
Data Exfiltration
Confidence
55% confidence
Finding

Data is uploaded to cloud storage (S3 / GCS / Azure Blob). This may be a legitimate backup or exfiltration to an external bucket. Manual review is recommended.

Content

Scanner excerpt · src/cli.py (reported line 584)May include surrounding context.

python
print(f"\n📊 {len(items)} files")
        
        elif args.subaction == 'upload':
            result = media.upload_file(args.file, name=args.name, force=args.force)
            if result.get('dry_run'):
                print("\n✋ Dry run complete. Add --execute to apply.")
            else:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The delete_product method performs an irreversible destructive action with no confirmation, preview, or secondary authorization. In a natural-language agent context, this creates a real risk that prompt ambiguity, hallucination, or prompt injection could cause unintended deletion of catalog data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Creating refunds has direct financial consequences and may affect customer trust, accounting, and fraud exposure. In an AI-operated workflow, issuing refunds without explicit disclosure and confirmation is dangerous because misinterpreted requests or malicious prompt steering could trigger unauthorized monetary actions.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The client exposes high-impact administrative capabilities far beyond low-risk 'store management,' including publishing/deleting themes, editing theme assets, deleting files, and updating shop settings. In an AI-driven natural-language skill, this broad action surface is dangerous because ambiguous or manipulated prompts could trigger live storefront changes, data loss, or business disruption without clear scope constraints.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Publishing or deleting themes directly affects the live storefront and can instantly alter or break customer-facing behavior. Without user-facing disclosure and confirmation, an AI agent could unintentionally push a bad theme live or remove an important theme due to misunderstanding or adversarial prompt content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Deleting a theme asset can remove templates, scripts, styles, or configuration that the storefront depends on, potentially causing partial outages or security-impacting behavior changes. Because the action is silent and immediate, an agent can make damaging production changes without ensuring user intent is specific and informed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The README shows fulfilling an order will also send a customer notification, but this side effect is only revealed after the action example rather than warned about up front. Because messaging customers can affect user data and customer experience, the skill description should more clearly disclose this behavior before users invoke it.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency is specified with a lower bound only, which permits installation of many different upstream releases and makes builds non-reproducible. In a store-management skill that may handle API credentials and business data, this increases supply-chain risk and makes it hard to verify whether vulnerable or breaking versions are being installed.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.31.0
pyyaml>=6.0.1
python-dateutil>=2.8.2
click>=8.1.7

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
95% confidence
Finding

Requests has multiple known advisories, and because the manifest does not pin a specific version, it is impossible to verify that deployed environments avoid affected releases. In a Shopify management skill, an HTTP client may process credentials, tokens, and admin API traffic, so unresolved package-version uncertainty is more dangerous than in a non-networked utility.

Content

No source excerpt is available for this finding.