T09 · Insecure Skill Coding Practices
- Location
scripts/flowconcierge.py:273- Finding
Unauthenticated Webhook Allows CRM Poisoning and Unauthorized SMS Sending
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
FlowConcierge does what it says, but it exposes billable CRM and SMS actions through an unauthenticated public webhook and lacks enough consent and confirmation guardrails.
Review before installing. Use a test Twilio and HubSpot account first, avoid enabling --sms-followup until webhook authentication and rate limits are added, do not expose the webhook publicly without a secret or signature check, and confirm call-recording/transcript, CRM, and SMS consent obligations for your callers. Prefer an existing Twilio number or require an explicit purchase confirmation, and pin dependencies in an isolated virtual environment.
scripts/flowconcierge.py:273Unauthenticated Webhook Allows CRM Poisoning and Unauthorized SMS Sending
scripts/flowconcierge.py:218Untrusted Website Content Is Embedded in AI System Instructions
install.sh:15Installer Uses Unpinned Third-Party Dependencies Without Integrity Verification
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
}
)
try:
with urllib.request.urlopen(req, timeout=30) as r:
return json.loads(r.read())
except urllib.error.HTTPError as e:
err = e.read().decode()
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
}
)
try:
with urllib.request.urlopen(req, timeout=30) as r:
return json.loads(r.read())
except urllib.error.HTTPError as e:
err = e.read().decode()
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
}
)
try:
with urllib.request.urlopen(req, timeout=30) as r:
return json.loads(r.read())
except urllib.error.HTTPError as e:
err = e.read().decode()
The skill logs call summaries and transcripts to HubSpot without a prominent privacy warning or consent guidance. Because phone calls can contain sensitive personal, financial, or health-related information, silently exporting AI-generated notes and transcripts to a third-party CRM creates significant privacy, compliance, and data-governance risk.
The README instructs users to execute npx clawhub@latest install ..., which pulls and runs the latest remote package version without pinning or integrity verification. That creates a supply-chain risk: if the package is compromised or a breaking/malicious release is published, users may execute attacker-controlled code during installation.
The README advertises that setup will auto-buy a local Twilio phone number, but it does not prominently warn that this action can incur charges or create billable telecom resources. Users may run setup expecting a reversible dry run and unintentionally authorize paid purchases, which is especially concerning in an automation-heavy install flow.
The README states that end-of-call events create or update HubSpot contacts, log summaries and transcripts, and may send SMS follow-ups, but it does not clearly warn users about the privacy, consent, and compliance implications of collecting caller data and storing call content. In a phone-receptionist context, this is materially risky because businesses may deploy it without informing callers or configuring lawful notice/consent flows.
The skill advertises capabilities that involve environment access, file I/O, and network activity, but it does not declare any tool scope or permission boundaries in the manifest. That makes the skill harder to review safely and increases the risk of over-broad execution, especially because it handles API keys, web scraping, webhook exposure, CRM logging, and SMS actions.
This markdown file repeatedly describes the skill as applicable to "any business" and usable by simply "Point it at your website," but it does not define specific invocation phrases, scope limits, or exclusion conditions. That broad natural-language framing can cause unintended activation because the description lacks precise trigger boundaries or negative examples.
The install instructions use an unpinned npx clawhub@latest, which allows whatever version is current at install time to run arbitrary package install logic. This creates a supply-chain risk: a compromised or breaking upstream release could execute unintended code on the user's machine during installation.
The skill can automatically buy a Twilio phone number and send SMS follow-ups to external recipients, but the documentation does not prominently warn users about account charges, messaging implications, or the fact that third parties will be contacted. This can lead to unauthorized spend, accidental outreach, or regulatory issues around unsolicited texts.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# ─── Twilio client ─────────────────────────────────────────────────────────────
class TwilioClient:
BASE = "https://api.twilio.com/2010-04-01"
def __init__(self, account_sid: str, auth_token: str):
self.sid = account_sid
The webhook accepts call summaries and transcripts, then forwards that content into HubSpot notes and optionally Twilio SMS without any consent, minimization, or authenticity checks. In a phone-reception context, this can expose sensitive caller data and also allows a forged webhook request to inject arbitrary content into CRM records or trigger SMS if the endpoint is reachable.
The setup flow can automatically purchase a Twilio number as soon as valid credentials are provided, with no confirmation prompt, dry-run mode, or spend guardrail. In operational terms this can cause unintended charges or resource provisioning if the command is run accidentally or by an untrusted automation path.
The command reference specifies '--lang — Language code (default: en)', which sets a specific language by default. Under the policy, forcing a language or locale without user opt-in can be a natural-language policy concern unless clearly justified or presented as a choice.
The options list sets --lang to default en, which imposes a language choice unless the user notices and overrides it. Per the language/locale policy, skills should avoid forcing a specific language without opt-in or clearer user choice.
The dependency is specified with only a lower bound, which allows future unreviewed versions of scrapling to be installed. This creates supply-chain risk because upstream breaking changes, compromised releases, or newly introduced vulnerable transitive dependencies could be pulled into deployments without explicit review. In this skill’s context, the package participates in website scraping and feeds downstream automation, so a malicious or vulnerable update could affect data collection and the broader assistant setup pipeline.
scrapling>=0.4.0
The assistant/transcriber is created with language defaulting to 'en', which imposes a language choice unless the user discovers and overrides --lang. This is a natural-language policy concern because the skill defaults to a specific language rather than explicitly offering language selection or documenting why English is required.
No suspicious patterns detected.