T08 · Insecure Dependencies
- Location
scripts/scrape.py:38- Finding
Mutable Third-Party Scraping Actor Can Poison Automated Campaign Input
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill does what it says in broad terms, but it can automatically add scraped contacts to a live outbound email campaign and stores lead data locally without strong review or retention controls.
Review this carefully before installing. Use separate low-privilege Apify and Hunter credentials if possible, test against a non-sending campaign first, add a manual approval or dry-run step before campaign writes, and avoid running it where plaintext lead files or console logs may be broadly accessible.
scripts/scrape.py:38Mutable Third-Party Scraping Actor Can Poison Automated Campaign Input
scripts/scrape.py:138Lead Personal Data Is Persisted and Printed Without Data-Minimization Controls
scripts/scrape.py:81Apify and Hunter API Credentials Are Transmitted in URL Query Parameters
This is another instance of materially misleading description-to-behavior mismatch, specifically around claimed LLM use, use of 'your own email,' outbound sending, and the breadth of the automation. In a security context, overclaiming or misdescribing behavior reduces transparency around network activity, data processing, and third-party contact handling, which increases the risk of unsafe deployment.
This is another instance of materially misleading description-to-behavior mismatch, specifically around claimed LLM use, use of 'your own email,' outbound sending, and the breadth of the automation. In a security context, overclaiming or misdescribing behavior reduces transparency around network activity, data processing, and third-party contact handling, which increases the risk of unsafe deployment.
The skill declares no explicit tool scope or permissions even though the content describes use of environment secrets, local file writes, and outbound network access to third-party APIs. That mismatch can cause users or a hosting platform to underestimate what the skill can do, especially since it handles API keys and automates external contact ingestion into an email campaign.
The skill promotes outbound pipeline generation but does not prominently warn that it automates scraping, enrichment, and loading of third-party contacts into a commercial email campaign. In this context, the omission is significant because the skill handles personal/business contact data and enables unsolicited outreach, creating privacy, compliance, and reputational risk for operators.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
def metrics(campaign_id):
api_key = load_api_key()
r = requests.get(
f"https://api.hunter.io/v2/campaigns/{campaign_id}/recipients",
params={"api_key": api_key, "limit": 100},
timeout=15,
)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
def metrics(campaign_id):
api_key = load_api_key()
r = requests.get(
f"https://api.hunter.io/v2/campaigns/{campaign_id}/recipients",
params={"api_key": api_key, "limit": 100},
timeout=15,
)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
def metrics(campaign_id):
api_key = load_api_key()
r = requests.get(
f"https://api.hunter.io/v2/campaigns/{campaign_id}/recipients",
params={"api_key": api_key, "limit": 100},
timeout=15,
)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
def metrics(campaign_id):
api_key = load_api_key()
r = requests.get(
f"https://api.hunter.io/v2/campaigns/{campaign_id}/recipients",
params={"api_key": api_key, "limit": 100},
timeout=15,
)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"website": website,
}]
}
r = requests.post(
f"https://api.hunter.io/v2/campaigns/{campaign_id}/recipients",
params={"api_key": api_key},
json=payload,
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
def run_apify(token, query, location):
"""Trigger Apify Indeed scrape and return raw results."""
url = f"https://api.apify.com/v2/acts/{APIFY_ACTOR}/run-sync-get-dataset-items"
params = {"token": token, "maxItems": MAX_ITEMS}
payload = {
"position": query,
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"country": "US",
"maxItems": MAX_ITEMS,
}
r = requests.post(url, params=params, json=payload, timeout=300)
r.raise_for_status()
return r.json()
The script automatically pushes harvested contact data into a live Hunter.io campaign with no interactive confirmation, dry-run mode, authorization check, or explicit disclosure at execution time. In an agent/skill context, this creates a real risk of unintended external action and privacy/compliance issues if the skill is invoked with real credentials or against an unexpected target set.
This request adds recipients directly to a Hunter.io campaign, causing an immediate state-changing external action using potentially scraped personal/business contact data. In an autonomous skill, such side effects are security-relevant because they can trigger unwanted outreach, compliance issues, or misuse of the user's account without a strong execution guard.
"website": website,
}]
}
r = requests.post(
f"https://api.hunter.io/v2/campaigns/{campaign_id}/recipients",
params={"api_key": api_key},
json=payload,
This Hunter.io endpoint reference is part of the same state-changing recipient-add flow and therefore represents a real externally mutating action, not just passive transmission. In the context of an autonomous outbound skill, that increases the chance of unreviewed bulk outreach or account misuse if invoked improperly.
}]
}
r = requests.post(
f"https://api.hunter.io/v2/campaigns/{campaign_id}/recipients",
params={"api_key": api_key},
json=payload,
timeout=15,
The script persists scraped lead and tracking data to local files without notice, minimization, retention controls, or file-permission hardening. This can expose personal/business contact data to other local users, backups, or later unintended reuse, especially on shared systems or agent hosts.
No suspicious patterns detected.