Back to skill

Security audit

lead-contact-enrichment-agent

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to provide real lead enrichment, but it needs review because it can send sensitive request text and contact data externally, run a broadly discovered local CLI, and store enriched data insecurely in temporary files.

Install only if you are comfortable sending lead, contact, company, and possibly full request text to Explorium. Avoid entering API keys through the documented command-line or echoed setup prompt, review where result files are written, clean up /tmp result files, and open exported CSVs cautiously. This is not clearly malicious, but the broad CLI discovery and sensitive data handling should be fixed before routine use with real customer or contact datasets.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:137
Finding

Unnecessary Transmission of the User's Complete Request

Content
View full analysis
" # Match the person MATCH_RESULT=$(python3 "$CLI" match-prospect \ --prospects '[{"full_name":"Jane Smith","company_name":"Acme Corp","email":"jane@acme.com"}]' \ --plan-id "$PLAN_ID" --call-reasoning "$QUERY") cat "$MATCH_RESULT" ``` The CLI converts these arguments into remotely transmitted request metadata: ```python def _add_tracking_args(parser) -> None: """Add optional request-context tracking args to any API-calling subcommand.""" parser.add_argument( "--call-reasoning", default=None, metavar="TEXT", help="The user query that triggered this call (e.g. 'find 500 healthcare PMs')", ) parser.add_argument( "--plan-id", default=None, metavar="UUID", help="Unique ID grouping all CLI calls made to answer a single user query", ) def _request_context(args): """Build the optional request_context payload for server-side call grouping. Privacy note: when --call-reasoning is supplied, the user's query text is sent to api.explorium.ai as part of the request metadata. This is opt-in — omit --call-reasoning if the user has not consented to query logging. """ reasoning = getattr(args, "call_reasoning", None) plan_id = getattr(args, "plan_id", None) if not reasoning and not plan_id: return None return { "type": "vibe-prospecting-plugin", "call_reasoning": reasoning, "plan_id": plan_id, } ``` ### Technical Analysis Entity identifiers and matching fields must be sent to Explorium for the declared enrichment functionality. The complete original natural-language request is not techni ...[truncated 1892 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
bin/agentsource.py:114
Finding

Predictable and Insecure Temporary Files Store Contact PII

Content
View full analysis
pathlib.Path: ts = int(time.time()) return TEMP_DIR / f"agentsource_{ts}_{command}.json" def write_result(command: str, data: dict) -> pathlib.Path: path = make_temp_path(command) path.write_text(json.dumps(data, indent=2, default=str)) print(str(path)) return path def write_error(command: str, error_msg: str, error_code: str = None, http_status: int = None) -> pathlib.Path: data = { "success": False, "error": error_msg, "error_code": error_code, "http_status": http_status, "command": command, "timestamp": int(time.time()), } path = make_temp_path(f"{command}_error") path.write_text(json.dumps(data, indent=2)) print(str(path)) return path ``` Imported CSV content is written in full: ```python write_result("from_csv", { "success": True, "source_csv": str(p), "total_rows": len(rows), "columns": columns, "data": rows, "sample": rows[:5], }) ``` Enriched data is also written in full: ```python write_result("enrich", { "success": True, "entity_type": entity_type, "enrichments_applied": enrichments, "total_fetched": len(enriched), "data": enriched, "sample": enriched[:5], }) ``` ### Technical Analysis Temporary filenames are based only on the current timestamp in seconds and the command name. They are consequently predictable and can collide when the same command is executed more than once during a second. The files are created in the shared `/tmp` directory using `Path.write_text()`. This operation does not provide exc ...[truncated 1797 chars]
Remediation
View remediation

T07 · Tool Hijacking and Spoofing

Error
Location
SKILL.md:65
Finding

Broad CLI Discovery Allows Local Tool Substitution

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
setup.sh:79
Finding

API-Key Setup Exposes the Secret Through Terminal Input, Output, and Process Arguments

Content
View full analysis
"$CONFIG_FILE" chmod 600 "$CONFIG_FILE" echo "[OK] API key saved to $CONFIG_FILE (mode 600, owner read-only)" echo "" echo "To also set it as an environment variable, add this to ~/.zshrc or ~/.bashrc:" echo " export EXPLORIUM_API_KEY='$api_key'" ``` The documented alternative places the secret in a command-line argument: ```bash export EXPLORIUM_API_KEY=your_api_key_here # Or: python3 ~/.agentsource/bin/agentsource.py config --api-key your_api_key_here ``` The CLI exposes the corresponding option: ```python p = sub.add_parser("config", help="Save API key to ~/.agentsource/config.json") p.add_argument("--api-key", metavar="KEY") ``` ### Technical Analysis The setup prompt uses `read -r` without `-s`, so terminal echo remains enabled while the API key is entered. The script later prints the complete key as part of a suggested shell export command. The `config --api-key ` interface places the key in the process argument vector and commonly in shell history. Depending on the operating system and environment, process arguments may be visible to other local users, monitoring systems, terminal capture, audit tooling, or support logs. The configuration file is changed to mode `0600`, which appropriately limits subsequent file access. However, that protection does not mitigate exposure during input, display, or command-line invocation. The setup script also interpolates the key directly into JSON rather than using a JS ...[truncated 1247 chars]
Remediation
View remediation
` from recommended setup instructions. 4. Accept the key through protected standard input, a secure credential store, or a narrowly scoped environment variable. 5. Warn users that shell startup files store secrets in plaintext and recommend an operating-system keychain or secret manager where available. 6. Serialize the configuration using Python's `json` module rather than shell string interpolation. 7. Retain mode `0600` and additionally ensure `~/.agentsource` has restrictive directory permissions. 8. Provide key revocation and rotation guidance for users who may have followed the insecure workflow. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
bin/agentsource.py:617
Finding

CSV Export Does Not Neutralize Spreadsheet Formula Injection

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill presents itself primarily as an enrichment plugin, but it also includes operational steps for CLI discovery, local installation/config expectations, API key configuration, and local state management under ~/.agentsource. While not inherently malicious, this broader operational footprint is not clearly disclosed and can surprise users with credential handling and filesystem side effects.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill presents itself primarily as an enrichment plugin, but it also includes operational steps for CLI discovery, local installation/config expectations, API key configuration, and local state management under ~/.agentsource. While not inherently malicious, this broader operational footprint is not clearly disclosed and can surprise users with credential handling and filesystem side effects.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill invokes shell commands, reads and writes local files, accesses environment variables, and sends data to a remote API, yet it declares no explicit tool scope or permission boundaries. This creates an overprivileged integration surface where a host agent may grant broad capabilities without user-visible constraints, increasing the chance of unintended file access, command execution, or data disclosure.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger phrases are broad and overlap with ordinary language such as 'add data to', 'fill in missing', or 'get more data on', which can cause accidental invocation on unrelated user requests. In this skill, accidental activation is more concerning because the workflow can lead to shell execution, file handling, and remote transmission of user-provided business/contact data.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The skill explicitly transmits search filters, entity IDs, and optional request metadata to an external API endpoint. Because the skill handles lead, contact, and company enrichment, that outbound data may contain sensitive business intelligence or personal contact information, making external transmission a real privacy and compliance concern if not tightly disclosed and consented to.

Content

Scanner excerpt · SKILL.md (reported line 49)May include surrounding context.

md
- "get contact info for"
metadata:
  required_env_vars: "EXPLORIUM_API_KEY — your Explorium AgentSource API key. Set via environment variable or run: python3 <cli_path> config --api-key <key>"
  data_sent_to_remote: "Search filters, entity IDs, and optional request metadata are sent to https://api.explorium.ai/v1/. See README for full details."
---

# Lead & Contact Data Enrichment Agent

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · SKILL.md (reported line 85)May include surrounding context.

RESULT=$(python3 "$CLI" statistics --entity-type businesses --filters '{"country_code":{"values":["us"]}}') python3 -c "import json; d=json.load(open('$RESULT')); print(d.get('error_code','OK'))"

text
If it prints `AUTH_MISSING`, show secure API key setup instructions (never ask the user to paste keys in chat).

---

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest positions the skill as CRM enrichment/list cleaning, but this code also supports broader prospect discovery via statistics, fetch, autocomplete, and matching workflows. That scope expansion matters because it can cause users or higher-level agents to disclose data or invoke lead-generation capabilities they did not knowingly authorize, creating a deceptive-capability and consent problem even if the code is not overtly malicious.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The events command exposes business event intelligence beyond simple record enrichment, which materially expands surveillance/monitoring capability relative to the stated use case. In an agent ecosystem, hidden monitoring features are dangerous because they bypass informed user consent and can be used for competitive intelligence or profiling outside expected CRM hygiene workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The tool exports fetched or enriched contact/company data to any user-specified local path without guardrails, warnings, or minimization. Because this skill handles potentially sensitive business contact information, silent persistence can create unintended local data retention, broaden access to PII, and increase exfiltration risk through shared directories, backups, or later processes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The example describes bulk enrichment of contact records with personal and professional data such as emails, phone numbers, LinkedIn URLs, and work history, but it does not warn the user that this workflow processes personal data and may trigger privacy, consent, and data-governance obligations. In a CSV-based bulk workflow, users may upload hundreds of records at once, making it easy to process personal data at scale without understanding compliance or sensitivity implications.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The example explicitly demonstrates retrieving and displaying a named individual's direct email address, phone number, and LinkedIn profile without any privacy notice, consent check, or usage limitation. In a lead-enrichment context this can normalize collection and disclosure of personal contact data, increasing the risk of privacy violations, unauthorized prospecting, and misuse of sensitive professional contact information.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · README.md (reported line 68)May include surrounding context.

md
#   ~/.agentsource/config.json          — API key storage (mode 600, only if you choose to save it)
#
# Nothing is sent to any network during setup. The API key is only used when
# you run CLI commands that call https://api.explorium.ai/v1/.

PLUGIN_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INSTALL_DIR="$HOME/.agentsource"

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · bin/agentsource.py (reported line 33)May include surrounding context.

python
#   ~/.agentsource/config.json          — API key storage (mode 600, only if you choose to save it)
#
# Nothing is sent to any network during setup. The API key is only used when
# you run CLI commands that call https://api.explorium.ai/v1/.

PLUGIN_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INSTALL_DIR="$HOME/.agentsource"

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · setup.sh (reported line 12)May include surrounding context.

sh
#   ~/.agentsource/config.json          — API key storage (mode 600, only if you choose to save it)
#
# Nothing is sent to any network during setup. The API key is only used when
# you run CLI commands that call https://api.explorium.ai/v1/.

PLUGIN_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INSTALL_DIR="$HOME/.agentsource"

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · setup.sh (reported line 46)May include surrounding context.

sh
echo "[OK] Python $PYTHON_VERSION"

# ---------------------------------------------------------------------------
# 2. Create directory structure
# ---------------------------------------------------------------------------
mkdir -p "$BIN_DIR"
echo "[OK] Created $BIN_DIR"

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · setup.sh (reported line 75)May include surrounding context.

sh
if [[ "${save_key:-}" =~ ^[Yy]$ ]]; then
        printf '{\n  "api_key": "%s"\n}\n' \
            "$EXPLORIUM_API_KEY" > "$CONFIG_FILE"
        chmod 600 "$CONFIG_FILE"
        echo "[OK] API key saved to $CONFIG_FILE (mode 600, owner read-only)"
    fi
else

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · setup.sh (reported line 85)May include surrounding context.

sh
if [[ "${save_key:-}" =~ ^[Yy]$ ]]; then
        printf '{\n  "api_key": "%s"\n}\n' \
            "$EXPLORIUM_API_KEY" > "$CONFIG_FILE"
        chmod 600 "$CONFIG_FILE"
        echo "[OK] API key saved to $CONFIG_FILE (mode 600, owner read-only)"
    fi
else

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The skill instructs exporting results to a local path under ~/Downloads without a clear warning that a file will be created or potentially overwritten. This can lead to unintended local data persistence, leakage of enriched personal/business data, or accidental replacement of an existing file.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The CLI self-describes as 'B2B prospecting' while the manifest markets the skill as enrichment/CRM hygiene, indicating a capability mismatch. This inconsistency increases the risk of deceptive deployment, where users believe they are only appending data to existing records but the tool can be used for broader prospecting tasks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

For markdown files, SQP-2 applies when the description omits warnings about behaviors that could affect user data or system integrity. The line states that the agent offers a CSV export, but there is no disclosure that this may create or save a file containing the enriched dataset.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.