Back to skill

Security audit

LeadFlow

Security checks for vulnerabilities and agentic risk

Overview

This lead-generation skill is mostly coherent, but it needs Review because it automatically fetches untrusted business websites from the user's network and exports untrusted fields to spreadsheets without adequate safety controls.

Install only if you are comfortable with a CLI that stores lead data locally, calls several external data providers with your API keys, fetches websites discovered from business listings, and can send selected lead data to a webhook URL you provide. Run it in a network-restricted environment if possible, treat generated spreadsheet files as untrusted, avoid debug logging with proxy credentials, and use limited-scope API keys.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
src/enrichment/email-scraper.ts:91
Finding
Unrestricted Website Fetching Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `src/enrichment/enrichment.service.ts:58-63`; `src/enrichment/email-scraper.ts:91-108, 162-177` **Vulnerability Type**: Server-Side Request Forgery (SSRF) **Risk Level**: High ### Vulnerable Code ```ts // src/enrichment/enrichment.service.ts:58-63 logger.debug(`Waterfall step 1: website scrape for ${domain}`); try { const scrapeResult = await scrapeWebsiteForEmails(lead.website!); if (scrapeResult.success && scrapeResult.emails.length > 0) { const best = scrapeResult.emails[0]!; ``` ```ts // src/enrichment/email-scraper.ts:91-108 let baseUrl = websiteUrl.trim(); if (!baseUrl.startsWith('http://') && !baseUrl.startsWith('https://')) { baseUrl = 'https://' + baseUrl; } // Remove trailing slash baseUrl = baseUrl.replace(/\/$/, ''); const urlObj = new URL(baseUrl); const domain = urlObj.hostname.replace('www.', ''); logger.debug(`Scraping ${baseUrl} for emails`); // Try each contact path for (const path of CONTACT_PATHS) { const pageUrl = baseUrl + path; try { const pageEmails = await scrapePageForEmails(pageUrl, domain); ``` ```ts // src/enrichment/email-scraper.ts:162-177 const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 10000); try { const response = await fetch(url, { signal: controller.signal, headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', }, redirect: 'follow', }); ``` ### Technical Analysis The enrichment waterfall automatically fetches website URLs stored in lead records. These URLs originate from external business listings and are not validated as public Internet destinations before being passed to `fetch`. The implementation accepts both HTTP and HTTPS, follows redirects automatically, and ...[truncated 2054 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse each URL and permit only the `http:` and `https:` schemes. 2. Reject URLs containing usernames or passwords. 3. Resolve the hostname before every request and reject all loopback, private, link-local, reserved, multicast, and unspecified IPv4 and IPv6 ranges. 4. Explicitly block common metadata destinations, including `169.254.169.254`, but do not rely on a metadata-only blocklist. 5. Disable automatic redirects and validate each redirect destination before following it. 6. Protect against DNS rebinding by connecting only to the validated resolved address while preserving correct TLS hostname verification. 7. Consider routing website scraping through a restricted egress proxy or isolated worker with no private-network access. 8. Require explicit confirmation before fetching URLs not originating from an approved provider. 9. Add tests for decimal, hexadecimal, octal, IPv4-mapped IPv6, shortened IPv4, DNS-rebinding, and redirect-based bypasses. 10. Limit response size and accepted content types to reduce resource-exhaustion and unintended data-processing risks. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
src/export/xlsx.exporter.ts:216
Finding
CSV Exports Permit Spreadsheet Formula Injection<![CDATA[ ## Vulnerability Details **File Location**: `src/export/xlsx.exporter.ts:216-240, 277-318, 351-370` **Vulnerability Type**: CSV/Spreadsheet Formula Injection **Risk Level**: High ### Vulnerable Code ```ts // src/export/xlsx.exporter.ts:216-240 const rows = leads.map((lead) => { const exportLead = leadToExportRow(lead); return headers .map((header) => { const value = exportLead[header as keyof ExportLead]; // Escape quotes and wrap in quotes if contains comma if (value.includes(',') || value.includes('"') || value.includes('\n')) { return `"${value.replace(/"/g, '""')}"`; } return value; }) .join(','); }); const csv = [headers.join(','), ...rows].join('\n'); ``` ```ts // src/export/xlsx.exporter.ts:277-318 const instantlyRows = leads.map((lead) => { const nameParts = splitName(lead.contactName); return [ lead.email ?? '', nameParts.firstName, nameParts.lastName, lead.companyName, formatPhoneDisplay(lead.phone), lead.website ?? '', lead.city ?? '', lead.state ?? '', lead.trade, lead.source, lead.rating?.toString() ?? '', ] .map((value) => { // Escape quotes and wrap if contains comma/quote/newline if (value.includes(',') || value.includes('"') || value.includes('\n')) { return `"${value.replace(/"/g, '""')}"`; } return value; }) .join(','); }); ``` ```ts // src/export/xlsx.exporter.ts:351-370 function csvEscape(value: string): string { if (value.includes(',') || value.includes('"') || value.includes('\n')) { return `"${value.replace(/"/g, '""')}"`; } return value; } async function writeCsvFile(path: string, headers: string[], rows: string[][]): Promise<void> { const dir = dirname(path); if (!existsSync(dir)) { await mkdir(dir, { recursive: true }); } const csv = [ headers.join(','), ...rows.map(row => row.map(csvEscape).join(',')), ].join('\n'); const { writeFile } = a ...[truncated 2154 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Implement one centralized spreadsheet-cell sanitizer and use it for every CSV and XLSX field. 2. Before CSV quoting, detect values whose first effective character is `=`, `+`, `-`, or `@`. 3. Also detect leading tabs, carriage returns, newlines, Unicode whitespace, and other characters that spreadsheet applications may ignore before formula evaluation. 4. Neutralize dangerous cells using an application-compatible strategy, such as prefixing an apostrophe and documenting the resulting display behavior. 5. Do not rely on enclosing the value in double quotes; quoting is CSV syntax, not formula neutralization. 6. Apply equivalent protections to values written through ExcelJS, explicitly forcing untrusted content to be plain text where necessary. 7. Preserve separate raw and export-safe representations if exact original values must remain available. 8. Add regression tests for standard formulas, DDE-style payloads, hyperlink and web-request formulas, leading whitespace, tab-prefixed payloads, and all export formats. 9. Warn users that existing exports created before the fix should be treated as untrusted. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
src/enrichment/hunter.client.ts:30
Finding
Hunter API Credential Is Embedded in Request URLs<![CDATA[ ## Vulnerability Details **File Location**: `src/enrichment/hunter.client.ts:30-43, 59-70, 82-91` **Vulnerability Type**: Sensitive Credential Exposure Through URL Query Parameters **Risk Level**: Medium ### Vulnerable Code ```ts // src/enrichment/hunter.client.ts:30-43 const params = new URLSearchParams({ domain, api_key: getApiKey(), limit: String(options?.limit ?? 10), }); if (options?.type) params.set('type', options.type); const url = `${BASE_URL}/domain-search?${params}`; logger.debug(`Hunter domain search: ${domain}`); const res = await fetch(url, { signal: AbortSignal.timeout(15000) }); ``` ```ts // src/enrichment/hunter.client.ts:59-70 const params = new URLSearchParams({ domain, first_name: firstName, last_name: lastName, api_key: getApiKey(), }); const url = `${BASE_URL}/email-finder?${params}`; logger.debug(`Hunter email finder: ${firstName} ${lastName} @ ${domain}`); const res = await fetch(url, { signal: AbortSignal.timeout(15000) }); ``` ```ts // src/enrichment/hunter.client.ts:82-91 const params = new URLSearchParams({ email, api_key: getApiKey(), }); const url = `${BASE_URL}/email-verifier?${params}`; logger.debug(`Hunter verify email: ${email}`); const res = await fetch(url, { signal: AbortSignal.timeout(15000) }); ``` ### Technical Analysis All Hunter API operations place `HUNTER_API_KEY` in the query string. Although HTTPS protects the URL while it is transmitted over the encrypted connection, complete URLs may still be retained by local diagnostics, outbound proxies, gateways, observability systems, tracing instrumentation, browser-like tooling, or provider-side access logs. The project logger does not define secret-redaction rules. The shown code does not directly log the full Hunter URL, but embedding credentials in URL objects increases the chance that exceptions, HTTP instrumentation, or future logging changes will disclose them. The data is sent only to the declared Hunter HTTPS endpoint, so thi ...[truncated 998 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use an authorization header or another non-URL authentication mechanism if supported by the Hunter API. 2. If query-string authentication is required by the provider, isolate URL construction and ensure the credential-bearing URL is never logged. 3. Configure Pino and any HTTP instrumentation to redact `api_key`, authorization values, and other secret parameters. 4. Sanitize errors before logging because HTTP libraries or observability tools may include complete request URLs. 5. Review outbound proxy, gateway, tracing, and provider logging retention policies. 6. Use a narrowly scoped credential where the provider supports scoping. 7. Rotate any key suspected of appearing in historical diagnostic logs. 8. Add automated tests confirming that errors and debug output never contain the configured API key. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
src/core/http/proxy-rotator.ts:48
Finding
Authenticated Proxy URLs Can Be Written to Logs Without Redaction<![CDATA[ ## Vulnerability Details **File Location**: `src/core/http/proxy-rotator.ts:48-60, 76-86, 143-149`; `src/utils/logger.ts:9-29` **Vulnerability Type**: Proxy Credential Exposure Through Logging **Risk Level**: Medium ### Vulnerable Code ```ts // src/core/http/proxy-rotator.ts:48-60 addProxies(urls: string[]): void { for (const url of urls) { const type = this.detectProxyType(url); this.proxies.push({ url, type, failCount: 0, successCount: 0, }); } logger.info(`Added ${urls.length} proxies (total: ${this.proxies.length})`); } ``` ```ts // src/core/http/proxy-rotator.ts:76-86 const totalRequests = proxy.successCount + proxy.failCount; if (totalRequests > 0) { const failRate = proxy.failCount / totalRequests; if (failRate >= this.maxFailRate) { if (this.autoRemove) { logger.warn(`Removing proxy ${proxy.url} (fail rate: ${(failRate * 100).toFixed(1)}%)`); this.proxies.splice(this.currentIndex, 1); ``` ```ts // src/core/http/proxy-rotator.ts:143-149 markFailure(proxy: Proxy): void { proxy.failCount++; logger.debug( `Proxy ${proxy.url} failed (${proxy.failCount}/${proxy.successCount + proxy.failCount} requests)` ); } ``` ```ts // src/utils/logger.ts:9-29 export const logger = pino({ level: config.LOG_LEVEL, transport: config.NODE_ENV === 'development' ? { target: 'pino-pretty', options: { colorize: true, translateTime: 'SYS:standard', ignore: 'pid,hostname', destination: 2, }, } : undefined, base: { pid: process.pid, }, timestamp: pino.stdTimeFunctions.isoTime, }, config.NODE_ENV !== 'development' ? pino.destination(2) : undefined); ``` ### Technical Analysis Proxy agent libraries accept credential-bearing URLs in the conventional form: ```text https://username:password@proxy.example:8443 ``` `ProxyRotator` stores the complete URL and interpolates it into warning an ...[truncated 1595 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse proxy URLs when they are registered and separate credentials from displayable endpoint metadata. 2. Never interpolate raw proxy URLs into logs. 3. Log only a sanitized identifier, protocol, hostname, and port, for example `https://proxy.example:8443`. 4. Configure Pino redaction for credential-bearing fields and avoid placing secrets inside free-form message strings that structured redaction cannot process. 5. Store proxy credentials in dedicated secret fields rather than in the URL where supported by the proxy-agent API. 6. Ensure exception messages from proxy libraries are sanitized before logging. 7. Default production logs to `info` or higher and ensure debug logging cannot expose secrets. 8. Add tests using URLs containing usernames and passwords and assert that neither value appears in any log level. 9. Rotate proxy credentials if historical logs may already contain authenticated URLs. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (117)

Credential Access

High
Category
Privilege Escalation
Content
```bash
# 1. Set up your API keys
cp .env.example .env
# Edit .env — only GOOGLE_PLACES_API_KEY is required to get started

# 2. Scrape dental and legal businesses in Miami
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
```bash
# 1. Set up your API keys
cp .env.example .env
# Edit .env — only GOOGLE_PLACES_API_KEY is required to get started

# 2. Scrape dental and legal businesses in Miami
leadflow scrape -t dental,legal -l "Miami, FL" --max-results 100
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
```bash
# 1. Set up your API keys
cp .env.example .env
# Edit .env — only GOOGLE_PLACES_API_KEY is required to get started

# 2. Scrape dental and legal businesses in Miami
leadflow scrape -t dental,legal -l "Miami, FL" --max-results 100
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
```bash
# 1. Set up your API keys
cp .env.example .env
# Edit .env — only GOOGLE_PLACES_API_KEY is required to get started

# 2. Scrape dental and legal businesses in Miami
leadflow scrape -t dental,legal -l "Miami, FL" --max-results 100
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
```bash
# 1. Set up your API keys
cp .env.example .env
# Edit .env — only GOOGLE_PLACES_API_KEY is required to get started

# 2. Scrape dental and legal businesses in Miami
leadflow scrape -t dental,legal -l "Miami, FL" --max-results 100
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The supplied code chunk does not implement the advertised lead-list generation workflow. It merely configures scraper sources and operational parameters such as rate limits, retries, circuit breakers, and proxy/browser needs. While Google Maps and Yelp are present as enabled sources, the main declared capabilities—scraping leads, enriching emails, verifying contacts, scoring quality, and exporting to CRM—are not evidenced here. Additionally, the code references other lead sources not mentioned in the description, though that alone is less significant than the absence of the core advertised behavior. Therefore, the description materially overstates what this code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description presents a full end-to-end lead generation and enrichment system. However, the provided code chunk is only a minimal barrel file that re-exports deduplication functionality. Based on this chunk alone, the observable behavior is limited to exposing a matcher/deduplication module, which is only a supporting utility and not representative of the broad capabilities claimed in the description. This is a material description-behavior mismatch because the actual code shown does not substantiate the primary advertised purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description promises an end-to-end lead list generation and enrichment product. The supplied code does not perform scraping, external data collection, email lookup, verification, scoring, or CRM integration. Instead, it is a narrowly scoped internal deduplication module using Fuse.js and simple merge logic for lead records. This is a materially different primary purpose from the declared description, so the description does not accurately represent this code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Yes, this is a mismatch based on the supplied code chunk. The declared description presents a full end-to-end lead generation system with specific business functionality. The actual code shown is only an index file that re-exports generic HTTP infrastructure modules. While such modules could support the described system, this chunk does not demonstrate the declared primary purpose or any of the key advertised capabilities. Therefore, the description is not accurately represented by this code chunk alone.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description promises end-user lead generation functionality: scraping business listings, enriching emails via multiple providers, verifying contacts, scoring leads, and exporting to CRM systems. The actual code chunk does none of those things directly. Instead, it provides infrastructure for rotating proxies to avoid blocks during network activity. While proxy rotation could be a supporting implementation detail for a scraper, this specific chunk’s behavior is not represented in the declared description, and its primary purpose is network proxy management rather than lead-list generation. Therefore this code chunk does not accurately match the declared description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description describes a full lead-generation and data-enrichment product. However, the provided code chunk only contains infrastructure for HTTP/request throttling via a token bucket rate limiter. It does not scrape websites, process leads, enrich or verify emails, score contacts, or export to a CRM. While rate limiting could be a supporting component inside such a system, this specific chunk’s actual behavior is limited to request pacing and does not substantively implement the declared end-user functionality. Therefore, the description does not accurately represent what this code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description promises a business-facing lead-list generation system with web scraping, contact enrichment, verification, scoring, and CRM export. The supplied code does none of those things. It only provides a circuit breaker abstraction for protecting async operations from repeated failures, plus metrics and logging. While such resilience code could support a larger scraping platform, this chunk's actual behavior is infrastructural and not representative of the declared end-user functionality. Therefore, the description does not accurately represent this code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description promises a full lead-generation workflow with scraping external platforms, enriching/verifying contacts, scoring, and exporting results. The supplied code chunk contains only a simple index file that re-exports resilience utilities (`retry` and `circuit-breaker`). This is infrastructure/support code and does not substantiate the claimed primary functionality. Based on the provided chunk, the actual behavior is materially different from the declared purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description promises an end-to-end city-to-lead-list system with scraping, enrichment, verification, scoring, and CRM export. The actual code does none of those domain-specific tasks. It only provides infrastructure for retrying async operations after transient failures, including rate-limit handling and exponential backoff. While retry logic could be a supporting component inside a scraper, this chunk by itself is not representative of the declared purpose and instead reflects a materially different primary behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The description presents a broad end-to-end lead generation system, but this code chunk is narrowly focused on one enrichment provider: Dropcontact. It sends company/person data to an external API to retrieve email information and derives a basic confidence score from the returned qualification. There is no evidence here of scraping Google Maps or Yelp, orchestrating a 4-provider waterfall, verifying contacts, producing comprehensive 0-100 quality scores, exporting to a CRM, or generating lead lists from a city. Because the declared purpose substantially overstates and differs from the observed behavior of this code chunk, this is a mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The code chunk is narrowly focused on scraping email addresses from provided company websites. It fetches a base URL and several common subpages, regex-extracts email addresses, filters generic or excluded domains, and assigns heuristic confidence scores to found emails. This is only one small subcomponent of the declared product. The declared description emphasizes a full lead-generation pipeline from city search sources (Google Maps/Yelp), enrichment, verification, lead scoring, and CRM export. None of those major capabilities appear in this code chunk. While the email scraping behavior could support the broader product, the supplied code does not accurately represent the declared end-to-end functionality on its own, so this is a mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared description presents a broad end-to-end lead generation workflow: source businesses from Google Maps/Yelp, enrich and verify contacts, score lead quality, and export to CRM. The supplied code only covers one subsystem: enriching existing leads with an email via a provider waterfall and storing basic enrichment metadata. While the 4-provider waterfall portion substantially matches part of the description, several core advertised capabilities are absent from this code chunk, especially city-based lead generation, Google Maps/Yelp scraping, verification workflow, scoring, and CRM export. Therefore the description does not accurately represent what this specific code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
This code does implement a subset of the declared functionality: email enrichment and email verification. However, the description presents the skill primarily as an end-to-end city-to-lead-list system with scraping from Google Maps and Yelp, multi-provider waterfall enrichment, lead scoring, and CRM export. None of those broader behaviors appear in this code chunk. Instead, the chunk is narrowly an API client for a single provider, Hunter.io, including domain search, person email finding, verification, and a simple best-email selection routine. That is a materially narrower and somewhat different behavior than the declared description, so this should be flagged as a mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The supplied code chunk is narrowly focused on phone-number validation via Twilio Lookup: it authenticates to Twilio, looks up phone metadata, maps line types, and batch-validates numbers. This does not match the declared headline functionality of city-to-lead-list generation, business scraping, email enrichment, lead scoring, or CRM export. While phone/contact verification could be considered loosely related to 'verifies contacts,' the specific implemented capability here is Twilio-based phone validation, which is only a small supporting piece and does not represent the declared purpose of the skill. Therefore this code chunk materially differs from the description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description presents a full lead-generation and enrichment workflow. However, the supplied code chunk contains only a TypeScript barrel file that re-exports error classes from another module. This behavior is merely structural/supporting code and does not substantiate any of the claimed core capabilities. Based on the provided chunk, the actual behavior is materially different from the declared purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description presents a comprehensive lead scraping, enrichment, verification, scoring, and CRM-export system. The provided code chunk, however, is only an index file that re-exports './xlsx.exporter.js'. Based on this chunk alone, the observable behavior is limited to exposing XLSX export functionality. That is a materially narrower and different capability set than the declared purpose. While export functionality may be one supporting part of the described skill, the supplied code does not substantiate the core advertised behaviors, so the description does not accurately represent what this code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description presents a full lead-generation and enrichment workflow, but this code chunk is narrowly focused on exporting already-stored leads. It reads leads from storage, formats them into spreadsheets/CSV variants, writes files to disk, and in one path marks leads as exported. While export is part of the declared feature set, the chunk does not implement the core advertised capabilities of scraping, enrichment, verification, or city-to-lead-list generation. It also says 'exports straight to your CRM,' but the code shown produces local CSV/XLSX files formatted for various CRMs rather than performing direct CRM integrations via API. Therefore, the supplied code does not accurately represent the declared primary purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description promises a full lead-generation and enrichment workflow with multiple concrete capabilities. However, the supplied code chunk contains only barrel exports from internal modules and no visible implementation of those behaviors. Based on this chunk alone, the actual behavior is just exposing library modules for programmatic use. That is materially different from the declared operational purpose, so this should be flagged as a mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Based solely on the supplied code chunk, the implementation does not substantiate the extensive functionality claimed in the description. The file is only an index module that re-exports another orchestrator file, so the actual behavior observable here is limited to module export wiring. Because none of the declared primary capabilities are implemented or evidenced in this chunk, the description does not accurately represent the supplied code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
The code supports part of the description: scraping leads from multiple sources, handling multiple trades/locations, deduplicating, saving, and progress reporting. However, several prominent advertised capabilities are absent from this chunk: email enrichment via a 4-provider waterfall, contact verification, lead scoring, and CRM export. The source handling is also generic rather than specifically demonstrating Google Maps and Yelp. This makes the declared description materially broader than the actual behavior shown here.

Static analysis

No suspicious patterns detected.