Back to skill

Security audit

Fathom

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly does what it says, but its webhook setup can continuously send sensitive meeting content to any user-supplied HTTPS endpoint with broad defaults.

Review the webhook feature carefully before installing. Use the read-only listing, summary, and transcript scripts only with meetings you are authorized to access. Do not run setup-webhook.sh unless you control the destination endpoint, understand that transcripts, summaries, and action items may be sent there for future recordings, and are prepared to delete the webhook later. Store the Fathom API key securely and rotate it if exposed.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/setup-webhook.sh:6
Finding
Persistent Disclosure of Sensitive Meeting Data to an Arbitrary Webhook Destination<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup-webhook.sh:6-9, 22-28, 47-56, 71-81` **Vulnerability Type**: Arbitrary webhook destination with excessive default data scope **Risk Level**: High ### Complete Code Snippet ```bash WEBHOOK_URL="" INCLUDE_TRANSCRIPT=true INCLUDE_SUMMARY=true INCLUDE_ACTION_ITEMS=true # Parse arguments while [[ $# -gt 0 ]]; do case $1 in --url) WEBHOOK_URL="$2"; shift 2 ;; --no-transcript) INCLUDE_TRANSCRIPT=false; shift ;; --no-summary) INCLUDE_SUMMARY=false; shift ;; --no-action-items) INCLUDE_ACTION_ITEMS=false; shift ;; if [ -z "$WEBHOOK_URL" ]; then echo "❌ Webhook URL required" echo "Usage: setup-webhook.sh --url https://your-domain.com/webhook" exit 1 fi if [[ ! "$WEBHOOK_URL" =~ ^https:// ]]; then echo "❌ Webhook URL must be HTTPS" exit 1 fi # Register webhook RESPONSE=$(curl -s -X POST "https://api.fathom.ai/external/v1/webhooks" \ -H "X-API-Key: $API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"destination_url\": \"$WEBHOOK_URL\", \"include_transcript\": $INCLUDE_TRANSCRIPT, \"include_summary\": $INCLUDE_SUMMARY, \"include_action_items\": $INCLUDE_ACTION_ITEMS, \"triggered_for\": [\"my_recordings\", \"shared_external_recordings\", \"my_shared_with_team_recordings\", \"shared_team_recordings\"] }") ``` ### Technical Analysis The script creates a persistent Fathom webhook whose destination is entirely controlled by the `--url` argument. Validation only checks whether the supplied string begins with `https://`. HTTPS provides transport encryption, but it does not establish that the receiving domain is owned or trusted by the user. The webhook enables transcripts, summaries, and action items by default. It also subscribes to four broad recording scopes, including externally shared and team-shared recordings. This exceeds a least-privilege configuration because sensitive content is ...[truncated 2116 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Use privacy-preserving defaults** - Initialize `INCLUDE_TRANSCRIPT`, `INCLUDE_SUMMARY`, and `INCLUDE_ACTION_ITEMS` to `false`. - Require explicit opt-in flags such as `--include-transcript`. - Default to the narrowest recording scope. 2. **Require explicit recording-scope selection** - Add flags for each supported `triggered_for` scope. - Do not automatically include external or team-shared recordings. - Clearly identify scopes that may contain third-party data. 3. **Confirm sensitive registration** - Display the normalized destination, selected scopes, and data categories before registration. - Require interactive confirmation. - Permit noninteractive registration only through an explicit option such as `--yes`, accompanied by documentation of the risks. 4. **Verify or restrict webhook destinations** - Prefer an administrator-configured allowlist of approved domains. - Where supported, require a destination ownership challenge before enabling delivery. - Parse the URL structurally rather than relying only on a prefix test. - Reject embedded credentials and malformed destinations. 5. **Construct the request safely** - Generate JSON with `jq` rather than interpolating the URL into a JSON string: ```bash PAYLOAD=$(jq -n \ --arg url "$WEBHOOK_URL" \ --argjson transcript "$INCLUDE_TRANSCRIPT" \ --argjson summary "$INCLUDE_SUMMARY" \ --argjson actions "$INCLUDE_ACTION_ITEMS" \ --argjson scopes "$TRIGGER_SCOPES" \ '{ destination_url: $url, include_transcript: $transcript, include_summary: $summary, include_action_items: $actions, triggered_for: $scopes }') ``` - Submit it using `curl --data-binary "$PAYLOAD"`. 6. **Improve lifecycle controls** - Provide a dedicated webhook listing and deletion command. - Clearly document that registration persists after the script ...[truncated 424 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (26)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill is presented as a read/search integration, yet it also documents webhook registration, outbound configuration to arbitrary user-specified HTTPS endpoints, and management of webhook secrets. That is materially different from passive retrieval and can cause ongoing external transmission of sensitive meeting data.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill is presented as a read/search integration, yet it also documents webhook registration, outbound configuration to arbitrary user-specified HTTPS endpoints, and management of webhook secrets. That is materially different from passive retrieval and can cause ongoing external transmission of sensitive meeting data.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The script allows an operator to register any arbitrary HTTPS endpoint as a destination and enables transcript, summary, and action-item delivery for multiple recording scopes. In the context of a skill described only as fetching meetings and call history, this creates a clear exfiltration path for sensitive meeting content to third-party infrastructure.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill documents shell commands and outbound API access but does not declare any explicit tool scope such as allowed tools or permissions. That increases the chance an agent can invoke shell/network capabilities more broadly than intended, which is risky in a skill that handles meeting transcripts and API keys.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill retrieves and exports highly sensitive meeting artifacts—transcripts, summaries, and potentially recordings—without warning about privacy, consent, retention, or organizational policy implications. In this context, missing warnings make accidental overcollection or improper sharing more likely.

Session Persistence

Medium
Category
Rogue Agent
Content
### 1. Get Your API Key
1. Go to [developers.fathom.ai](https://developers.fathom.ai)
2. Create an API key
3. Copy the key (format: `v1XDx...`)

### 2. Configure
Confidence
78% confidence
Finding
The setup recommends persisting a long-lived API key in a local file or environment variable, which creates session persistence and increases the blast radius if the workstation, shell history, or environment is compromised. Given the skill accesses sensitive meeting data, persistent credentials deserve stronger handling guidance.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Option A: Store in file (recommended)
echo "YOUR_API_KEY" > ~/.fathom_api_key
chmod 600 ~/.fathom_api_key

# Option B: Environment variable
export FATHOM_API_KEY="YOUR_API_KEY"
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The documentation extends the skill from meeting retrieval into automatic transcript ingestion via webhooks. In a context involving call transcripts and summaries, that expansion increases data exposure because users may not expect persistent forwarding of sensitive conversations.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The webhook setup command enables outbound integration to an external endpoint outside the manifest's apparent read/search scope. Because meeting transcripts may contain confidential business or personal information, hidden or under-disclosed sync behavior materially raises confidentiality risk.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The webhook instructions omit a warning that enabling auto-ingestion may continuously transmit future meeting data to an external service. For meeting transcripts and action items, this can create silent, persistent exfiltration of sensitive information well beyond a one-time fetch.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
This script materially expands the skill from passive retrieval of meeting data into active configuration of outbound webhooks that can continuously export future meeting content. That capability is outside the stated purpose and increases risk because it creates a persistence mechanism for ongoing data disclosure rather than a one-time fetch operation.

External Transmission

Medium
Category
Data Exfiltration
Content
echo ""

# Register webhook
RESPONSE=$(curl -s -X POST "https://api.fathom.ai/external/v1/webhooks" \
    -H "X-API-Key: $API_KEY" \
    -H "Content-Type: application/json" \
    -d "{
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The registration flow sends configuration that will cause Fathom to deliver potentially sensitive transcripts and summaries externally, but the script presents this as a simple setup step without prominent privacy or data-sharing warnings. Users may not understand that they are enabling ongoing transfer of confidential meeting data to another service.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
echo "  1. Get your API key from https://developers.fathom.ai"
    echo "  2. Save it:"
    echo "     echo 'YOUR_KEY' > ~/.fathom_api_key"
    echo "     chmod 600 ~/.fathom_api_key"
    echo ""
    echo "  Or set environment variable:"
    echo "     export FATHOM_API_KEY='YOUR_KEY'"
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

External Transmission

Medium
Category
Data Exfiltration
Content
RESPONSE=$(curl -s -w "\n%{http_code}" \
    -H "X-API-Key: $API_KEY" \
    "https://api.fathom.ai/external/v1/meetings?limit=1")

HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
RESPONSE=$(curl -s -w "\n%{http_code}" \
    -H "X-API-Key: $API_KEY" \
    "https://api.fathom.ai/external/v1/meetings?limit=1")

HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
RESPONSE=$(curl -s -w "\n%{http_code}" \
    -H "X-API-Key: $API_KEY" \
    "https://api.fathom.ai/external/v1/meetings?limit=1")

HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
RESPONSE=$(curl -s -w "\n%{http_code}" \
    -H "X-API-Key: $API_KEY" \
    "https://api.fathom.ai/external/v1/meetings?limit=1")

HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
RESPONSE=$(curl -s -w "\n%{http_code}" \
    -H "X-API-Key: $API_KEY" \
    "https://api.fathom.ai/external/v1/meetings?limit=1")

HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
RESPONSE=$(curl -s -w "\n%{http_code}" \
    -H "X-API-Key: $API_KEY" \
    "https://api.fathom.ai/external/v1/meetings?limit=1")

HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
RESPONSE=$(curl -s -w "\n%{http_code}" \
    -H "X-API-Key: $API_KEY" \
    "https://api.fathom.ai/external/v1/meetings?limit=1")

HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
RESPONSE=$(curl -s -w "\n%{http_code}" \
    -H "X-API-Key: $API_KEY" \
    "https://api.fathom.ai/external/v1/meetings?limit=1")

HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Context-Inappropriate Capability

Low
Confidence
84% confidence
Finding
The manifest describes fetching recordings, transcripts, and summaries from Fathom, which justifies calling the Fathom API. However, this script also implements credential discovery by reading both the FATHOM_API_KEY environment variable and ~/.fathom_api_key from the local filesystem, which is a separate capability not mentioned in the manifest.

Missing User Warnings

Low
Confidence
86% confidence
Finding
This code accesses sensitive credentials via the FATHOM_API_KEY environment variable or a ~/.fathom_api_key file, but provides no warning, prompt, or explanatory comment that the script will read stored secrets. Under the code-file criteria, sensitive credential access should have some visible disclosure unless clearly covered elsewhere.

Missing User Warnings

Low
Confidence
79% confidence
Finding
The script performs a curl request to api.fathom.ai using an API key, which transmits credentialed request data over the network. Although this is aligned with the script's purpose of listing Fathom calls, there is no explicit warning in the help/output/comments that it contacts the external Fathom service using the stored key.

Static analysis

No suspicious patterns detected.