Back to skill

Security audit

WhatsApp Forward

Security checks for vulnerabilities and agentic risk

Overview

This skill is a small WhatsApp helper that runs a local Node script and has a real VCard input-validation weakness, but its behavior is disclosed, limited, and not malicious.

Install only if you are comfortable using it as a local formatting helper. Avoid feeding it untrusted contact names or phone numbers, and review generated VCards before importing or forwarding them until the escaping and phone validation issue is fixed.

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

Warning
Location
scripts/forward.js:10
Finding

Unescaped User Input Enables VCard Field and Record Injection

Content
View full analysis

Vulnerability Details

File Location: scripts/forward.js, lines 10–19 and 80–94
Vulnerability Type: VCard injection caused by insufficient input validation and output encoding
Risk Level: Medium

Vulnerable Code

Lines 10–19:

javascript
function generateVCard(name, phone) {
  const cleanPhone = phone.replace(/\D/g, '');

  const vcard = `BEGIN:VCARD
VERSION:3.0
N:;${name};;;
FN:${name}
TEL;type=CELL;type=VOICE;waid=${cleanPhone}:+${cleanPhone}
END:VCARD`;

Lines 80–94:

javascript
function multiVCard(contactsJson) {
  try {
    const contacts = JSON.parse(contactsJson);
    const vcards = contacts.map(c => ({
      displayName: c.name,
      vcard: `BEGIN:VCARD
VERSION:3.0
N:;${c.name};;;
FN:${c.name}
TEL;type=CELL;type=VOICE;waid=${c.phone}:+${c.phone}
END:VCARD`
    }));

    console.log(JSON.stringify({ total: vcards.length, vcards }, null, 2));

Technical Analysis

Values controlled through command-line arguments or the multi-vcard JSON document are interpolated directly into structured VCard content. The contact name is not escaped in either generation path. The multiple-contact path also inserts the phone value without applying the digit-only normalization used by generateVCard.

VCard text values require syntax-aware escaping. In particular, untrusted carriage returns or line feeds can introduce new properties because each line represents a VCard field. An attacker can also inject END:VCARD followed by BEGIN:VCARD to append an unauthorized contact record. Unescaped backslashes, semicolons, and commas can alter parsing of structured values.

JSON serialization does not remediate this issue. Although the outer JSON output escapes line breaks for transport, a consumer that parses the JSON obtains the original malicious line breaks inside the vcard string.

Attack Path

  1. An attacker influences a contact name or phone value passed to ...[truncated 1558 chars]
Remediation
View remediation

Remediation Suggestions

  1. Implement a dedicated VCard text-escaping function and apply it to every text field before interpolation:

    javascript
    function escapeVCardText(value) {
      if (typeof value !== 'string') {
        throw new TypeError('VCard text values must be strings');
      }
    
      return value
        .replace(/\\/g, '\\\\')
        .replace(/\r\n|\r|\n/g, '\\n')
        .replace(/;/g, '\\;')
        .replace(/,/g, '\\,');
    }
    
  2. Validate and normalize phone numbers consistently in both generation paths:

    javascript
    function normalizePhone(value) {
      if (typeof value !== 'string') {
        throw new TypeError('Phone number must be a string');
      }
    
      const normalized = value.replace(/\D/g, '');
      if (!/^\d{7,15}$/.test(normalized)) {
        throw new Error('Invalid phone number');
      }
      return normalized;
    }
    
  3. Validate that multi-vcard input is an array and that every entry is a non-null object containing string name and phone properties. Reject malformed records rather than coercing arbitrary values.

  4. Prefer a maintained VCard serialization library that correctly implements the selected VCard version instead of constructing records through raw template interpolation.

  5. Add regression tests covering carriage returns, line feeds, BEGIN:VCARD, END:VCARD, semicolons, commas, backslashes, non-string properties, missing fields, and malformed phone numbers. Verify that no attacker-controlled input can create a physical VCard property or record boundary.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep