Back to skill

Security audit

Exa Company Research

Security checks for vulnerabilities and agentic risk

Overview

This company-research skill is coherent, but its shell command examples can execute unintended commands if a crafted company name or domain is substituted literally.

Review this skill before installing. It should be used only where the agent can call the Exa CLI with shell-free argument arrays or otherwise safely handle company names, domains, and result IDs. Avoid running the shown templates literally with untrusted input, and be aware it may read local product-marketing context files if they exist.

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

Error
Location
SKILL.md:30
Finding

Shell Command Injection Through Unsafe Template Substitution

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 30–61
Vulnerability Type: Shell command injection
Risk Level: High

The skill instructs the agent to insert user-controlled company names and domains, as well as externally sourced result IDs, directly into shell commands:

bash
node tools/clis/exa.js search --query "[company name] company overview" --num-results 10 --text
bash
node tools/clis/exa.js search --query "[company name] [domain.com] overview" --num-results 10 --text
bash
node tools/clis/exa.js search --query "[company name] company overview" --num-results 10 --dry-run
bash
node tools/clis/exa.js search --query "[company] funding round investment" --num-results 5 --text
node tools/clis/exa.js search --query "[company] leadership team executives" --num-results 5 --text
node tools/clis/exa.js search --query "[company] product features pricing" --num-results 5 --text
node tools/clis/exa.js search --query "[company] news announcement" --num-results 5 --start-date "[30 days ago YYYY-MM-DD]" --text
bash
node tools/clis/exa.js contents --ids "[id1],[id2],[id3]" --text --highlights

Technical Analysis

The documented commands interpolate untrusted values into command strings intended for shell execution. Although the placeholders are enclosed in double quotes, shell double quotes do not prevent command substitution using $() or backticks. An attacker can therefore supply a crafted company name or domain containing shell syntax. Search-result IDs may likewise be unsafe if returned content can influence them.

For example, a company name containing Example $(touch /tmp/exa-injection) would produce:

bash
node tools/clis/exa.js search --query "Example $(touch /tmp/exa-injection) company overview" --num-results 10 --text

If executed through a shell, touch /tmp/exa-injection is evaluated before the Node process starts. Quotation alon ...[truncated 1735 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not create shell command strings by concatenating or substituting user-controlled values.

  2. Invoke Node through an argument-array API such as spawn or execFile with shell processing disabled:

    javascript
    spawn("node", [
      "tools/clis/exa.js",
      "search",
      "--query",
      companyName + " company overview",
      "--num-results",
      "10",
      "--text"
    ], { shell: false });
    
  3. Update the skill instructions to require structured tool invocation or direct API calls rather than executable shell templates.

  4. Validate company domains against a strict domain-name format when a domain is expected.

  5. Validate result IDs against the exact identifier format returned by Exa, rejecting shell metacharacters and unexpected delimiters.

  6. Treat company names as opaque data and pass them as individual process arguments. Allowlist validation alone should not replace shell-free execution.

  7. If shell execution is unavoidable, apply a well-tested, platform-specific shell-escaping library to every dynamic value; do not rely on surrounding values with double quotes.

  8. Run the research tool with least privilege, restricted filesystem access, minimal environment variables, and constrained network permissions to reduce impact if validation fails.

  9. Add security tests using inputs containing $(), backticks, quotes, semicolons, newlines, pipes, and redirection operators, verifying that none are interpreted as shell syntax.

Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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
Findings (1)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The description says to use this skill when the user wants to research a company and includes phrases like 'company info,' 'what does [company] do,' and 'tell me about [company].' These are broad, natural conversational requests without clear boundaries or exclusion conditions, which increases the chance of unintended invocation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.