T09 · Insecure Skill Coding Practices
- Location
crm_filter.py:112- Finding
AI Classification Prompt Injection Through Untrusted Contact Fields
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This CRM skill is purpose-aligned, but it can send contact details to Anthropic and persist rejected contacts without strong consent or review controls.
Review this before installing if your contacts include confidential, regulated, or customer data. Use it only if you are comfortable sending contact metadata to Anthropic for Stage 2 scoring, and consider running without ANTHROPIC_API_KEY or adding an explicit opt-in, field minimization, dependency pinning, and a way to review or clear learning.json.
crm_filter.py:112AI Classification Prompt Injection Through Untrusted Contact Fields
README.md:95Unpinned Anthropic SDK Installation Reduces Supply-Chain Integrity
The skill advertises AI-powered relevance scoring and requires an ANTHROPIC_API_KEY, but it does not warn users that contact details and contextual notes may be transmitted to an external AI service. In a CRM context, this is particularly sensitive because contacts, lead notes, and relationship metadata may contain personal, confidential, or regulated information, increasing privacy and compliance risk.
The trigger phrases are broad natural-language requests such as 'score this lead' and 'who should I reach out to', which can overlap with ordinary conversation and cause unintended invocation by an agent. In this skill's context, accidental activation is more dangerous because it can lead to processing CRM/contact data and potentially invoking the external AI-backed scoring path without a clear, deliberate user action.
The skill states that 'learning.json' is auto-updated, but the user-facing description does not clearly warn that using the skill modifies persistent preference data. That can surprise users, create unwanted profiling, and retain sensitive preference or contact-related signals over time without informed consent.
The code transmits contact metadata such as email address, name, subjects, interaction history, and reply status to Anthropic in stage2_classify. Even if intended for functionality, this is a real data-exposure risk because sensitive personal/business relationship data leaves the local environment and is sent to a third party based only on presence of an environment variable, with no minimization, consent, or trust boundary checks.
The call to client.messages.create(...) sends contact data to an external AI provider without any user-facing notice in the code path. This is dangerous because users may reasonably assume CRM processing is local, while the implementation exports potentially sensitive contact and communication metadata to a remote service silently.
This manifest appears to drive activation or filtering behavior using generic keywords such as "confirm your", "invoice", and "receipt" plus broad thresholds like min_exchanges and max_days_between, but it does not document the exact trigger scope or negative examples. In a manifest file, this lack of specificity can cause unintended matches or invocations because it is unclear when the skill should activate versus abstain.
The README explicitly states that rejected contacts are persisted across runs, but it does not warn users about retention, review, or deletion of potentially sensitive contact data. In a CRM context, even a rejected-contact list can contain personal identifiers such as email addresses, so undocumented persistence increases privacy and compliance risk.
The save_config method writes rejected contact data back to learning.json, modifying persistent user data. While the docstring notes persistence, there is no visible user-facing warning, confirmation, or log message when this write occurs.
No suspicious patterns detected.