T09 · Insecure Skill Coding Practices
- Location
utilities/config-health-check/config_health_check.py:192- Finding
Attacker-Controlled API Configuration Can Exfiltrate the Convbox API Key
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a disclosed Convbox analytics helper, but it needs Review because an included health-check utility can expose the API key to a configuration-controlled endpoint.
Install only if you trust the publisher and are comfortable giving the skill access to Convbox business analytics. Avoid running the health checker with any modified or third-party access.yaml, prefer pinned/isolated installation methods, and review or clear memory.md if store benchmarks or budget caps should not persist across sessions.
utilities/config-health-check/config_health_check.py:192Attacker-Controlled API Configuration Can Exfiltrate the Convbox API Key
README.md:100Unpinned Remote Package Execution in Installation Instructions
The skill is presented as a storefront analytics/reporting tool, but it also directs infrastructure-style health checks, endpoint probing, schema validation, and account enumeration through a utility. This mismatch can bypass user expectations and security review boundaries, leading to authenticated probing of connected systems beyond the apparent business purpose.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
Why do Meta and Google report more conversions than our first-party data? Which channels can safely receive more budget? Where are customers dropping out of the onsite funnel? Create a weekly paid-media review and prioritize what we should fix first.
Representative workflows include:
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.
The README instructs users to run npx skills add ..., which fetches and executes the latest published skills package without a pinned version. If the upstream package is compromised, typosquatted, or updated with malicious code, users could execute attacker-controlled code during installation.
The skill requires environment access, file reads, and network use but does not declare an explicit tool/permission scope. That weakens governance and review because the skill can access sensitive capabilities without a clear allowlist, increasing the chance of overreach or unintended data access.
The skill instructs the agent to read persisted store-profile memory and proactively summarize business context back to the user at session start. That creates a risk of unnecessary disclosure of stored sensitive business data, especially if the wrong user/session gains access or if the information is surfaced without need-to-know.
Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.
1. **Load memory → summarize as session context.** Check for the store-profile memory (`memory.md`). If it exists, read it and briefly summarize it back to the user as the working context: business background (store URL, primary category, main objective), benchmarks (gross margin, target / breakeven ROAS, budget cap), and preferences (attribution model, report language, work role). Keep this to a few lines. If no memory exists, treat it as first-time setup and go to step 2.
2. **Confirm default configuration.** Ask the user to confirm the two defaults that drive everything downstream, showing what is currently on file (or "not set" for a first session):
- **Work role** — defaults to **General** (all results, no trimming); or one of Founder / Marketing Director / CRM / Site Ops / Creative Strategist / Media Buyer.
- **Store info** — store URL, primary category, main business objective, and benchmarks.
Ask "Is this still correct?" If anything is wrong or missing, guide the user to fill in / correct it, then **write the updated profile back to memory** for reuse (see Section 2 for the field list and write rules).
Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.
1. **Load memory → summarize as session context.** Check for the store-profile memory (`memory.md`). If it exists, read it and briefly summarize it back to the user as the working context: business background (store URL, primary category, main objective), benchmarks (gross margin, target / breakeven ROAS, budget cap), and preferences (attribution model, report language, work role). Keep this to a few lines. If no memory exists, treat it as first-time setup and go to step 2.
2. **Confirm default configuration.** Ask the user to confirm the two defaults that drive everything downstream, showing what is currently on file (or "not set" for a first session):
- **Work role** — defaults to **General** (all results, no trimming); or one of Founder / Marketing Director / CRM / Site Ops / Creative Strategist / Media Buyer.
- **Store info** — store URL, primary category, main business objective, and benchmarks.
Ask "Is this still correct?" If anything is wrong or missing, guide the user to fill in / correct it, then **write the updated profile back to memory** for reuse (see Section 2 for the field list and write rules).
Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.
1. **Load memory → summarize as session context.** Check for the store-profile memory (`memory.md`). If it exists, read it and briefly summarize it back to the user as the working context: business background (store URL, primary category, main objective), benchmarks (gross margin, target / breakeven ROAS, budget cap), and preferences (attribution model, report language, work role). Keep this to a few lines. If no memory exists, treat it as first-time setup and go to step 2.
2. **Confirm default configuration.** Ask the user to confirm the two defaults that drive everything downstream, showing what is currently on file (or "not set" for a first session):
- **Work role** — defaults to **General** (all results, no trimming); or one of Founder / Marketing Director / CRM / Site Ops / Creative Strategist / Media Buyer.
- **Store info** — store URL, primary category, main business objective, and benchmarks.
Ask "Is this still correct?" If anything is wrong or missing, guide the user to fill in / correct it, then **write the updated profile back to memory** for reuse (see Section 2 for the field list and write rules).
Persisting store profile details across sessions creates a standing repository of business-sensitive information such as store URL, objectives, benchmarks, and operational preferences. Persistent storage increases exposure in the event of access control mistakes, data retention issues, or later unintended disclosure by the assistant.
The trigger condition says the skill is the default entry point whenever a user raises any analysis, diagnostic, or reporting request across a very wide set of store topics. This lacks clear exclusion conditions or tighter invocation constraints, increasing the chance of unintended activation for general business-analysis conversations.
The document states the skill does not call Tools or Agent.Skills, yet elsewhere it explicitly instructs using utility skills. This contradiction undermines trust in the skill's security boundary and may cause reviewers or users to underestimate cross-skill execution and data flow.
The manifest-like metadata sets the scenario mapping key to a Chinese phrase only, which can impose a specific language/locale in routing or invocation behavior. The file does not state that language selection is optional or that this plan is intentionally limited to a Chinese-language environment.
The mapping key is given only in Chinese ("广告质量分诊断"), which indicates a locale-specific naming choice without any accompanying opt-in, language choice, or justification that this skill is region-specific. Under the policy, forcing a specific language or locale without user choice is a natural-language policy concern.
The metadata uses a Chinese scenario mapping key (投放扩量判断) while the rest of the plan is in English, indicating a language-specific routing or invocation requirement. The file does not offer a user language choice or justify the locale restriction as region-specific, which can violate language/locale policy requirements.
Line L007 uses the scenario mapping key "归因冲突诊断", which imposes a specific language/locale in the skill definition. The file does not indicate that language selection is optional or that the skill is region-specific, so this appears to violate the language-choice policy.
The routing examples include broad, everyday phrases such as 'anything wrong with my campaigns' and 'what's off today', which can cause the skill to activate on ambiguous user requests. In an agent setting, over-broad triggers increase the chance of unintended data access, incorrect analysis execution, or misrouting to downstream plans without sufficient user intent confirmation.
Suspicious Unicode normalization or mixed-script content
The scenario mapping key is specified only in Chinese ("素材表现诊断"), which indicates a fixed language expectation without any documented user choice or opt-in. Under the policy, language constraints should either be optional for the user or clearly justified as region-specific.
The routing examples are very broad, everyday phrases that can match vague user requests and send users into this plan when they may have intended a different workflow. In a skill-routing system, overbroad invocation patterns can cause unintended data access, misleading analysis, or execution of the wrong business process, especially when the plan fetches analytics by default.
The plan instructs the agent to persist shop-level thresholds to memory without requiring a clear user-facing notice or explicit consent at write time. Persistent storage of business preferences can create privacy, governance, and cross-session integrity risks, particularly if users do not realize data is being retained or later reused to influence analysis outcomes.
The file hard-codes the functions.md scenario mapping key as the Chinese phrase "利润归因诊断" while the rest of the plan is in English, with no note that this is locale-specific or user-selectable. This can reflect a language/locale policy violation because it imposes a specific language convention without opt-in or justification.
Suspicious Unicode normalization or mixed-script content
This markdown plan is in scope for vague-trigger review. Phrases like "why did CVR drop" and "where are users dropping off" are broad, natural ways to ask for general analysis and the file does not provide negative examples or tighter routing constraints beyond saying it is invoked by SKILL.md routing, which could lead to unintended routing collisions with related diagnostic skills.
The scenario mapping key includes Chinese text (异常监控) with no indication that language choice is optional or user-selected. This can violate language/locale policy because the skill content implicitly fixes part of the experience to a specific language without offering opt-in or alternatives.
Detected: suspicious.exposed_secret_literal