Back to skill

Security audit

Tavily Crawl

Security checks for vulnerabilities and agentic risk

Overview

The skill is for crawling websites, but it automatically uses local Tavily credentials and may download and run an unpinned npm OAuth helper, so it needs review before installation.

Install only if you are comfortable sending crawl targets and instructions to Tavily and letting the skill use Tavily credentials from local auth/config files. Prefer setting a scoped `TAVILY_API_KEY` only for the command, avoid crawling private/internal sites unless approved, and review or pin the `mcp-remote` OAuth helper before first use.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T08 · Insecure Dependencies

Warning
Location
scripts/crawl.sh:105
Finding
Automatic Execution of an Unpinned npm Package<![CDATA[ ## Vulnerability Details **File Location**: `scripts/crawl.sh`, lines 105-112 **Vulnerability Type**: Unpinned third-party dependency execution **Risk Level**: Medium ### Vulnerable Code ```bash if [ -z "$TAVILY_API_KEY" ]; then set +e echo "No Tavily token found. Initiating OAuth flow..." >&2 echo "Please complete authentication in your browser..." >&2 npx -y mcp-remote https://mcp.tavily.com/mcp </dev/null >/dev/null 2>&1 & MCP_PID=$! ``` ### Technical Analysis When no Tavily credential is available, the script invokes `npx -y mcp-remote` without specifying an exact package version or validating package integrity. The `-y` option suppresses the normal installation confirmation. Consequently, npm may download and execute whichever version of `mcp-remote` is currently resolved by the configured registry. The effective executable code is therefore not contained in, pinned by, or auditable from this project. A compromised package release, npm maintainer account, transitive dependency, package registry, or local npm registry configuration could cause arbitrary code to execute during authentication. This behavior is triggered automatically as part of the documented first-run workflow. ### Attack Path 1. The user invokes `scripts/crawl.sh` without setting `TAVILY_API_KEY`, and no acceptable cached Tavily token is found. 2. The script reaches the OAuth branch. 3. `npx -y` resolves and, if necessary, downloads the current `mcp-remote` package and its dependencies. 4. npm executes package-controlled code without interactive confirmation. 5. If the resolved package or dependency is malicious or compromised, that code executes with the permissions and environment of the user running the Skill. 6. The malicious code may access files, credentials, environment variables, or network resources available to that user. ### Impact Assessment Successful exploitation provides arbitrary code execution with the invoking user's privileges. The ...[truncated 302 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin `mcp-remote` to a reviewed exact version rather than resolving the latest available release. - Manage the package through a committed lockfile containing integrity hashes. - Install dependencies during a controlled setup phase instead of dynamically downloading executable code during normal Skill operation. - Require explicit user approval before installing or executing a package that is not already present. - Prefer distributing an audited local dependency or invoking a preinstalled binary whose version and checksum have been verified. - Restrict the authentication subprocess's environment and filesystem access where sandboxing is available. - Preserve subprocess output or provide securely sanitized diagnostics rather than suppressing all output, so unexpected installation behavior can be investigated. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/crawl.sh:195
Finding
Predictable Output Files Can Be Overwritten Through Symlinks or Filename Collisions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/crawl.sh`, lines 195-203 **Vulnerability Type**: Unsafe file creation and symlink-following file overwrite **Risk Level**: Low ### Vulnerable Code ```bash # Create filename from URL FILENAME=$(echo "$PAGE_URL" | sed 's|https\?://||' | sed 's|[/:?&=]|_|g' | cut -c1-100) FILEPATH="$OUTPUT_DIR/${FILENAME}.md" echo "# $PAGE_URL" > "$FILEPATH" echo "" >> "$FILEPATH" echo "$CONTENT" >> "$FILEPATH" echo "Saved: $FILEPATH" ``` ### Technical Analysis The script deterministically derives each output filename from the returned page URL and writes to it using shell redirection with the truncating `>` operator. It does not verify that the destination is a new regular file, reject symbolic links, or use exclusive and atomic file creation. Shell redirection follows symbolic links. If another local actor can prepare the selected output directory, that actor can create a symlink using a predictable crawl filename and point it to another file writable by the victim. When the relevant URL is returned, the first redirection truncates the symlink target and replaces its contents with crawl output. The filename transformation also truncates names to 100 characters and maps several distinct URL characters to underscores. Different URLs can therefore produce the same filename, causing pages from the same crawl to overwrite one another even without an attacker. ### Attack Path 1. An attacker learns or predicts a URL that the user will crawl and applies the script's public filename transformation to it. 2. The attacker requires write access to the chosen output directory, or otherwise causes the user to select an attacker-prepared directory. 3. The attacker creates the expected `.md` output path as a symbolic link to another file writable by the user. 4. Tavily returns a result whose URL maps to that filename. 5. The command `echo "# $PAGE_URL" > "$FILEPATH"` ...[truncated 851 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Create a new output directory with restrictive permissions, such as mode `0700`, and refuse to use an existing untrusted directory by default. - Reject output paths that already exist or are symbolic links. - Use exclusive file creation rather than truncating redirection. Open files with no-follow and exclusive-create semantics where supported. - Write content to a securely created temporary file inside the destination directory and atomically rename it only after all validation succeeds. - Append a cryptographic hash of the complete URL to each normalized filename to prevent collisions caused by character replacement or truncation. - Confirm through canonical path checks that every destination remains beneath the intended output directory. - Define an explicit overwrite policy and require user confirmation if replacement of an existing regular file is intentionally supported. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared purpose says the skill simply crawls a website from a URL, but the content reveals additional sensitive behaviors: reading local auth material, triggering OAuth in a browser, using a third-party remote service, and accepting broader operational parameters. This mismatch can mislead users and agents into approving or invoking the skill without understanding data exposure, credential use, and external dependencies.

Agent Config Directory Access

High
Category
Agent Snooping
Content
### Alternative: API Key

If you prefer using an API key, get one at https://tavily.com and add to `~/.claude/settings.json`:
```json
{
  "env": {
Confidence
90% confidence
Finding
The skill instructs users to place a third-party API key into the agent configuration file at ~/.claude/settings.json, a sensitive configuration location that may be shared across skills or accessible to broader agent tooling. This expands credential exposure risk and couples the skill to privileged local configuration rather than a dedicated secret-management path.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill invokes shell-based behavior but does not declare a tool scope such as permissions or allowed-tools, which weakens reviewability and enforcement of what the skill may execute. In an agent environment, undeclared shell capability increases the chance of unexpected command execution, filesystem access, or network use beyond what a user would infer from the metadata.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The activation wording is broad enough to match many common requests involving websites, documentation, offline analysis, or downloading content. Over-broad triggering can cause the agent to select a networked, file-writing skill in situations where the user did not intend external transmission or local persistence.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation does not prominently warn that user-supplied URLs and retrieved page content are sent to an external Tavily service and may also be stored as local markdown files. In a security-sensitive agent context, missing disclosure increases the risk of accidental exfiltration of proprietary URLs, sensitive content, or regulated data.

External Transmission

Medium
Category
Data Exfiltration
Content
### Basic Crawl

```bash
curl --request POST \
  --url https://api.tavily.com/crawl \
  --header "Authorization: Bearer $TAVILY_API_KEY" \
  --header 'Content-Type: application/json' \
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
### Basic Crawl

```bash
curl --request POST \
  --url https://api.tavily.com/crawl \
  --header "Authorization: Bearer $TAVILY_API_KEY" \
  --header 'Content-Type: application/json' \
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
```bash
curl --request POST \
  --url https://api.tavily.com/crawl \
  --header "Authorization: Bearer $TAVILY_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
Confidence
50% 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
```bash
curl --request POST \
  --url https://api.tavily.com/crawl \
  --header "Authorization: Bearer $TAVILY_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
Confidence
50% 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
```bash
curl --request POST \
  --url https://api.tavily.com/crawl \
  --header "Authorization: Bearer $TAVILY_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
Confidence
50% 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
```bash
curl --request POST \
  --url https://api.tavily.com/crawl \
  --header "Authorization: Bearer $TAVILY_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
Confidence
50% 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
```bash
curl --request POST \
  --url https://api.tavily.com/crawl \
  --header "Authorization: Bearer $TAVILY_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
Confidence
50% 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
```bash
curl --request POST \
  --url https://api.tavily.com/crawl \
  --header "Authorization: Bearer $TAVILY_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
Confidence
50% 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
```bash
curl --request POST \
  --url https://api.tavily.com/crawl \
  --header "Authorization: Bearer $TAVILY_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
Confidence
50% 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

Medium
Confidence
95% confidence
Finding
This skill goes beyond crawling a website by recursively searching `~/.mcp-auth` for cached OAuth tokens and, if none are found, launching an OAuth process to obtain new credentials. Accessing local credential stores and initiating authentication flows increases sensitivity because the skill can silently consume secrets unrelated to the immediate user request.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script reads cached MCP OAuth access tokens from the user's home directory without clearly disclosing that sensitive local credentials will be inspected and reused. Even if the tokens are only used for Tavily, undisclosed secret access violates least surprise and can expose users to unintended credential use in an otherwise simple 'crawl a URL' skill.

Rp1

Medium
Category
MCP Rug Pull
Confidence
97% confidence
Finding
The script executes `npx -y mcp-remote` without pinning a specific package version or integrity hash, so a future malicious or compromised release could run arbitrary code during the OAuth helper flow. Because this helper is invoked automatically when no API key is present, the attack surface is reachable in normal use and could lead to code execution under the user's account.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script transmits the provided URL and crawl arguments to Tavily's remote service, but the help text does not clearly warn users that their targets and instructions leave the local system. This matters because crawl targets, path filters, or semantic instructions may contain sensitive internal URLs, documentation locations, or confidential investigation context.

External Transmission

Medium
Category
Data Exfiltration
Content
}')

# Call Tavily MCP server via HTTPS (SSE response)
RESPONSE=$(curl -s --request POST \
    --url "https://mcp.tavily.com/mcp" \
    --header "Authorization: Bearer $TAVILY_API_KEY" \
    --header 'Content-Type: application/json' \
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.