Back to skill

Security audit

travily_search_pro

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but it ships a real-looking Tavily API key in its package, so users should review it before installing.

Install only after removing the bundled .env credential and supplying your own Tavily API key through a private local configuration. Do not submit secrets, private internal URLs, regulated data, or confidential research topics unless you are comfortable sending them to Tavily.

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
.env:1
Finding

Hardcoded Tavily API Credential

Content
View full analysis

Vulnerability Details

File Location: .env:1
Vulnerability Type: Hardcoded secret / plaintext API credential
Risk Level: High

Vulnerable Code

dotenv
TAVILY_API_KEY=tvly-dev-[REDACTED]

The credential is loaded into the process environment and subsequently used to authenticate to Tavily:

python
TAVILY_API_KEY = os.environ.get("TAVILY_API_KEY", "")
python
headers = {
    'Authorization': f'Bearer {TAVILY_API_KEY}',
    'Content-Type': 'application/json'
}

Technical Analysis

The project distributes a live-looking Tavily API key in its .env file rather than accepting the secret exclusively through secure runtime configuration. Anyone who can download, inspect, clone, archive, or otherwise access the project can recover the credential without bypassing any access control.

The three scripts load values from the packaged .env file into os.environ. The search client passes the key to TavilyClient, while the extraction and research clients place it in an HTTP Bearer authorization header. Although these are legitimate uses of the credential, bundling it with the source code breaks secret-separation requirements and makes credential disclosure unavoidable when the project is shared.

Attack Path

  1. An attacker obtains a copy of the project package or repository.
  2. The attacker opens .env and extracts the value assigned to TAVILY_API_KEY.
  3. The attacker supplies that value to the Tavily SDK or uses it as a Bearer credential in requests to supported Tavily API endpoints.
  4. Tavily attributes the requests and associated usage to the exposed credential's account.
  5. The attacker can continue using the credential until it is revoked, rotated, expired, or otherwise disabled.

Impact Assessment

Successful exploitation does not grant local operating-system privileges, code execution, or persistence. It grants whatever API access and quota are assign ...[truncated 383 chars]

Remediation
View remediation

Remediation Suggestions

  1. Revoke and rotate the exposed Tavily API key immediately; deleting it from the current project does not invalidate copies already obtained.

  2. Remove .env from all distributed packages and version-control history. If it was committed, rewrite repository history where practical while treating the credential as permanently compromised.

  3. Add .env and other secret-bearing configuration files to .gitignore and packaging exclusion rules.

  4. Provide a .env.example file containing only a nonfunctional placeholder such as:

    dotenv
    TAVILY_API_KEY=replace-with-your-own-key
    
  5. Supply the real credential at runtime through environment injection, a CI/CD secret store, an operating-system credential facility, or a dedicated secrets manager.

  6. Apply least privilege, usage limits, billing alerts, and key rotation policies to the replacement credential.

  7. Review Tavily usage logs for unauthorized activity associated with the exposed key.

  8. Add automated secret scanning to pre-commit hooks and CI pipelines to prevent future credential disclosure.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (27)

Tainted flow: 'headers' from os.environ.get (line 38, credential/environment) → requests.post (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/tavily_extract.py (reported line 42)May include surrounding context.

python
try:
        print(f"正在提取: {url}")
        response = requests.post(url_api, json=data, headers=headers, timeout=60)
        response.raise_for_status()
        result = response.json()
        if isinstance(result, list) and len(result) > 0:

Tainted flow: 'headers' from os.environ.get (line 41, credential/environment) → requests.post (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/tavily_research.py (reported line 48)May include surrounding context.

python
print(f"模型: {model}")
        print("这可能需要 30-120 秒...\n")

        response = requests.post(url, json=data, headers=headers, timeout=180)
        response.raise_for_status()
        result = response.json()

Tainted flow: 'headers' from os.environ.get (line 41, credential/environment) → requests.get (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/tavily_research.py (reported line 59)May include surrounding context.

python
attempt = 0
            while attempt < 60:
                time.sleep(2)
                poll_response = requests.get(poll_url, headers=headers, timeout=30)
                poll_result = poll_response.json()
                if poll_result.get('status') == 'completed':
                    return poll_result

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

代码的核心能力仅是 Tavily 搜索。虽然提供了 search_depth 和 include_raw_content 等搜索参数,但没有看到任何对应 Tavily research 或 extract 的独立功能、方法或命令入口。描述将技能表述为同时支持 search、research、extract 三个功能,而实际代码块只覆盖 search,因此描述夸大了已实现能力,属于描述与行为不一致。未发现额外的未声明高风险能力;从 .env 读取 API Key 属于实现细节,不构成此类不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个包含 search、research、extract 三个功能的综合技能,但提供的代码片段只实现了 extract(URL 内容提取)功能,没有看到任何网络搜索或深度研究相关逻辑、API 调用或命令参数。因此代码行为只覆盖了声明中的一部分,不能完整准确代表所宣称的能力范围。除此之外,代码访问 Tavily API 与其 extract 子功能一致,没有发现额外未声明的高风险能力。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

声明描述把该技能表述为支持 search、research、extract 三个功能,但提供的代码片段只包含一个 tavily_research.py 脚本,且其中仅实现了 research() 深度研究调用,没有搜索或内容提取相关接口、命令参数或代码路径。因此,代码行为只覆盖声明中的一部分能力,描述对实际可用功能有明显高估,构成描述与行为不一致。其余行为如读取 .env、调用外部 Tavily API、轮询任务状态、输出到文件,均属于实现 research 功能的合理支持细节,不属于额外未声明的高风险能力。

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/tavily_client.py (reported line 3)May include surrounding context.

python
#!/usr/bin/env python3
"""
Tavily Search API - 从 .env 加载配置
"""
import os
import sys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/tavily_client.py (reported line 9)May include surrounding context.

python
#!/usr/bin/env python3
"""
Tavily Search API - 从 .env 加载配置
"""
import os
import sys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/tavily_client.py (reported line 33)May include surrounding context.

python
#!/usr/bin/env python3
"""
Tavily Search API - 从 .env 加载配置
"""
import os
import sys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/tavily_extract.py (reported line 11)May include surrounding context.

python
#!/usr/bin/env python3
"""
Tavily Search API - 从 .env 加载配置
"""
import os
import sys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/tavily_extract.py (reported line 33)May include surrounding context.

python
#!/usr/bin/env python3
"""
Tavily Search API - 从 .env 加载配置
"""
import os
import sys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/tavily_research.py (reported line 12)May include surrounding context.

python
#!/usr/bin/env python3
"""
Tavily Search API - 从 .env 加载配置
"""
import os
import sys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/tavily_research.py (reported line 34)May include surrounding context.

python
#!/usr/bin/env python3
"""
Tavily Search API - 从 .env 加载配置
"""
import os
import sys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/tavily_client.py (reported line 10)May include surrounding context.

python
from pathlib import Path

# 尝试从 .env 加载
ENV_FILE = Path(__file__).parent.parent / ".env"
if ENV_FILE.exists():
    with open(ENV_FILE) as f:
        for line in f:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/tavily_extract.py (reported line 12)May include surrounding context.

python
from pathlib import Path

# 尝试从 .env 加载
ENV_FILE = Path(__file__).parent.parent / ".env"
if ENV_FILE.exists():
    with open(ENV_FILE) as f:
        for line in f:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/tavily_research.py (reported line 13)May include surrounding context.

python
from pathlib import Path

# 尝试从 .env 加载
ENV_FILE = Path(__file__).parent.parent / ".env"
if ENV_FILE.exists():
    with open(ENV_FILE) as f:
        for line in f:

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill advertises use of environment variables, network access, and file output via scripts, but does not declare any explicit tool scope such as permissions or allowed-tools. This weakens reviewability and least-privilege controls, making it easier for an agent runtime to grant broader capabilities than users expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill instructs users to submit search queries and URLs to Tavily but does not clearly warn that this data is transmitted to an external third-party service. This can lead to unintended disclosure of sensitive prompts, research topics, internal URLs, or other confidential information entered by the user.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The docstring, comments, argparse help text, and runtime output strings are written in Chinese throughout the file, with no option for the user to choose another language or locale. This creates a natural-language locale policy issue because the skill imposes a specific language experience by default rather than offering opt-in or documenting a justified region-specific constraint.

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/tavily_extract.py (reported line 36)May include surrounding context.

python
print("错误: 请在 .env 文件中设置 TAVILY_API_KEY")
        sys.exit(1)

    url_api = 'https://api.tavily.com/extract'
    data = {'urls': [url], 'extract_depth': extract_depth}
    headers = {'Authorization': f'Bearer {TAVILY_API_KEY}', 'Content-Type': 'application/json'}

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/tavily_research.py (reported line 37)May include surrounding context.

python
print("错误: 请在 .env 文件中设置 TAVILY_API_KEY")
        sys.exit(1)

    url_api = 'https://api.tavily.com/extract'
    data = {'urls': [url], 'extract_depth': extract_depth}
    headers = {'Authorization': f'Bearer {TAVILY_API_KEY}', 'Content-Type': 'application/json'}

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/tavily_research.py (reported line 55)May include surrounding context.

python
print("错误: 请在 .env 文件中设置 TAVILY_API_KEY")
        sys.exit(1)

    url_api = 'https://api.tavily.com/extract'
    data = {'urls': [url], 'extract_depth': extract_depth}
    headers = {'Authorization': f'Bearer {TAVILY_API_KEY}', 'Content-Type': 'application/json'}

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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/tavily_extract.py (reported line 42)May include surrounding context.

python
try:
        print(f"正在提取: {url}")
        response = requests.post(url_api, json=data, headers=headers, timeout=60)
        response.raise_for_status()
        result = response.json()
        if isinstance(result, list) and len(result) > 0:

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This file includes user-facing natural-language strings in Chinese, starting with the module description and continuing throughout CLI help and status messages. Because the script does not offer any language or locale selection, it effectively forces a specific language without user opt-in, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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/tavily_research.py (reported line 48)May include surrounding context.

python
print(f"模型: {model}")
        print("这可能需要 30-120 秒...\n")

        response = requests.post(url, json=data, headers=headers, timeout=180)
        response.raise_for_status()
        result = response.json()

Static analysis

No suspicious patterns detected.