Back to skill

Security audit

Magento 2 Skill

Security checks for vulnerabilities and agentic risk

Overview

This Magento skill is mostly coherent and purpose-aligned, but it can perform high-impact store mutations and has under-scoped transport and retry behavior that users should review before installing.

Install only if you are comfortable giving the skill Magento API credentials that can read customer/order data and perform store-changing actions. Use least-privilege Magento integration tokens, configure only HTTPS base URLs, confirm every write command carefully, avoid arbitrary custom API writes unless you know the endpoint, and treat report output as customer PII.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/magento_client.py:45
Finding

OAuth-Authenticated Magento Traffic Can Be Sent Over Plaintext HTTP

Content
View full analysis

Vulnerability Details

File Location: scripts/magento_client.py:45-66
Vulnerability Type: Missing transport security enforcement for sensitive API traffic
Risk Level: High

Vulnerable Code

python
self.base_url = self._require_env("MAGENTO_BASE_URL").rstrip("/")
self.timeout = int(self._env_with_fallback("MAGENTO_TIMEOUT", "30"))
self.auth = OAuth1(
    client_key=self._require_env("MAGENTO_CONSUMER_KEY"),
    client_secret=self._require_env("MAGENTO_CONSUMER_SECRET"),
    resource_owner_key=self._require_env("MAGENTO_ACCESS_TOKEN"),
    resource_owner_secret=self._require_env("MAGENTO_ACCESS_TOKEN_SECRET"),
    signature_method="HMAC-SHA256",
)
self.session = requests.Session()
self.session.headers.update({"Content-Type": "application/json", "Accept": "application/json"})

# Setup retries for transient errors
retry_strategy = Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[429, 500, 502, 503, 504],
    allowed_methods=["HEAD", "GET", "OPTIONS", "POST", "PUT", "DELETE"],
)
adapter = HTTPAdapter(max_retries=retry_strategy)
self.session.mount("http://", adapter)
self.session.mount("https://", adapter)

Authenticated requests are subsequently issued without validating the URL scheme:

python
def get(self, path: str, params: dict | None = None) -> Any:
    resp = self.session.get(self._url(path), params=params, auth=self.auth, timeout=self.timeout)
    self._raise_for_status(resp)
    return resp.json()

def post(self, path: str, body: dict) -> Any:
    resp = self.session.post(self._url(path), json=body, auth=self.auth, timeout=self.timeout)
    self._raise_for_status(resp)
    return resp.json()

def put(self, path: str, body: dict) -> Any:
    resp = self.session.put(self._url(path), json=body, auth=self.auth, timeout=self.timeout)
    self._raise_for_status(resp)
    return resp.json()

def delete(self, path: str) -
...[truncated 2501 chars]
Remediation
View remediation

Remediation Suggestions

  • Parse MAGENTO_BASE_URL during client initialization and reject every scheme other than https.
  • Reject malformed URLs and URLs containing embedded user information.
  • If plaintext HTTP is required for isolated local development, require a clearly named opt-in such as MAGENTO_ALLOW_INSECURE_HTTP=1 and emit a prominent warning.
  • Restrict any development exception to loopback addresses or explicitly approved hosts.
  • Retain normal TLS certificate verification and do not introduce verify=False.
  • Consider applying an allowlist of expected Magento hostnames in managed deployments.
  • Document HTTPS as mandatory rather than merely showing it in examples.

Example validation:

python
parsed = urllib.parse.urlparse(self.base_url)
if parsed.scheme != "https":
    raise ValueError("MAGENTO_BASE_URL must use HTTPS")
if not parsed.hostname:
    raise ValueError("MAGENTO_BASE_URL must contain a valid hostname")

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/magento_client.py:57
Finding

Automatic Retries Can Replay Non-Idempotent Magento Write Operations

Content
View full analysis

Vulnerability Details

File Location: scripts/magento_client.py:57-63
Vulnerability Type: Unsafe retry policy for state-changing HTTP methods
Risk Level: Medium

Vulnerable Code

python
# Setup retries for transient errors
retry_strategy = Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[429, 500, 502, 503, 504],
    allowed_methods=["HEAD", "GET", "OPTIONS", "POST", "PUT", "DELETE"],
)

The affected methods send state-changing requests through the retry-enabled session:

python
def post(self, path: str, body: dict) -> Any:
    resp = self.session.post(self._url(path), json=body, auth=self.auth, timeout=self.timeout)
    self._raise_for_status(resp)
    return resp.json()

def put(self, path: str, body: dict) -> Any:
    resp = self.session.put(self._url(path), json=body, auth=self.auth, timeout=self.timeout)
    self._raise_for_status(resp)
    return resp.json()

def delete(self, path: str) -> Any:
    resp = self.session.delete(self._url(path), auth=self.auth, timeout=self.timeout)
    self._raise_for_status(resp)
    return resp.json()

Technical Analysis

The retry policy explicitly includes POST, PUT, and DELETE. Many Magento POST operations are non-idempotent, including shipment creation, invoice creation and capture, coupon creation, order cancellation workflows, cache clearing, and arbitrary custom-module operations.

A server may commit a write and then return a retryable status, or an intermediary may generate a retryable response after the request reaches the application. The client can then repeat the completed operation up to three times. The outcome is particularly unpredictable for custom_api.py, because the semantics of custom endpoints are unknown.

This behavior also conflicts with the documented error-handling rule in SKILL.md, which states that failed operations should not be retried automatica ...[truncated 1481 chars]

Remediation
View remediation

Remediation Suggestions

  • Limit automatic retries to safe, idempotent methods by default:
python
retry_strategy = Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[429, 500, 502, 503, 504],
    allowed_methods=["HEAD", "GET", "OPTIONS"],
)
  • Do not automatically retry POST or DELETE operations.
  • Evaluate PUT retries per endpoint rather than globally; only retry where the operation is demonstrably idempotent.
  • Use Magento-supported idempotency keys or unique operation identifiers where available.
  • For ambiguous write failures, report that the result is unknown and require the caller to verify server state before retrying.
  • Add endpoint-specific reconciliation checks, such as checking whether an invoice or shipment already exists.
  • Keep retry policy separate for read and write sessions so future code cannot accidentally inherit unsafe behavior.
  • Add tests simulating a server that commits a write and then returns a retryable error.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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 (28)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The description significantly overstates the behavior of this code chunk. The code is entirely focused on inventory operations: stock item lookup/update, low-stock listing, bulk stock operations, and Magento MSI endpoints (sources, source items, salable quantity, stocks). There is no evidence of functionality for orders, customers, promotions, reporting, module discovery, schema exploration, or arbitrary custom API interaction. While inventory is one valid subset of the declared scope, the declared purpose and example triggers present this as a general Magento management skill, which is materially broader than the actual code shown. This is a description-versus-behavior mismatch due to substantial missing declared capabilities in the implementation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description presents a broad Magento store management and discovery tool, including operational actions across multiple domains and custom module/API exploration. The supplied code chunk only implements read-only reporting commands over orders, products, and stock items, producing aggregated sales and inventory reports. While sales reporting and some inventory analysis are consistent with part of the declaration, the actual code is materially narrower than the declared purpose and lacks the advertised management, module discovery, and custom API capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The code is clearly Magento-related and does include part of the declared discovery functionality: listing modules and inspecting the REST schema. However, its actual scope is much narrower than the description. It does not implement order, catalog, customer, inventory, promotion, or sales-reporting operations; instead it offers system/admin tasks such as health checks, site listing, and cache inspection/clearing. Cache clearing is a meaningful capability not mentioned in the description, while many declared triggers imply business operations that this code chunk cannot perform. Therefore the description does not accurately represent this specific code chunk's behavior.

Content

No source excerpt is available for this finding.

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/magento_client.py (reported line 175)May include surrounding context.

python
prefix = "MAGENTO_BASE_URL_"
    sites = sorted(
        key[len(prefix):].lower()
        for key in os.environ
        if key.startswith(prefix)
    )
    has_default = bool(os.environ.get("MAGENTO_BASE_URL"))

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The invoice command creates and captures payment immediately, which is a financially impactful write operation, without any confirmation or preview. In the context of a Magento management skill, this is especially dangerous because an agent error, ambiguous user request, or malicious prompt injection could trigger unintended charges or accounting actions against a live store.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares environment and network-dependent behavior but does not define an explicit tool scope such as allowed-tools or permissions. In practice, that means a broadly triggered skill could gain access to credentials in environment variables and perform authenticated network actions against a production Magento instance without a narrowly declared execution boundary.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger language is extremely broad, including phrases like 'anything referencing a Magento store,' which can cause the agent to invoke this skill in situations the user did not intend. Because the skill has network access and can perform authenticated actions against a commerce platform, unintended invocation increases the chance of exposing store metadata or steering the agent toward sensitive operations.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% 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 · SKILL.md (reported line 43)May include surrounding context.

md
## Authentication

All requests are signed with OAuth 1.0a. Credentials are read from environment variables — never ask the user to paste them in chat.

### Single site (default)

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 · SKILL.md (reported line 331)May include surrounding context.

md
- Never expose OAuth credentials in chat output, logs, or summaries.
- For any **write operation** (cancel, delete, update-price, update-status, update-group, cache-flush, ship, invoice, create-coupon, disable, source-item-update, and all POST/PUT/DELETE via custom_api.py), always repeat the full command back to the user and wait for explicit confirmation before executing.
- **Read-only operations** (list, get, search, check, status, modules, schema, cache-list, reports) may be executed directly without confirmation.
- When a date range is not specified for reports, default to the last 30 days.
- Monetary values are returned in the store's base currency — include the currency code in output.
- **Multi-site**: When multiple sites are configured, always confirm which site the user intends before executing write operations. Use `system.py sites` to discover available sites.

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 · SKILL.md (reported line 336)May include surrounding context.

md
- Never expose OAuth credentials in chat output, logs, or summaries.
- For any **write operation** (cancel, delete, update-price, update-status, update-group, cache-flush, ship, invoice, create-coupon, disable, source-item-update, and all POST/PUT/DELETE via custom_api.py), always repeat the full command back to the user and wait for explicit confirmation before executing.
- **Read-only operations** (list, get, search, check, status, modules, schema, cache-list, reports) may be executed directly without confirmation.
- When a date range is not specified for reports, default to the last 30 days.
- Monetary values are returned in the store's base currency — include the currency code in output.
- **Multi-site**: When multiple sites are configured, always confirm which site the user intends before executing write operations. Use `system.py sites` to discover available sites.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The reference documents order-cancel, shipment, invoice, and comment-writing endpoints without clearly marking them as state-changing or potentially irreversible operations. In an agent skill that can act on natural-language requests, this increases the risk that the agent or a user invokes destructive actions unintentionally, especially because these endpoints affect financial and fulfillment workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The product DELETE and stock update endpoints are listed without warnings about deletion, inventory corruption, or storefront impact. In the context of a Magento management skill, these operations are especially dangerous because an LLM-driven agent may interpret broad user instructions and directly alter catalog availability or permanently remove products.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The reference includes administrative and bulk-write endpoints for inventory sources, stock assignments, stock deletion, and cache clearing without cautionary notes. These actions can disrupt store availability, routing, and operational integrity at scale, and the skill description explicitly supports custom API exploration, which makes unsafe endpoint discovery and invocation more dangerous.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The delete command irreversibly removes a product immediately after receiving a SKU, with no confirmation prompt, dry-run mode, or explicit force flag. In a catalog-management skill that is designed to perform live administrative actions against a Magento store, this increases the risk of accidental or unintended destructive changes from user mistakes, misrouted agent actions, or prompt/parameter confusion.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The update-group command performs a live state-changing API call that modifies a customer's group immediately, with no confirmation prompt, dry-run mode, or explicit safeguard. In an agent skill context, this increases the risk of accidental or unauthorized customer segmentation changes caused by misinterpreted prompts, automation mistakes, or prompt injection driving unintended administrative actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The order-exceptions report includes raw customer_email values in output for pending, payment-review, and stuck-processing orders. Exposing personally identifiable information in diagnostics increases privacy and data-handling risk, especially because these reports may be shown to users, logged, copied into chat transcripts, or sent to systems that do not need customer identifiers.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The update command performs an immediate inventory write based solely on CLI arguments, with no preview, confirmation gate, or dry-run mode. In an agent skill context, this increases the chance that a mistaken prompt, ambiguous instruction, or unsafe automation path can silently alter stock levels and disrupt fulfillment or storefront availability.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The source-item-update command directly updates MSI source inventory without any user confirmation, preview, or dry-run behavior. Because this skill is designed for store management and may be invoked by an agent from natural-language requests, a bad interpretation or unauthorized invocation could modify per-source inventory and affect allocation, salability, and operational planning.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The cancel command performs an irreversible business action immediately after invocation, with no confirmation prompt, dry-run mode, or secondary safeguard. In an agent skill that can be triggered from natural-language requests, this increases the risk of accidental cancellations from mis-parsed intent, wrong order identifiers, or prompt injection influencing the agent to issue a destructive action.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The disable command performs an immediate live mutation against the Magento API by fetching a rule, setting is_active to false, and issuing a PUT without any confirmation, dry-run mode, or explicit warning. In an agent skill designed to manage promotions on a production store, this increases the chance of accidental or prompt-induced business-impacting changes such as disabling active discounts and disrupting campaigns or revenue.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The top-customers report prints customer email addresses and names directly to output without any warning, minimization, or access-control check in this script. In the context of a Magento admin/reporting skill, this creates a privacy and data-handling risk because an operator can easily expose personally identifiable information in terminals, logs, chat transcripts, or downstream tooling.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency list is completely unpinned, so installations may resolve to different versions over time, including vulnerable or breaking releases. In a skill that manages a Magento/Adobe Commerce store and may handle credentials, orders, and inventory, supply-chain drift increases risk because a later install could silently pull an unsafe version of a network-facing library.

Content

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

text
requests
requests-oauthlib
pandas
tabulate

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
89% confidence
Finding

The manifest includes requests without a version pin, and the package has multiple known advisories across versions, so there is no way to verify whether deployed installations are affected. In a Magento integration skill that performs REST calls and may handle API credentials, a vulnerable HTTP client could expose secrets, weaken TLS/request validation behavior, or enable request-manipulation issues depending on the resolved version.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

Leaving requests-oauthlib unpinned allows dependency resolution to select arbitrary future releases, which can introduce security regressions or incompatible OAuth behavior. Because this skill likely authenticates to store APIs, unstable auth-library versions can affect confidentiality and integrity of store access.

Content

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

text
requests
requests-oauthlib
pandas
tabulate
ruff

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

An unpinned pandas dependency creates non-reproducible builds and may expose the environment to newly introduced vulnerable releases or unsafe transitive changes. While pandas is less security-critical than HTTP/auth libraries here, this still weakens supply-chain control in a store-management skill.

Content

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

text
requests
requests-oauthlib
pandas
tabulate
ruff

Static analysis

No suspicious patterns detected.