Back to skill

Security audit

Tavily Research

Security checks for vulnerabilities and agentic risk

Overview

This research skill is purpose-aligned but needs review because it reads shared MCP token files and automatically runs an unpinned npm OAuth helper.

Install only if you are comfortable with a Tavily-backed research helper reading local MCP auth caches, sending research queries to Tavily, and running an unpinned npm OAuth helper when no credential is available. Prefer setting a dedicated `TAVILY_API_KEY` through a scoped secret mechanism and avoid relying on broad `~/.mcp-auth` discovery until the package pins its OAuth dependency and narrows credential lookup.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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/research.sh:105
Finding

Automatic Execution of an Unpinned npm Package

Content
View full analysis

Vulnerability Details

File Location: scripts/research.sh, line 105
Vulnerability Type: Runtime supply-chain exposure through an unpinned dependency
Risk Level: Medium

Vulnerable Code:

bash
npx -y mcp-remote https://mcp.tavily.com/mcp </dev/null >/dev/null 2>&1 &

Technical Analysis

When no Tavily credential is available, the script invokes npx -y mcp-remote without specifying an exact reviewed package version or enforcing package integrity. The -y option automatically approves package installation and execution.

Consequently, package code and applicable installation lifecycle scripts retrieved from the npm registry execute with the permissions of the user running the skill. The effective executable payload can change after the skill itself has been audited. A compromised package release, transitive dependency, npm account, or registry resolution path could therefore introduce arbitrary code without requiring any modification to this repository.

Attack Path

  1. An attacker compromises the mcp-remote package, one of its dependencies, or its package publishing infrastructure.
  2. The attacker publishes a malicious version or injects malicious installation/runtime behavior.
  3. A user runs the research skill without TAVILY_API_KEY and without a usable cached Tavily token.
  4. The authentication fallback reaches line 105 and uses npx -y to retrieve and execute the currently resolved package.
  5. The malicious package code executes locally under the invoking user's account.

Impact Assessment

Successful exploitation provides arbitrary code execution with the privileges of the user invoking the skill. The malicious dependency could read or modify files accessible to that user, access environment variables and local credentials, tamper with Agent resources, initiate network connections, or modify subsequent command execution.

The scope is limited by the invoking a ...[truncated 153 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin mcp-remote to an exact, reviewed version rather than resolving the latest available release at runtime.
  • Install dependencies through a committed lockfile containing integrity hashes.
  • Avoid downloading and executing packages during normal skill operation. Prefer a preinstalled, audited OAuth client or vendor the minimal reviewed implementation.
  • Disable or tightly control dependency lifecycle scripts where operationally possible.
  • Verify package provenance and integrity before execution.
  • Run the OAuth helper with restricted filesystem, environment, and network access.
  • Fail safely with explicit installation instructions if the reviewed dependency is unavailable rather than automatically retrieving executable code.

T05 · Unauthorized Access and Privilege Escalation

Note
Location
scripts/research.sh:42
Finding

Overbroad Recursive Enumeration of Shared MCP Credential Files

Content
View full analysis

Vulnerability Details

File Location: scripts/research.sh, lines 42-60
Vulnerability Type: Excessive access to shared credential storage
Risk Level: Low

Vulnerable Code:

bash
get_mcp_token() {
    MCP_AUTH_DIR="$HOME/.mcp-auth"
    if [ -d "$MCP_AUTH_DIR" ]; then
        # Search recursively for *_tokens.json files
        while IFS= read -r token_file; do
            if [ -f "$token_file" ]; then
                token=$(jq -r '.access_token // empty' "$token_file" 2>/dev/null)
                if [ -n "$token" ] && [ "$token" != "null" ]; then
                    # Check if valid Tavily token (correct issuer and not expired)
                    if ! is_valid_tavily_token "$token"; then
                        continue  # Skip invalid/non-Tavily/expired tokens
                    fi
                    echo "$token"
                    return 0
                fi
            fi
        done < <(find "$MCP_AUTH_DIR" -name "*_tokens.json" 2>/dev/null)
    fi
    return 1
}

Technical Analysis

The script recursively searches the entire shared ~/.mcp-auth directory and opens every file matching *_tokens.json. This is broader than reading a known Tavily-specific credential location and gives the process visibility into access tokens associated with unrelated MCP integrations.

The code reduces immediate exposure by validating the decoded JWT issuer before selecting a token, and the reviewed implementation does not intentionally transmit unrelated credentials. Nevertheless, it violates least-privilege principles because unrelated token files are still discovered, opened, and parsed. This unnecessarily expands the credential exposure surface and could amplify the impact of future defects or compromised runtime code.

Attack Path

  1. The user has authentication files for Tavily and other MCP providers under ~/.mcp-auth.
  2. The user invokes the r ...[truncated 1100 chars]
Remediation
View remediation

Remediation Suggestions

  • Read credentials only from a documented, provider-specific Tavily token location.
  • Replace recursive find usage with an exact expected path or a narrowly constrained filename.
  • Prefer an official credential API or OAuth helper that returns only the credential for the requested provider.
  • Verify that the credential file is owned by the current user and has restrictive permissions before reading it.
  • Avoid storing unrelated access tokens in shell variables during credential discovery.
  • If multiple cache layouts must be supported, maintain an explicit allowlist of Tavily-specific paths rather than scanning shared authentication storage.
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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (5)

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

The skill instructs users to place a secret API key in the agent configuration file ~/.claude/settings.json, which is a sensitive config location that may be broadly readable by other skills, tooling, or processes in the agent environment. Referencing and normalizing writes to this file increases the chance of credential exposure, accidental leakage, or cross-skill secret access.

Content

Scanner excerpt · SKILL.md (reported line 19)May include surrounding context.

Alternative: API Key

If you prefer using an API key, get one at https://tavily.com and add to ~/.claude/settings.json:

json
{
  "env": {

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill invokes a shell script (./scripts/research.sh) but does not declare any permissions or allowed-tools scope. That creates an undeclared capability boundary, making it harder for the agent runtime or reviewer to understand and constrain execution, and increasing the risk of unexpected command execution or access beyond what users expect.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This research skill searches the user's ~/.mcp-auth directory for cached OAuth access tokens and, if none are found, launches a browser-based OAuth flow to obtain one. That exceeds the minimal expectations of a simple research helper and creates credential-access and unexpected-auth side effects, especially because the script is capable of reusing tokens discovered from the broader user environment rather than a skill-scoped secret explicitly supplied for this purpose.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding

The script executes npx -y mcp-remote without pinning an exact package version or integrity hash, so behavior can change over time and a compromised or malicious upstream release would be executed locally during authentication. Because this happens automatically in a shell script and may run in user environments with access to tokens and browser auth state, it creates a real software supply-chain risk.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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/research.sh (reported line 160)May include surrounding context.

sh
}')

# 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' \

Static analysis

No suspicious patterns detected.