Back to skill

Security audit

FlowConcierge — AI Phone Receptionist for Any Business

Security checks for vulnerabilities and agentic risk

Overview

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.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/flowconcierge.py:273
Finding

Unauthenticated Webhook Allows CRM Poisoning and Unauthorized SMS Sending

Content
View full analysis
Remediation
View remediation

T01 · Skill Instruction Hijacking

Warning
Location
scripts/flowconcierge.py:218
Finding

Untrusted Website Content Is Embedded in AI System Instructions

Content
View full analysis
str: try: from scrapling import Fetcher, StealthyFetcher, DynamicFetcher except ImportError: print("❌ Scrapling not installed. Run: pip install scrapling") sys.exit(1) print(f" 🌐 Scraping {url}...") for tier, label, fn in [ (1, "plain HTTP", lambda: Fetcher().get(url, timeout=15, follow_redirects=True)), (2, "stealth mode", lambda: StealthyFetcher().fetch(url, timeout=30, headless=True)), (3, "full JS", lambda: DynamicFetcher().fetch(url, timeout=45, headless=True)), ]: try: print(f" Tier {tier}: {label}...") page = fn() content = str(getattr(page, "markdown", None) or page or "") if len(content) > 200: print(f" ✅ Got {len(content):,} chars") return content except Exception as e: print(f" Tier {tier} failed: {e}") return f"Business website: {url}\n\nPlease answer caller questions accurately." def build_system_prompt(name: str, kb_content: str = "") -> str: return f"""You are a friendly, professional AI receptionist for {name}. Your role: - Answer caller questions warmly and accurately - Provide information about the business (hours, location, services, pricing) - Help callers find what they need - Take messages when appropriate - Transfer to a human when the caller requests it or when you cannot help Always be concise, warm, and honest. Never guess — say "I don't have that information." Business Information: {kb_content[:4000]} """.strip() ``` The same untrusted content is also uploaded to VAPI as a knowledge-base document: ```python kb_id = vapi.create_knowledge_base(business_name, kb_content) ``` ### Technical Ana ...[truncated 2609 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
install.sh:15
Finding

Installer Uses Unpinned Third-Party Dependencies Without Integrity Verification

Content
View full analysis
=0.4.0 ``` The installer also downloads Playwright browser components obtained through the installed Python environment: ```bash python3 -m playwright install chromium --quiet 2>/dev/null || true ``` ### Technical Analysis The installer requests `scrapling` without an exact version, while the requirements file allows any release greater than or equal to version 0.4.0. No lockfile, package hash, transitive dependency constraints, trusted index configuration, or virtual environment is used. As a result, the code reviewed during this audit is not sufficient to determine the code that will actually be installed in a future execution. Package installation may execute build backends, setup hooks, and dependency code with the privileges of the user running the installer. A compromised upstream release, compromised maintainer account, malicious transitive dependency, or unexpected incompatible update could therefore execute arbitrary code during installation or later import. This audit did not establish that the current `scrapling` package is malicious. The finding is the absence of controls that ensure the installed artifacts match reviewed versions. ### Attack Path 1. An operator runs `bash install.sh`. 2. The script invokes the environment's default `pip` executable without an isolated environment or locked dependency set. 3. The package index resolves the newest acceptable `scrapling` release and its then-current transitive dependencies. 4. If an upstream or transitive package has been compromised, malicious installation or import-time code runs under the operator's account. ...[truncated 963 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

Tainted flow: 'req' from os.environ.get (line 171, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/flowconcierge.py (reported line 54)May include surrounding context.

python
}
        )
        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()

Tainted flow: 'req' from os.environ.get (line 171, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/flowconcierge.py (reported line 133)May include surrounding context.

python
}
        )
        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()

Tainted flow: 'req' from os.environ.get (line 171, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/flowconcierge.py (reported line 179)May include surrounding context.

python
}
        )
        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()

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

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.

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 · scripts/flowconcierge.py (reported line 114)May include surrounding context.

python
# ─── 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

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

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.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
scrapling>=0.4.0

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.