T09 · Insecure Skill Coding Practices
- Location
references/locations.md:147- Finding
High-Impact Shopify Mutations Lack Consistent Explicit Confirmation Controls
- Content
View full analysis
Vulnerability Details
File Locations:
references/blogs.md:104-114, 309-319references/files.md:242-252references/locations.md:147-195references/markets.md:144-154references/menus.md:222-232references/pages.md:193-203references/segments.md:106-116references/shipping.md:236-246references/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: MediumVulnerable 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
View remediation
Remediation Suggestions
- Expand
SKILL.mdso every destructive, externally visible, billing-related, subscription-related, and inventory-routing mutation requires explicit approval. - Add a
REQUIRES PERMISSIONblock immediately before each affected mutation rather than relying only on a central policy. - 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.
- Require a new, unambiguous confirmation such as “confirm” after presenting the final mutation plan. Do not treat the original request as confirmation.
- For bulk operations, enumerate the resources or provide a bounded summary and require separate confirmation.
- Apply least-privilege Shopify scopes so the integration cannot perform unrelated mutations.
- Add a centralized mutation-risk registry that defaults unknown write operations to confirmation-required.
- Record the approving user, timestamp, mutation name, target IDs, and resulting Shopify response in an audit log.
- Add automated tests that verify no deletion, activation, cancellation, billing, publishing, or inventory-routing mutation can execute without a confirmation state.
- Expand
