T09 · Insecure Skill Coding Practices
- Location
scripts/apiclaw.py:75- Finding
Plaintext API Key Fallback Lacks File Permission and Repository Safeguards
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is mostly coherent Amazon analytics tooling, but it handles API keys and seller nationality profiling in ways users should review carefully before installing.
Review this before installing if you will use a paid or sensitive APIClaw account. Prefer APICLAW_API_KEY from a secure environment or secret manager, do not paste the key into normal chat, and do not store it in the skill directory. Be cautious with workflows that identify 'Chinese sellers' or infer seller origin from names, because those results can be biased or inaccurate. Use the skill only for explicit Amazon seller analytics requests.
scripts/apiclaw.py:75Plaintext API Key Fallback Lacks File Permission and Repository Safeguards
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
Referenced artifact was not completely inspected
| `SKILL.md` (this file) | Start here — covers 80% of tasks |
The code accesses credentials from the environment and local filesystem, then uses them for outbound authenticated requests. In a skill ecosystem, credential access is sensitive because the script can consume secrets available to the runtime and couple them with external network access; although intended for legitimate API authentication, this still enlarges the blast radius if the skill or environment is misused or logs/outputs are later extended unsafely.
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 or integrity value. That exposes users to supply-chain risk: a compromised or newly published package version could execute arbitrary code during installation, and the skill context makes this more concerning because the target audience is installing tooling into an AI-agent workspace where secrets and local files may be accessible.
The README instructs users to tell their AI agent the API key so it can save it to config.json automatically, but provides no warning about where that file is stored, whether it is plaintext, or how to avoid exposing the secret in prompts, logs, chat history, or version control. In a skill for AI agents, this is especially risky because users may paste credentials into conversational contexts that are retained, inspected by other tools, or written to insecure workspace files.
The skill requires access to environment variables, local files, and the network, but it does not explicitly declare a tool/permission scope limiting those capabilities. That creates an over-privileged execution model where a hosting agent may grant broader access than is necessary, increasing the blast radius if the skill or a referenced script is compromised or behaves unexpectedly.
The trigger phrases for comprehensive recommendations are very broad ('help me choose', 'what should I sell'), which can cause the skill to activate in contexts where the user did not clearly request Amazon seller analytics. Overbroad invocation increases the chance of unintended data processing and can chain users into more sensitive workflows than expected.
The skill explicitly instructs the agent to identify and rank sellers by nationality/location ('Chinese sellers') and to infer that identity from weak proxies like seller names, brand names, or category patterns when location data is missing. That goes beyond ordinary product analytics into demographic profiling, creating a risk of biased targeting, inaccurate inferences, and discriminatory downstream decisions.
The skill provides detailed guidance for nationality/locale-specific analysis without any justification, safeguards, or opt-in framing, and even recommends fallback heuristics to guess seller origin when data is absent. In this context, that makes the skill more dangerous because it operationalizes sensitive segmentation as a normal product-research task rather than an exceptional, constrained analysis.
The Chinese seller case-study trigger includes a very broad phrase ('Chinese sellers'), making it easy to invoke a nationality-focused profiling workflow with minimal user intent. Because the downstream workflow centers on identifying and comparing sellers by nationality, accidental activation materially increases privacy, fairness, and misuse risk.
The phrase "pain points" is broad and commonly used across many business, UX, and customer-support contexts, so it can unintentionally invoke this review-analysis workflow when the user is not asking about Amazon products. Because this skill performs product/review analytics, overbroad activation can lead to wrong-task execution and irrelevant external API calls.
The trigger phrase "can I do this" is highly generic and can match many unrelated user requests, causing the Amazon research skill to activate outside its intended scope. In an agent system, this increases the chance of incorrect tool routing, unnecessary API use, and context leakage into workflows that are not actually about Amazon product evaluation.
The trigger "what do users want" is too generic to safely route to category consumer insights because it applies to nearly any research or product-design conversation. In this skill context, that ambiguity makes accidental activation more likely and can cause the agent to fetch Amazon category analytics when the user intended a different domain entirely.
The competitor-analysis trigger examples include ambiguous everyday language such as 'what are they saying', which can overlap with normal questions about opinions, messaging, or summaries unrelated to Amazon competitors. Over-broad activation increases the chance of unintended skill routing and unnecessary access to external product-analysis functions.
The trigger set for listing copy generation includes broad phrases like 'write listing' and 'help me write product page', which can match many ordinary content-writing requests without clear Amazon-specific constraints. This can cause the skill to activate unexpectedly, leading the agent to pull competitor and product data or steer the conversation into commerce-specific workflows when the user intended generic copywriting help.
The optimization-diagnosis triggers use broad phrases such as 'optimize my listing' and 'what's wrong with my listing' without limiting them to Amazon seller listings. This can misroute generic marketplace, ecommerce, real-estate, or even non-commerce 'listing' requests into a workflow that fetches product and competitor data, creating unintended tool use and context confusion.
The activation guidance says to load the skill for broad categories like market monitoring, competitor tracking, or anomaly detection, which are common seller-analysis intents and may overlap with many unrelated requests. Over-broad trigger conditions increase the chance of inappropriate invocation, causing the agent to use this skill when the user did not explicitly request Amazon/APIClaw-specific analysis, which can lead to data leakage through unnecessary external API calls or tool misuse.
The load condition 'pricing strategy, profit estimation, or listing reference tasks' is broad enough to activate this skill for generic pricing or reference requests that may not actually require Amazon seller analytics. Over-broad triggering can cause unintended tool invocation, unnecessary exposure of external API-backed capabilities, and misrouting of user queries into a commerce-specific workflow without sufficient domain confirmation.
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)
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)
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)
get_api_key() documents that the fallback config file is config.json in the skill directory, and the implementation there follows that behavior. However, cmd_check separately checks ~/.apiclaw/config.json instead (L564-L582), creating contradictory in-code documentation and behavior around where credentials are expected to reside.
The script explicitly instructs users to persist the API key in config.json within the skill directory, creating a durable local secret store. In agent environments, skill directories are at higher risk of being packaged, synced, inspected by other tools, or accidentally committed, making persistent plaintext credentials more dangerous than ephemeral environment-based secrets.
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 script supports reading a long-lived API key from a plaintext config.json file in the skill directory and even instructs the user to create that file. Plaintext local credential storage increases the chance of accidental disclosure through repository commits, backups, shared directories, or permissive filesystem access, especially in agent/skill environments where package contents may be inspected.
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_")
No suspicious patterns detected.