Back to skill

Security audit

Shopify Order Management

Security checks for vulnerabilities and agentic risk

Overview

This is a legitimate Shopify automation skill, but it needs review because its public webhook can accept unauthenticated order data and the workflows handle customer PII and automated emails without enough safeguards.

Review before installing. Do not enable the public webhook or customer recovery emails until webhook verification fails closed using the raw request body, email content is escaped and recovery URLs are validated, and you have clear privacy, retention, access-control, opt-out, and deduplication rules for customer data.

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
workflows/01-new-order-handler.json:23
Finding

Webhook authentication fails open when the signature or secret is absent

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
workflows/01-new-order-handler.json:176
Finding

Unescaped Shopify and webhook data is interpolated into HTML email bodies

Content
View full analysis
New Order Received
Order#{{ $json.order_number }}
Customer{{ $json.customer_name }}
Email{{ $json.customer_email }}
Total{{ $json.currency }} {{ $json.total_price }}
Payment{{ $json.financial_status }}
Items{{ $json.items_summary }}
Shipping{{ $json.shipping_address }}
``` Low-stock table construction: ```javascript let alertHtml = ''; for (const item of lowStock) { const color = item.inventory_quantity <= 0 ? 'red' : 'orange'; alertHtml += ``; } alertHtml += '
ProductVariantSKUStockPrice
${item.product_title}${item.variant_title}${item.sku}${item.inventory_quantity}${item.price}
'; ``` Abandoned-cart email: ```html =

Hi {{ $json.customer_name }},

We noticed you left some items in your cart:

Items: {{ $json.items }}

Total: {{ $json.currency }} {{ $json.total_price }}

Your cart is still saved! Complete your purchase here:

Complete Your ...[truncated 2863 chars]

Remediation
View remediation
`, `"`, and `'`. 2. Use a template system that escapes interpolated values by default rather than assembling HTML in n8n code nodes. 3. Keep intentional markup, such as table structure and `
` separators, separate from untrusted product names and customer values. 4. Parse recovery links with a URL parser and enforce: - The `https:` scheme. - An approved Shopify or store hostname. - No embedded username or password. - Rejection of malformed, empty, or unexpected URLs. 5. Consider generating both plain-text and sanitized HTML versions of each message. 6. Add test cases containing HTML tags, quotes, entity sequences, links, images, and malformed URLs in every Shopify-derived field. 7. Fix the webhook authentication flaw so arbitrary remote users cannot directly supply notification content. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
workflows/04-abandoned-cart-recovery.json:51
Finding

Abandoned-cart recovery lacks deduplication and send-state tracking

Content
View full analysis
{ if (!c.email) return false; if (c.completed_at) return false; // Already completed const createdAt = new Date(c.created_at); return createdAt <= oneHourAgo && createdAt >= oneDayAgo; }); if (abandoned.length === 0) { return [{ json: { skip: true, message: 'No abandoned carts to recover' } }]; } return abandoned.map(c => ({ json: { email: c.email, customer_name: c.shipping_address ? `${c.shipping_address.first_name || ''} ${c.shipping_address.last_name || ''}`.trim() : 'there', total_price: c.total_price || '0', currency: c.currency || 'USD', items: (c.line_items || []).map(i => `${i.title} x${i.quantity}`).join(', '), abandoned_url: c.abandoned_checkout_url || '', created_at: c.created_at } })); ``` Every returned item is passed to the email node: ```json { "sendTo": "={{ $json.email }}", "subject": "=You left something behind!", "message": "=

Hi {{ $json.customer_name }},

We noticed you left some items in your cart:

Items: {{ $json.items }}

Total: {{ $json.currency }} {{ $json.total_price }}

Your cart is still saved! Complete your purchase here:

Complete Your Order

If you have any questions, just reply to this email.

", "o ...[truncated 1592 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (13)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| 01 | `01-new-order-handler.json` | Webhook → parse order → log to Sheets → notify admin |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| 04 | `04-abandoned-cart-recovery.json` | Scheduled → fetch abandoned carts → recovery email |

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill handles and persists customer PII and commerce data in Google Sheets, and it automates outbound recovery emails to customers, but the description lacks clear privacy, consent, and compliance warnings. This is dangerous because operators may deploy it without understanding data-handling obligations, retention risks, or email-marketing/legal constraints, increasing the chance of privacy violations or abusive messaging.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The workflow persists customer PII and order data, including name, email, phone, shipping address, and purchase details, into Google Sheets. While this is likely intended for business operations, storing sensitive order data in a broad collaboration tool without any minimization, retention controls, or disclosure increases privacy and data exposure risk if the sheet is overshared, compromised, or retained indefinitely.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The workflow emails customer order details to an admin mailbox, including customer identity, contact information, purchased items, and shipping address. Email is commonly forwarded, retained, and less tightly controlled than transactional systems, so sending full order PII this way increases the chance of unauthorized disclosure or long-term uncontrolled storage.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The workflow uses Google Sheets OAuth credentials and reads a Shopify access token from environment variables for authenticated data access. The file does not include any explanatory text or warning that the workflow depends on and uses these credentials to access external services.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This JSON workflow makes authenticated HTTP requests to Shopify and writes returned order status data into Google Sheets on a recurring schedule. There is no visible warning, confirmation step, or descriptive note in the file explaining that external data will be fetched and persisted automatically.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This JSON workflow transmits product and stock information via email, including SKU and inventory quantities, but the file contains no user-facing warning, confirmation, or explanatory description about that outbound notification. For manifest/config-style workflow definitions, this is the only visible artifact here, so the email transmission lacks disclosure within the reviewed file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This workflow automatically emails customers with their email address, item list, total price, and recovery link, which is a user-data-affecting outbound action. In this JSON file there is no confirmation step, user-facing notice, or explanatory description warning that customer data will be transmitted via email.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The file reads SHOPIFY_STORE_URL and SHOPIFY_ACCESS_TOKEN from environment variables and uses the access token in a request header to Shopify. There is no user-facing comment, warning, or description here that the skill depends on sensitive credentials and performs authenticated network access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The workflow emails a daily sales report containing business data such as revenue, order counts, fulfillment, and top products to the address in SHOPIFY_ADMIN_EMAIL. In this JSON skill file there is no warning, confirmation, or explanatory note that collected Shopify data will be sent externally via email.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest description highlights Google Sheets tracking and Shopify Admin API integration, but the documented behavior also includes sending admin notifications, abandoned-cart recovery emails, and daily sales report emails. Email delivery is a substantive operational capability, not just an incidental implementation detail, and it is not mentioned in the manifest summary line.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The HTTP request uses environment-derived store URL and access token values, including a sensitive Shopify access token. The file contains no user-facing comment, warning, or documentation indicating that the workflow reads credentials from the environment to access store checkout data.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.