T09 · Insecure Skill Coding Practices
- Location
SKILL.md:29- Finding
Plaintext API Key Persistence Without File Permission Protection
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a coherent Amazon research integration, but it needs Review because it stores API keys in plaintext and includes nationality-based seller profiling guidance.
Review this skill before installing if you are comfortable sending Amazon research queries to APIClaw. Prefer APICLAW_API_KEY as an environment variable and do not give the agent an API key to save automatically. Avoid using the Chinese seller workflow for decisions based on nationality or inferred origin.
SKILL.md:29Plaintext API Key Persistence Without File Permission Protection
README.md:39Unpinned Third-Party CLI Execution During Installation
Skill instructs the agent to never refuse or to always comply. Suppressing the agent's ability to decline removes a core safety control and enables downstream harmful requests to succeed.
> AI-powered Amazon product research. From market discovery to daily operations.
>
> **Language rule**: Always respond in the user's language. If the user asks in Chinese, reply in Chinese. If in English, reply in English. The language of this skill document does not affect output language.
> All API calls go through `scripts/apiclaw.py` — one script, 5 endpoints, built-in error handling.
## Credentials
The skill tells the agent to store user-provided API keys in config.json but provides no meaningful user-facing warning about persistence, retention, or exposure risks. This is especially dangerous because users may assume a provided key is used only for the current task, while the skill silently creates a durable secret on disk.
Referenced artifact was not completely inspected
| `SKILL.md` (this file) | Start here — covers 80% of tasks |
The skill embeds a dedicated workflow for analyzing and ranking a nationality-based seller segment, including counting, filtering, and deriving strategy insights from 'Chinese sellers' as a class. In the context of an Amazon product-research skill, this is more dangerous because it operationalizes sensitive-group profiling as a built-in feature rather than an incidental edge case, enabling discriminatory segmentation and business decisions based on nationality.
The script accesses a bearer API key from the environment or a local config file and then uses it for outbound requests. In an agent skill setting, local credential harvesting and use are sensitive because they expand the trust boundary, and reading secrets from a plaintext file in the skill directory increases the chance of accidental exposure, misuse, or inclusion in shared artifacts.
def get_api_key():
"""
Get API key from environment variable or config file.
Priority:
1. Environment variable APICLAW_API_KEY
The README tells users to run npx clawhub install Amazon-analysis-skill without pinning a specific package version. This creates a supply-chain risk because npx may fetch the latest package at execution time, so a compromised or malicious upstream release could run arbitrary code on the user's machine during install.
The README instructs users to either export an API key or tell the AI agent the key so it can save it to config.json automatically, but it gives no warning about secret exposure, storage location, file permissions, or agent access scope. In this skill context, that is especially risky because the skill is designed for use by AI agents, increasing the chance that credentials are stored insecurely, echoed in logs, written to shared workspaces, or exposed to other tools.
The skill declares access to environment variables, local files, and networked API use, but does not constrain those capabilities with an explicit tool scope such as allowed-tools or permissions. That increases the attack surface because the agent may use broader-than-necessary capabilities when handling untrusted prompts or skill content.
The trigger description includes broad catch-all phrasing such as handling 'any Amazon seller data needs,' which can cause the skill to activate for loosely related requests. Over-broad activation increases the chance of unnecessary credential use, unnecessary network calls, and the model following skill instructions in contexts the user did not intend.
The skill explicitly instructs the agent to persist a user-provided API key into a local config.json file, even though transient in-memory use or environment-based configuration would satisfy the stated functionality. Persisting credentials to disk creates unnecessary exposure through later reads, logs, backups, workspace sharing, or cross-task leakage.
The intent-routing table uses vague phrases like 'what should I sell' and 'find products,' which are common natural-language queries that may overlap with broader business, marketing, or creative advice requests. This raises the risk of the skill engaging tools and data flows without sufficiently clear user intent or scope boundaries.
The trigger phrases for comprehensive recommendations are broad enough to activate on common shopping or advice requests, increasing the chance the skill is invoked outside its intended Amazon-seller-research context. Over-broad activation expands data handling and recommendation behavior in contexts where users may not expect specialized market analysis, which can produce inappropriate or overreaching outputs.
This guidance explicitly directs the agent to infer seller nationality from location metadata, brand names, pinyin-style names, and naming patterns, which introduces sensitive-attribute profiling unrelated to the core product-research function. The fallback heuristics are especially risky because they encourage unreliable ethnic or nationality inference from names and linguistic patterns, which can lead to discriminatory analysis and harmful targeting.
The Chinese seller case-study trigger includes a very broad phrase ('Chinese sellers') that can activate nationality-focused analysis with minimal user specificity. Because the downstream workflow profiles a nationality-based seller segment, broad triggering makes sensitive analysis easier to invoke accidentally or opportunistically, amplifying the risk of discriminatory use.
The trigger phrase set for risk assessment includes very generic language such as 'can I do this' and 'what are the risks', which overlaps heavily with ordinary user conversation. In an agent system, this can cause the skill to activate unintentionally on unrelated prompts, pulling in product-analysis behavior and external API usage when the user did not clearly request Amazon seller analysis.
The category consumer insights trigger list contains broad phrases like 'who is buying' and 'what do users want', which are common in many non-Amazon contexts. This increases the chance of accidental skill invocation and unintended use of external analysis logic for unrelated user requests.
The trigger phrases for listing copy generation are broad enough to match generic writing requests like 'write listing' or 'help me write product page' without strong Amazon-specific scoping. In an agent system, this can cause the skill to activate on loosely related user prompts and pull external competitive or product data unexpectedly, creating overreach and increasing the chance of irrelevant or unauthorized tool use.
The diagnosis triggers such as 'optimize my listing' or 'improve my listing' are ambiguous and can apply to many non-Amazon or non-commerce contexts. Because the associated workflow initiates competitor lookups and review analysis, an overly permissive match may invoke this skill for requests outside its intended scope, leading to unnecessary external calls and unintended data processing.
This skill is explicitly designed to transmit user-supplied product research inputs and authentication credentials to a third-party service at api.apiclaw.io. In a skill context, that external data flow is security-relevant because queries, category selections, ASINs, and API usage metadata leave the local environment and are sent off-platform.
# ─── Configuration ───────────────────────────────────────────────────────────
BASE_URL = "https://api.apiclaw.io/openapi/v2" # APIClaw API base URL
API_DOCS = "https://api.apiclaw.io/api-docs" # API documentation URL
MAX_RETRIES = 2 # Maximum number of retry attempts for failed requests
RETRY_DELAY = 2 # Initial retry delay in seconds; doubles on 429 (rate limit)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# ─── Configuration ───────────────────────────────────────────────────────────
BASE_URL = "https://api.apiclaw.io/openapi/v2" # APIClaw API base URL
API_DOCS = "https://api.apiclaw.io/api-docs" # API documentation URL
MAX_RETRIES = 2 # Maximum number of retry attempts for failed requests
RETRY_DELAY = 2 # Initial retry delay in seconds; doubles on 429 (rate limit)
REQUEST_TIMEOUT = 60 # Request timeout in seconds; realtime/product can be slow (up to 30s)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# ─── Configuration ───────────────────────────────────────────────────────────
BASE_URL = "https://api.apiclaw.io/openapi/v2" # APIClaw API base URL
API_DOCS = "https://api.apiclaw.io/api-docs" # API documentation URL
MAX_RETRIES = 2 # Maximum number of retry attempts for failed requests
RETRY_DELAY = 2 # Initial retry delay in seconds; doubles on 429 (rate limit)
REQUEST_TIMEOUT = 60 # Request timeout in seconds; realtime/product can be slow (up to 30s)
The script explicitly instructs users to persist the API key in a plaintext config.json under the skill directory, creating durable local credential storage. In shared agent/workspace environments this is dangerous because the file may be committed, copied, read by other tools, or exposed through logs, backups, or artifact packaging.
print(" export APICLAW_API_KEY='hms_live_yourkey'", file=sys.stderr)
print("", file=sys.stderr)
print(" Method 2: Config file", file=sys.stderr)
print(f" Create config.json in the skill directory: {skill_dir}", file=sys.stderr)
print(' Content: {"api_key": "hms_live_yourkey"}', file=sys.stderr)
print("", file=sys.stderr)
print("Get a free key at https://apiclaw.io/api-keys", file=sys.stderr)
The file-level credential documentation and get_api_key() describe config lookup in a skill-local config.json, but cmd_check() instead looks in ~/.apiclaw/config.json. This is an active contradiction in the skill's own documented configuration model, which can mislead operators about where secrets are read from during execution.
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.
"priceMin", "priceMax", "ratingMin", "ratingMax", "bsrMin", "bsrMax",
"salesGrowthRateMin", "salesGrowthRateMax", "sellerCountMin", "sellerCountMax",
"variantCountMin", "variantCountMax"):
val = getattr(args, attr.replace("Min", "_min").replace("Max", "_max")
.replace("monthly", "monthly_").replace("review", "review_")
.replace("sales", "sales_").replace("Growth", "_growth_")
.replace("Rate", "rate_").replace("price", "price_")
The CLI help for the check subcommand says it will 'Fetch latest OpenAPI spec to verify available endpoints', but cmd_check() never requests the OpenAPI spec or API docs. It only tests a hardcoded list of endpoints with sample API calls, so the inline documentation overstates and misdescribes the implemented behavior.
No suspicious patterns detected.