T09 · Insecure Skill Coding Practices
- Location
hooks/emotion-state/handler.ts:268- Finding
Complete Conversation Messages Are Transmitted to External Classifiers Without Data Minimization
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill provides emotion tracking, but it also sends full recent messages to a classifier and shares stored emotion profiles across agents with weak scoping.
Review before installing. This skill should only be enabled where users understand that recent conversation messages may be sent to an external or configured classifier, emotion profiles will persist on disk, and summaries may be injected into future prompts. Prefer a trusted local or tightly controlled HTTPS classifier, set EMOTION_MAX_OTHER_AGENTS to 0 unless cross-agent sharing is explicitly desired, and define deletion and retention practices for the stored emotion-state.json files.
hooks/emotion-state/handler.ts:268Complete Conversation Messages Are Transmitted to External Classifiers Without Data Minimization
hooks/emotion-state/handler.ts:320Untrusted Classifier Output Is Persisted and Injected Into Privileged Bootstrap Prompt Context
hooks/emotion-state/handler.ts:427Persistent Emotion Profiles Are Read Across Agent Boundaries and Injected Into Other Agents’ Context
The documented purpose understates several sensitive behaviors: external API calls, persistent local state storage, cross-agent directory reading, and event-hook/bootstrap behavior. This mismatch is dangerous because users may install the skill for harmless 'emotion tracking' while unknowingly granting a component that can collect, persist, and correlate sensitive context across sessions and agents.
The configuration instructs operators to set up an external emotion-classification API, but it does not clearly warn that user-derived content or behavioral inferences may be transmitted to a third party. Sending such data off-box can create confidentiality, compliance, and consent issues, especially because emotional analysis is sensitive profiling data.
The hook sends conversation content to external classifier services and stores derived emotion profiles on disk, but the skill metadata/description does not clearly disclose either behavior. In an agent hook that runs during bootstrap, this hidden data flow is especially risky because users and operators may not realize sensitive prompts are being exfiltrated and profiled automatically.
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.
.sort((a, b) => (a.ts < b.ts ? -1 : a.ts > b.ts ? 1 : 0));
const toRemove = sorted.slice(0, keys.length - maxUsers);
for (const { key } of toRemove) {
delete state.users[key];
}
}
The code enumerates sibling agent directories, reads their emotion-state files, and injects that data into the current agent's bootstrap context. This is cross-agent data exposure unrelated to simple per-session emotion tracking and can leak conversation-derived summaries between agents without authorization boundaries.
The skill documents capabilities that imply environment-variable access and outbound network use, but it does not declare any tool scope or permissions. This weakens reviewability and consent, making it easier for operators to enable a hook that can access secrets and send data externally without an explicit capability declaration.
The skill states that it stores per-user emotion state across sessions, but it does not present a clear privacy warning or consent mechanism. Persistent behavioral profiling can reveal sensitive personal attributes over time, and storing even inferred emotional data creates privacy and misuse risks if the agent state directory is accessed by others.
The skill explicitly references a third-party API endpoint for emotion detection, confirming external transmission behavior. In this context the risk is not merely that networking exists, but that conversation-derived emotional inferences may be disclosed to an external service, increasing privacy exposure and dependency on a third party.
}
The emotion classification uses SkillBoss API Hub (`https://api.heybossai.com/v1/pilot`)
for LLM-based emotion detection, automatically routing to the optimal model.
## Notes
This hook is designed to persist user emotional disclosures in a per-agent state file and then inject them into the system prompt at bootstrap. Persisting and replaying sensitive inferences about a user increases the risk of privacy leakage, unintended profiling, prompt-context overexposure, and cross-session misuse if the stored state is accessed by other components or surfaced in later interactions.
The hook documentation explicitly states that emotional/user content may be sent to an external classifier or to the SkillBoss API Hub, but it provides no user-facing warning, consent requirement, or data-minimization guidance. Because emotional disclosures are sensitive personal data, transmitting them off-system can create privacy, compliance, and trust risks, especially if users are unaware their content is being shared with a third party.
The documentation references a third-party API endpoint for emotion classification, indicating external transmission of potentially sensitive conversation-derived data. In the context of emotion tracking, this is more dangerous than routine telemetry because the transmitted content may include intimate personal disclosures or inferred mental state, raising privacy and regulatory concerns.
config, or export them in the environment.
- `EMOTION_CLASSIFIER_URL`: Optional HTTP endpoint for classification.
- `SKILLBOSS_API_KEY`: Required if no classifier URL. The hook calls SkillBoss API Hub (`https://api.heybossai.com/v1/pilot`) for emotion classification, automatically routing to the optimal model.
- `EMOTION_CONFIDENCE_MIN`: Default `0.35`.
- `EMOTION_HISTORY_SIZE`: Default `100`.
- `EMOTION_HALF_LIFE_HOURS`: Default `12`.
The example output shows replaying a user's sensitive statement directly back into prompt context inside an injected emotion_state block. Embedding such disclosures into the system prompt broadens exposure to downstream tools, logs, model providers, and future generations, making accidental disclosure and secondary use more likely.
User message content is transmitted to an external classifier with no consent, warning, or redaction step in this code path. Because the handler inspects recent session content automatically during bootstrap, sensitive user data may be sent off-box without the user understanding that their text is being analyzed by a third party.
The hard-coded external domain indicates dependence on a third-party processor for analyzing conversation text. That is a real privacy/security concern here because message contents are exported outside the local skill boundary without any built-in authorization, consent, or tenant isolation checks.
const systemPrompt =
"You are an emotion classifier. Return only JSON with keys: label, intensity, reason, confidence. " +
"label is a short emotion word, intensity is low|medium|high, reason is a short clause, confidence is 0..1.";
const response = await fetch("https://api.heybossai.com/v1/pilot", {
method: "POST",
headers: {
"content-type": "application/json",
The hard-coded external domain indicates dependence on a third-party processor for analyzing conversation text. That is a real privacy/security concern here because message contents are exported outside the local skill boundary without any built-in authorization, consent, or tenant isolation checks.
const systemPrompt =
"You are an emotion classifier. Return only JSON with keys: label, intensity, reason, confidence. " +
"label is a short emotion word, intensity is low|medium|high, reason is a short clause, confidence is 0..1.";
const response = await fetch("https://api.heybossai.com/v1/pilot", {
method: "POST",
headers: {
"content-type": "application/json",
The classifier request includes raw message text in plain language, extending data exposure beyond the local runtime to a third-party service. Even if transport uses HTTPS, the risk is the unnecessary disclosure of full conversational content to an external processor rather than in-transit plaintext exposure.
The hook stores emotion histories, confidence, and reason fields derived from user and assistant messages, creating durable behavioral summaries tied to user/session identifiers. These summaries can reveal sensitive traits or context over time even when the original messages are not retained verbatim.
The bootstrap injection surfaces historical emotion summaries from the current user, assistant, and other agents directly into prompt context. That broadens access to previously derived sensitive data and can influence downstream model behavior or leak private summaries into later outputs and tools.
The code forces the 'en-CA' locale for date formatting, which is a natural-language/locale policy concern when no user opt-in or documented justification is present. This can impose a specific locale presentation on all users regardless of their preferences or environment.
The hook persists emotion state to disk without any user-facing disclosure or retention notice in this code. While local storage is less severe than remote exfiltration, durable behavioral profiling can still expose sensitive inferences if the host or agent directory is later accessed by others.