T09 · Insecure Skill Coding Practices
Warning
- Location
- references/locations.md:147
- Finding
- High-Impact Shopify Mutations Lack Consistent Explicit Confirmation Controls## Vulnerability Details **File Locations**: - `references/blogs.md:104-114, 309-319` - `references/files.md:242-252` - `references/locations.md:147-195` - `references/markets.md:144-154` - `references/menus.md:222-232` - `references/pages.md:193-203` - `references/segments.md:106-116` - `references/shipping.md:236-246` - `references/subscriptions.md:264-344` - Related incomplete central policy: `SKILL.md:22-33` **Vulnerability Type**: Missing authorization confirmation for destructive and business-impacting operations **Risk Level**: Medium ### Vulnerable Code Representative location and inventory-routing mutations from `references/locations.md:147-195`: ```graphql ## Activate Location mutation ActivateLocation($locationId: ID!) { locationActivate(locationId: $locationId) { location { id isActive } userErrors { field message } } } ## Deactivate Location mutation DeactivateLocation($locationId: ID!, $destinationLocationId: ID) { locationDeactivate(locationId: $locationId, destinationLocationId: $destinationLocationId) { location { id isActive } userErrors { field message } } } Note: When deactivating, inventory moves to the destination location. ## Delete Location mutation DeleteLocation($locationId: ID!) { locationDelete(locationId: $locationId) { deletedLocationId userErrors { field message } } } ``` Representative subscription mutations from `references/subscriptions.md:264-344`: ```graphql ## Commit Draft (Activate) mutation CommitSubscriptionDraft($draftId: ID!) { subscriptionDraftCommit(draftId: $draftId) { contract { id status } userErrors { field message } } } ## Pause Subscription mutation PauseSubscription($subscriptionContractId: ID!) { ...[truncated 3861 chars]
- Remediation
- ## Remediation Suggestions 1. Expand `SKILL.md` so every destructive, externally visible, billing-related, subscription-related, and inventory-routing mutation requires explicit approval. 2. Add a `REQUIRES PERMISSION` block immediately before each affected mutation rather than relying only on a central policy. 3. Before execution, retrieve and display: - Resource type, title, and Shopify GID. - Current state and proposed state. - All affected records. - Inventory, billing, customer, shipping, and storefront consequences. - Whether the operation is reversible. 4. Require a new, unambiguous confirmation such as “confirm” after presenting the final mutation plan. Do not treat the original request as confirmation. 5. For bulk operations, enumerate the resources or provide a bounded summary and require separate confirmation. 6. Apply least-privilege Shopify scopes so the integration cannot perform unrelated mutations. 7. Add a centralized mutation-risk registry that defaults unknown write operations to confirmation-required. 8. Record the approving user, timestamp, mutation name, target IDs, and resulting Shopify response in an audit log. 9. Add automated tests that verify no deletion, activation, cancellation, billing, publishing, or inventory-routing mutation can execute without a confirmation state.
