T01 · Skill Instruction Hijacking
- Location
references/prompts/brickowl-tools.txt:13- Finding
Checked-in guidance instructs the Agent to bypass approval for marketplace mutations
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches its BrickOwl marketplace purpose, but it has conflicting approval guidance and can send the API key to a caller-selected API URL.
Review before installing. Use only with a BrickOwl API key you are comfortable granting to an agent, do not rely on it for unattended marketplace changes, and avoid BRICKOWL_BASE_URL or --base-url overrides unless you fully trust the destination. Confirm every create, update, delete, wishlist, and bulk write in the current conversation, and treat order addresses, buyer email, inventory costs, and personal notes as private.
references/prompts/brickowl-tools.txt:13Checked-in guidance instructs the Agent to bypass approval for marketplace mutations
scripts/brickowl_cli.py:29Unrestricted API base URL can exfiltrate the BrickOwl API key
Referenced artifact was not completely inspected
- CLI source: `scripts/brickowl_cli.py`
Referenced artifact was not completely inspected
- CLI source: `scripts/brickowl_cli.py`
The prompt explicitly states that BrickOwl listing operations execute immediately without an approval flow, even though the available tools include create, update, and delete actions that can alter a live marketplace inventory. This is dangerous because a misunderstood prompt, prompt injection elsewhere, or accidental user phrasing could cause irreversible listing changes or deletions without a final confirmation checkpoint.
The skill declares and documents capabilities that require environment-variable access and outbound network access, but it does not explicitly scope or declare those permissions. That weakens platform-level least-privilege controls and makes it harder for reviewers or runtime policy to constrain secret access and API egress.
The OpenAPI spec documents an inventory update operation with a delete flag, which directly enables destructive marketplace writes despite the skill being described as supporting 'safe marketplace writes'. Without explicit safeguards, an agent using this spec could remove inventory lots unintentionally or through prompt manipulation, causing business-impacting data loss.
The spec exposes destructive deletion of inventory via a boolean flag but provides no warning, confirmation guidance, or usage constraints. In a transactional marketplace skill, lack of friction around destructive actions increases the risk of accidental deletions or unsafe autonomous execution.
The order detail response includes personal data such as buyer email and shipping/billing addresses, yet the spec gives no privacy or data-handling warning. In an agent-integrated skill, exposing PII without minimization guidance raises the risk of unnecessary collection, display, logging, or downstream disclosure.
The /bulk endpoint allows caller-supplied endpoint, method, and parameters, enabling composition of multiple API calls beyond the narrowly described skill behaviors. In an agent context, this broad primitive can bypass intended per-action restrictions and make it easier for prompt-influenced workflows to perform unexpected or higher-risk operations at scale.
Removing user approval for state-changing actions enables autonomous execution over marketplace inventory, including listing creation, modification, and deletion. In this skill context, that materially increases the risk of unauthorized sales changes, pricing mistakes, inventory loss, or business disruption if the agent is induced to act on ambiguous or malicious instructions.
- **Currency**: Prices are in the store's default currency (set in BrickOwl shop settings, not via API)
- **Condition Values**: "New" or "Used" (case-insensitive, defaults to "New")
- **Rate Limits**: 600 requests per minute for standard operations
- **NO User Approval Required**: Unlike BrickLink tools, these execute immediately without approval flow
- **Inventory Updates**: Update operations only modify fields that are provided (null checks for partial updates)
When to Use BrickOwl:
The trigger 'User mentions BrickOwl marketplace or selling platform' is broad enough to match general discussion about BrickOwl, not just requests to use this skill. Without clearer constraints or negative examples, the skill could be invoked when the user is merely asking informational questions rather than requesting inventory actions.
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.
- Ask which platform they want to use if not specified
4. When user explicitly specifies service:
- Use only that service without asking
- Examples: "create BrickOwl listing", "sell on BrickLink"
Examples:
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import urllib.request
from typing import Any, Iterable
DEFAULT_BASE_URL = "https://api.brickowl.com/v1"
READ_TIMEOUT_SECONDS = 30
WRITE_COMMANDS = {"inventory-create", "inventory-update", "inventory-delete", "wishlist-create", "bulk"}
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import urllib.request
from typing import Any, Iterable
DEFAULT_BASE_URL = "https://api.brickowl.com/v1"
READ_TIMEOUT_SECONDS = 30
WRITE_COMMANDS = {"inventory-create", "inventory-update", "inventory-delete", "wishlist-create", "bulk"}
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import urllib.request
from typing import Any, Iterable
DEFAULT_BASE_URL = "https://api.brickowl.com/v1"
READ_TIMEOUT_SECONDS = 30
WRITE_COMMANDS = {"inventory-create", "inventory-update", "inventory-delete", "wishlist-create", "bulk"}
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.
def require_any_change(args: argparse.Namespace, field_names: Iterable[str]) -> None:
if not any(getattr(args, field) is not None for field in field_names):
raise BrickOwlCliError("provide at least one field to update")
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.
require_identifier(args)
change_fields = ["absolute_quantity", "relative_quantity", "price", "condition", "for_sale", "public_note", "personal_note"]
require_any_change(args, change_fields)
fields = {"lot_id": args.lot_id, "external_lot_id": args.external_lot_id, **{field: getattr(args, field) for field in change_fields}}
path = "/inventory/update"
if not ensure_write_allowed(args, path, fields):
return None
No suspicious patterns detected.