Back to skill

Security audit

AI Crush Simulator

Security checks for vulnerabilities and agentic risk

Overview

This skill is a local, heuristic crush-advice tool with no evidence of hidden data access, persistence, or exfiltration, though one reply feature omits the promised disclaimer.

This appears reasonable to install if you are comfortable sharing crush or relationship details with the local skill flow. Treat its advice as lightweight suggestions, not facts about another person, and prefer a version that fixes the missing reply disclaimer and refreshes dev dependencies.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Note
Location
src/modules/replyGenerator.ts:94
Finding
Required Safety Disclaimer Is Missing from Reply Generation Outputs## Vulnerability Details **File Location**: `SKILL.md:22`, `SKILL.md:46`, `SKILL.md:190-191`, `src/types.ts:85-89`, `src/modules/replyGenerator.ts:94-106`, and `cli/main.ts:55-67` **Vulnerability Type**: Missing enforcement of a declared output safety control **Risk Level**: Low The Skill metadata declares `alwaysDisclaimer: true`, and its documentation requires every output to include a disclaimer framed as “Based on what you shared...”. However, the reply-generation result type has no disclaimer field, `generateReplies()` does not return a disclaimer, and the CLI reply renderer does not display one. ### Vulnerable Code `src/types.ts:85-89`: ```ts export interface ReplyOptions { goal: UserGoal; replies: ReplyOption[]; tip: string; } ``` `src/modules/replyGenerator.ts:94-106`: ```ts export function generateReplies(context: ReplyContext): ReplyOptions { const template = TEMPLATES[context.userGoal]; const tones: ReplyTone[] = ['bold', 'chill', 'safe']; const replies: ReplyOption[] = tones.map(tone => ({ tone, text: template[tone].text, rationale: template[tone].rationale, })); return { goal: context.userGoal, replies, tip: template.tip, }; } ``` `cli/main.ts:55-67`: ```ts function printReplies(options: ReturnType<typeof generateReplies>) { section('✏️ Reply Options'); for (const reply of options.replies) { const label = reply.tone === 'bold' ? '🔥 Bold' : reply.tone === 'chill' ? '😎 Chill' : '🙂 Safe'; print(`\n${label}`); print(` "${reply.text}"`); print(` → ${reply.rationale}`); } print(`\n💡 Tip: ${options.tip}`); } ``` ### Technical Analysis The implementation does not enforce the safety contract declared in `SKILL.md`. Other user-facing modules return an explicit disclaimer, but `generateReplies()` returns actionable i ...[truncated 1550 chars]
Remediation
## Remediation Suggestions 1. Add a mandatory `disclaimer: string` property to `ReplyOptions`: ```ts export interface ReplyOptions { goal: UserGoal; replies: ReplyOption[]; tip: string; disclaimer: string; } ``` 2. Define and return the required disclaimer from `generateReplies()`: ```ts const DISCLAIMER = 'Based on what you shared — these are general reply ideas, not facts about what the other person feels. Choose only what feels authentic and respectful to you.'; return { goal: context.userGoal, replies, tip: template.tip, disclaimer: DISCLAIMER, }; ``` 3. Update `printReplies()` and the test renderer to display `options.disclaimer`. 4. Add automated assertions confirming that every public user-facing module returns a non-empty disclaimer beginning with the required framing. 5. Add a policy consistency test that compares mandatory Skill metadata controls with the fields and behavior of every public output type.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The declared description presents a broader coaching skill with multiple user-facing capabilities: analyzing situations, decoding crush texts, generating replies, and advising on next steps. This code chunk only performs one subset of that promise: it combines a few situation fields, runs heuristic scoring and flag detection, derives a connection-depth label, and returns a summary/disclaimer. There is no logic here for text-message decoding as a distinct function, no reply generation, and no concrete recommendation engine for what to do next. The behavior is related to the domain, but the implemented capability in this chunk is materially narrower than the declared description.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger phrases are broad enough that the skill may activate for generic relationship-advice requests, causing unintended invocation and possible routing of sensitive teen/social conversations into this skill. In a youth-focused advice context, accidental activation can increase privacy and safety risk because users may share personal interpersonal details they did not intend for this specific skill flow.

Known Vulnerable Dependency: esbuild==0.27.3 — 1 advisory(ies): GHSA-g7r4-m6w7-qqqr (esbuild allows arbitrary file read when running the development server on Window)

Low
Category
Supply Chain
Confidence
60% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/node": "^25.4.0",
    "tsx": "^4.21.0",
    "typescript": "^5.9.3"
  }
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"license": "ISC",
  "devDependencies": {
    "@types/node": "^25.4.0",
    "tsx": "^4.21.0",
    "typescript": "^5.9.3"
  }
}
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"devDependencies": {
    "@types/node": "^25.4.0",
    "tsx": "^4.21.0",
    "typescript": "^5.9.3"
  }
}
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Static analysis

No suspicious patterns detected.