T09 · Insecure Skill Coding Practices
- Location
src/shopify.py:45- Finding
Shopify access token can be transmitted to an unvalidated host without publishing consent
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is broadly aligned with e-commerce asset generation, but it has unsafe handling of store credentials, live publishing, and writable output paths that should be reviewed before installation.
Install only after reviewing the code paths that use Shopify and WooCommerce credentials. Use a test store first, avoid setting store admin credentials as ambient environment variables unless publishing is intended, use least-privilege tokens, validate store URLs, and constrain output paths to a dedicated directory.
src/shopify.py:45Shopify access token can be transmitted to an unvalidated host without publishing consent
src/woocommerce.py:50WooCommerce credentials are used automatically without HTTPS or destination validation
src/main.py:562Caller-controlled output path allows arbitrary file overwrite
src/product_synthesizer.py:193Unsanitized product input is published as storefront HTML
Introducing our premium {product_name}, designed to exceed your expectations. Crafted with precision and attention to detail, this product offers exceptional value and performance.
Our {product_name} stands out from the competition with its superior build quality and thoughtful design. Whether you're a beginner or professional, this product is perfect for your needs.
Order now and experience the difference!
""" ``` The fallback-language branch has the same issue: ```python description = f"""Premium quality product with excellent features and great value.
Order now!
""" ``` Shopify receives the unsanitized HTML: ```python product_data = { "product": { "title": title, "body_html": description, ``` WooCommerce also receives it directly: ```python product_data = { "name": title, "description": description, "short_description": short_description, ``` ### Technical Analysis `product_name` and caller-provided descriptions are treated as trusted HTML. The synthesizer inserts `product_name` into HTML templates without escaping special characters. In addition, when a caller supplies `description`, `synthesize()` uses ...[truncated 1787 chars]requirements.txt:6Unpinned and unnecessary dependencies create supply-chain exposure
The skill is framed as content generation, yet it reportedly performs direct WooCommerce or WordPress API access and live store mutation. That discrepancy materially increases risk because users may authorize a content tool without realizing it can publish products or change stock in a production commerce system.
The skill is framed as content generation, yet it reportedly performs direct WooCommerce or WordPress API access and live store mutation. That discrepancy materially increases risk because users may authorize a content tool without realizing it can publish products or change stock in a production commerce system.
The skill is framed as content generation, yet it reportedly performs direct WooCommerce or WordPress API access and live store mutation. That discrepancy materially increases risk because users may authorize a content tool without realizing it can publish products or change stock in a production commerce system.
The skill is framed as content generation, yet it reportedly performs direct WooCommerce or WordPress API access and live store mutation. That discrepancy materially increases risk because users may authorize a content tool without realizing it can publish products or change stock in a production commerce system.
The skill is framed as content generation, yet it reportedly performs direct WooCommerce or WordPress API access and live store mutation. That discrepancy materially increases risk because users may authorize a content tool without realizing it can publish products or change stock in a production commerce system.
The skill is framed as content generation, yet it reportedly performs direct WooCommerce or WordPress API access and live store mutation. That discrepancy materially increases risk because users may authorize a content tool without realizing it can publish products or change stock in a production commerce system.
The skill requests and documents use of multiple high-privilege credentials, including store access tokens and API secrets, for networked operations against live commerce platforms. In this context, broad credential access is dangerous because compromise, misuse, or accidental invocation could lead to unauthorized publication, inventory changes, store reconnaissance, or leakage of business-sensitive data.
- `GOOGLE_API_KEY` - Google API Key for Nano Banana 2 image generation
- `SHOPIFY_STORE_URL` - Shopify store URL
- `SHOPIFY_ACCESS_TOKEN` - Shopify Admin API access token
- `WOOCOMMERCE_STORE_URL` - WooCommerce store URL
- `WOOCOMMERCE_CONSUMER_KEY` - WooCommerce API consumer key
- `WOOCOMMERCE_CONSUMER_SECRET` - WooCommerce API consumer secret
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
}
})
return prompts
def _generate_content_drafts(
self,
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
}
})
return prompts
def _generate_content_drafts(
self,
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Args:
google_api_key: Google API Key for Nano Banana 2
shopify_store_url: Shopify store URL
shopify_access_token: Shopify Admin API access token
woo_store_url: WooCommerce store URL
woo_consumer_key: WooCommerce API consumer key
woo_consumer_secret: WooCommerce API consumer secret
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Args:
google_api_key: Google API Key for Nano Banana 2
shopify_store_url: Shopify store URL
shopify_access_token: Shopify Admin API access token
woo_store_url: WooCommerce store URL
woo_consumer_key: WooCommerce API consumer key
woo_consumer_secret: WooCommerce API consumer secret
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Args:
google_api_key: Google API Key for Nano Banana 2
shopify_store_url: Shopify store URL
shopify_access_token: Shopify Admin API access token
woo_store_url: WooCommerce store URL
woo_consumer_key: WooCommerce API consumer key
woo_consumer_secret: WooCommerce API consumer secret
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
args = parser.parse_args()
# Get API keys from environment if not provided
google_api_key = args.api_key or os.environ.get("GOOGLE_API_KEY")
shopify_url = args.shopify_url or os.environ.get("SHOPIFY_STORE_URL")
shopify_token = args.shopify_token or os.environ.get("SHOPIFY_ACCESS_TOKEN")
The code is designed to access a Shopify Admin API token, which is a powerful credential for store management. Credential access is especially sensitive here because the skill description does not clearly prepare the user for privileged store operations, increasing the likelihood of misuse or overbroad deployment.
Args:
store_url: Shopify store URL (e.g., "mystore.myshopify.com")
access_token: Shopify Admin API access token
"""
self.store_url = store_url or os.environ.get("SHOPIFY_STORE_URL", "")
self.access_token = access_token or os.environ.get("SHOPIFY_ACCESS_TOKEN", "")
This code performs authenticated product creation in a live Shopify store, which materially exceeds the declared skill scope of generating visuals, product data, copy, and export-ready assets. In a skill context, undocumented write access to an external commerce platform is dangerous because it can alter production catalog state, publish unintended products, and create business impact without clear user expectation.
This skill performs direct state-changing actions against a live WooCommerce store, including product creation and inventory updates, despite being framed as a content-generation and commerce-asset preparation tool. That mismatch is dangerous because users may authorize or invoke the skill expecting draft/export behavior, while the code can publish products and alter stock in production.
The skill declares access to sensitive environment variables and clearly describes networked publishing behavior, but it does not declare any explicit tool scope or allowed-tools policy. That creates an authorization gap where an agent may use broader capabilities than a reviewer or user expects, especially given the presence of store credentials and write-capable commerce workflows.
The quick-start example hard-codes country="us" and language="en", which presents a default locale choice rather than asking the user to select one. Similar locale defaults recur in the documented API, and the file does not clearly state that users should be offered a language/locale choice first.
The API reference explicitly defines country='us' and language='en' as defaults for the main workflow. This is a natural-language policy concern because it bakes in a specific locale and language without indicating user consent, choice, or a justified regional limitation.
The manifest describes a skill focused on generating visuals, structured product data, localized commerce copy, and export-ready commerce assets. This JSON additionally produces a multi-week social/media distribution strategy with channels, KPIs, timing guidance, and iteration planning, which is a broader marketing campaign planning function rather than a direct commerce asset generation detail.
This JSON output includes a locale-setting field of "language": "en", which indicates the skill is forcing English output. The policy allows locale constraints only when the user is given a choice or when the restriction is clearly documented and justified, neither of which is present in this file.
The prompt instructs the system to produce a generated_images field as if actual image generation and file persistence will occur, which implicitly expands the skill from content generation into side-effecting execution. This is dangerous because downstream orchestrators may treat the prompt as authorization to invoke tools or write files without explicit manifest declaration, user consent, or policy checks.
The prompt explicitly states that the system will call Google AI Studio API, save generated images to local storage, and return file paths/URLs, introducing undeclared network access and local file writes. This creates a capability mismatch where an LLM prompt can socially engineer the host agent into performing sensitive side effects beyond the stated skill scope.
Automatic image generation and local storage are presented as silent default behavior with no user-facing warning or consent step. Hidden side effects are risky because users may provide inputs assuming text-only processing, while the system performs external API calls, incurs cost, transmits data off-box, or writes artifacts locally without transparency.
The schema description explicitly promises an end-to-end workflow including auto-publishing, while the skill metadata describes generation of visuals, product data, copy, and export-ready assets. This mismatch can cause downstream systems or users to authorize a capability they did not reasonably expect, increasing the risk of unintended store modifications or product publication without clear consent boundaries.
No suspicious patterns detected.