T09 · Insecure Skill Coding Practices
- Location
SKILL.md:47- Finding
Shell Command Injection Through Unsafe JSON Interpolation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill performs the advertised lead-scanning workflow, but it handles personal lead data and CRM updates with enough scoping and safety gaps that it should be reviewed before installation.
Review this before installing. Use dedicated least-privilege Slack, Apollo, and HubSpot credentials; confirm that sending badge/business-card data to Apollo and HubSpot is authorized; consider disabling personal email and phone reveal unless required; make the DM recipient configurable; and implement the HTTP calls with safe JSON serialization and safe temporary-file handling rather than literal shell string substitution.
SKILL.md:47Shell Command Injection Through Unsafe JSON Interpolation
SKILL.md:44Predictable Temporary File Allows Symlink-Based File Overwrite
The cleanup command interpolates a message timestamp into a shell command: rm /tmp/lead-[ts].jpg. If ts is not strictly validated and shell-escaped, an attacker who can influence that value or the generated filename could trigger command injection or unintended file deletion. In an agent/tooling context, shelling out with untrusted parameters is especially dangerous because it can turn message data into arbitrary local command execution.
i. Track DM timestamp from response, add to pending_dm_replies in state
j. React ✅ on original #leadscanner message
k. Add msg ts to processed_ids, update last_ts
l. Cleanup: `rm /tmp/lead-[ts].jpg`
### Part 2: Check DM Replies for HubSpot Updates
The manifest description says the skill will 'reply in-thread with summary and link' for scanned leads. However, the detailed workflow in the file routes the summary to a DM with Mark (L051) and tracks DM replies there, while only adding a ✅ reaction on the original channel message (L053). This is a material behavior mismatch in where lead data is delivered.
The skill processes images of badges/business cards and transmits extracted personal data to Apollo and HubSpot, but the description omits any user warning or consent/privacy notice. That creates a real data-governance and privacy risk because operators may use the skill without understanding that lead PII is being sent to third parties and potentially enriched with additional personal data.
The overview line says 'reply in-thread,' which indicates responses should go into the Slack thread tied to the original lead message. Later workflow steps contradict that by instructing the skill to 'Send DM to Mark' and manage updates through DM threads (L051-L052, L057-L070). This is an active contradiction within the file's own documentation.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
### Part 1: Process New #leadscanner Messages
1. Load state from ~/clawd/memory/slack-lead-scanner-state.json
2. Fetch messages: `curl -H "Authorization: Bearer $SLACK_TOKEN" "https://slack.com/api/conversations.history?channel=C0AQAJ8VD8A&oldest=[last_ts]&limit=50"`
3. Filter: ts > last_ts, not in processed_ids, has files or non-empty text
4. For each new message:
a. Download image: `curl -H "Authorization: Bearer $SLACK_TOKEN" "[file.url_private_download]" -o /tmp/lead-[ts].jpg`
The skill sends extracted lead data to Apollo, including a request to reveal personal emails and phone numbers. This is a meaningful privacy and data-minimization risk because sensitive personal/business-card data is being disclosed to a third party for enrichment, potentially beyond what the lead originally provided or what the operator expects.
b. Analyze with image tool: "Extract structured data from this badge or business card. Return JSON: {first_name, last_name, company, title, email, phone, notes}"
c. Append message.text to notes
d. Dedup: Search HubSpot first by firstname+lastname+company — if exists, skip enrich, go to step (g)
e. Enrich via Apollo: `curl -X POST -H "Content-Type: application/json" -d '{"api_key":"[KEY]","first_name":"[f]","last_name":"[l]","organization_name":"[co]","title":"[t]","reveal_personal_emails":true,"reveal_phone_number":true}' https://api.apollo.io/api/v1/people/match`
f. Sleep 10s, then search HubSpot for new contact (sort by createdate DESC, filter name+company)
g. Get contact id, build link: `https://app.hubspot.com/contacts/43856876/contact/[id]`
h. Send DM to Mark (user:U03H7C6HW5B) with formatted message (see Reply Format below)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
- "company is Acme Corp" → company
- "phone is 415-555-1234" → phone
- "add note: met at SaaStr" → note (create HubSpot note via /crm/v3/objects/notes)
d. Apply update via HubSpot PATCH: `curl -X PATCH -H "Authorization: Bearer $HUBSPOT_TOKEN" -H "Content-Type: application/json" -d '{"properties":{"[field]":"[value]"}}' "https://api.hubapi.com/crm/v3/objects/contacts/[hubspot_contact_id]"`
e. Reply in thread: "✅ Updated [field] to [value] for [contact_name]."
f. If unrecognized instruction, reply: "❓ I didn't understand that. Try: 'update title to [value]' or 'email is [value]'"
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# Apollo People Enrichment API
## Endpoint
POST https://api.apollo.io/api/v1/people/match
## Headers
Content-Type: application/json
The documentation explicitly enables revealing personal emails and phone numbers but provides no privacy, consent, or data-handling warning. In the context of a Slack-based lead scanner that extracts contact data from images and text and then enriches and syncs it onward, this increases the risk of collecting and propagating sensitive personal data without adequate user awareness or policy guardrails.
The note that Apollo auto-syncs to HubSpot describes onward transfer of enriched lead data to another integrated system without warning about external transmission, data minimization, or access control implications. In this skill, where information is harvested from Slack and enriched automatically, silent propagation to CRM systems can magnify privacy, compliance, and over-sharing risks.
The file hardcodes a DM workflow to a specific person and prescribes fixed response text, but it does not itself impose a language or locale restriction. Because SQP-3 is limited to language or locale policy violations, this file appears compliant on that dimension and no stronger policy issue is evident.
No suspicious patterns detected.