Back to skill

Security audit

travel-customizer

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed travel-lead collection integration that sends confirmed customer details to a configured Feishu table, with some privacy and hardening items to address.

Before installing, use a dedicated least-privilege Feishu app and table, restrict access to submitted records, tell travelers that their contact and travel details will be stored in Feishu, define retention/deletion practices, avoid collecting unnecessary sensitive notes, pin dependencies, and sanitize error messages before exposing them to users.

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)

T09 · Insecure Skill Coding Practices

Warning
Location
tools.py:87
Finding

Feishu resource identifiers exposed through unsanitized exception messages

Content
View full analysis

Vulnerability Details

File Location: tools.py, lines 87–104
Vulnerability Type: Sensitive information exposure through verbose error handling
Risk Level: Medium

Vulnerable Code:

python
url = f"{FEISHU_API_BASE}/bitable/v1/apps/{base_token}/tables/{table_id}/records"
headers = {
    "Authorization": f"Bearer {token}",
    "Content-Type": "application/json"
}
payload = {
    "records": [{"fields": fields}]
}

resp = requests.post(url, headers=headers, json=payload, timeout=10)
resp.raise_for_status()
result = resp.json()

if result.get('code') == 0:
    return {"status": "success", "message": "需求已成功提交至飞书表格!"}
else:
    return {"status": "error", "message": f"飞书 API 错误: {result.get('msg')}"}

except Exception as e:
    return {"status": "error", "message": f"系统异常: {str(e)}"}

Technical Analysis

The request URL embeds the configured FEISHU_BASE_TOKEN and FEISHU_TABLE_ID. When Feishu returns a non-successful HTTP status, requests.Response.raise_for_status() raises an exception whose text can include the request URL. The catch-all exception handler then returns that raw exception text to the tool caller.

Consequently, an internal integration error can disclose Feishu resource identifiers beyond the trusted server boundary. The bearer token is placed in an HTTP header and is not ordinarily included in raise_for_status() output, and the application secret is only used by the separate authentication request. Therefore, the reviewed path does not establish direct disclosure of the bearer token or application secret.

The fixed official HTTPS endpoint prevents caller-controlled server-side request forgery. Sending the credentials and traveler information to Feishu is otherwise consistent with the Skill's declared purpose.

Attack Path

  1. An attacker or untrusted user invokes the submission tool after satisfying the conversational confirmation workflow.
  2. The reque ...[truncated 929 chars]
Remediation
View remediation

Remediation Suggestions

  • Never return raw exception strings from HTTP libraries to users or agent-visible tool responses.
  • Return a fixed, generic failure message with a non-sensitive internal error code.
  • Record detailed diagnostics only in access-controlled server logs.
  • Sanitize logged URLs by replacing the Base Token and Table ID path segments with placeholders.
  • Do not log authorization headers, application secrets, tenant access tokens, request bodies containing traveler data, or complete remote responses.
  • Catch narrower exception classes such as requests.Timeout, requests.ConnectionError, and requests.HTTPError.
  • Validate Feishu responses while retaining only safe fields such as a documented error code.
  • Add tests that trigger non-2xx responses and verify that returned errors contain no configured identifiers, credentials, URLs, headers, or traveler data.

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unbounded dependency version permits unreviewed future releases

Content
View full analysis

Vulnerability Details

File Location: requirements.txt, line 1
Vulnerability Type: Non-reproducible and insufficiently constrained third-party dependency
Risk Level: Low

Vulnerable Code:

text
requests>=2.28.0

Technical Analysis

The dependency declaration sets only a minimum version and no upper or exact bound. A future installation may therefore resolve to a release that was not present when the Skill was reviewed. This makes deployments non-reproducible and expands supply-chain exposure.

No malicious package, typosquatted dependency, or currently vulnerable resolved version was identified from the reviewed files. The risk arises from permitting future, unreviewed releases rather than from demonstrated malicious behavior in the named requests package.

This dependency is security-sensitive because it processes outbound authentication and record-creation requests containing Feishu credentials, access tokens, and traveler data.

Attack Path

  1. The Skill is installed or rebuilt after a newer compatible requests release becomes available.
  2. The package resolver selects that release because the declaration permits any version at or above 2.28.0.
  3. The selected release has not been reviewed with the Skill and could contain a regression, compromised distribution artifact, or incompatible behavior.
  4. Package code executes within the Skill environment and participates in requests carrying credentials and personal data.

This path depends on a problematic future or otherwise untrusted package release; the audit found no evidence that the currently available dependency is malicious.

Impact Assessment

A compromised dependency would execute with the same privileges as the Skill process. That scope could include reading Feishu configuration variables, observing tenant access tokens and traveler data in process memory, altering outbound requests, or transmitting those values elsewhere. T ...[truncated 152 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin requests and its transitive dependencies to reviewed exact versions through a lock file.
  • Generate and enforce cryptographic package hashes, such as with pip-compile --generate-hashes and pip install --require-hashes.
  • Update dependencies through a controlled review process rather than resolving unrestricted versions during deployment.
  • Run vulnerability and provenance scanning against every locked dependency artifact.
  • Rebuild and test the Skill whenever dependency versions change.
  • Retrieve packages only from an explicitly configured trusted package index.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (11)

Tainted flow: 'url' from os.getenv (line 85, 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 · tools.py (reported line 16)May include surrounding context.

python
"app_secret": app_secret
    }
    try:
        resp = requests.post(url, json=payload, timeout=10)
        resp.raise_for_status()
        data = resp.json()

Tainted flow: 'url' from os.getenv (line 85, 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 · tools.py (reported line 94)May include surrounding context.

python
"records": [{"fields": fields}]
        }
        
        resp = requests.post(url, headers=headers, json=payload, timeout=10)
        resp.raise_for_status()
        result = resp.json()

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · tools.py (reported line 9)May include surrounding context.

python
FEISHU_API_BASE = "https://open.feishu.cn/open-apis"

def get_tenant_access_token(app_id: str, app_secret: str) -> str:
    """获取飞书 Tenant Access Token"""
    url = f"{FEISHU_API_BASE}/auth/v3/tenant_access_token/internal"
    payload = {
        "app_id": app_id,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README explicitly describes collecting names, phone numbers, travel preferences, dates, and budgets and storing them in Feishu, but it does not clearly disclose the data handling implications, retention, or that personal data is transmitted to an external third-party platform. This can lead operators to deploy the skill without informed consent flows or adequate privacy notice, increasing the risk of improper personal data collection and compliance violations.

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 · tools.py (reported line 16)May include surrounding context.

python
"app_secret": app_secret
    }
    try:
        resp = requests.post(url, json=payload, timeout=10)
        resp.raise_for_status()
        data = resp.json()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The function transmits personal data including name, phone number, destination, dates, budget, and special requirements to an external Feishu service, but this file provides no consent, notice, minimization, or policy enforcement. In an agent skill context, silent third-party transmission of user PII is risky because users may not understand that their travel inquiry is being stored in an external SaaS system.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

This request intentionally transmits user-supplied travel and contact data to an external Feishu table. In the skill context, the transmission is core functionality, but it is still security/privacy-relevant because it exports PII to a third-party platform and may include sensitive free-text requirements without validation or user confirmation.

Content

Scanner excerpt · tools.py (reported line 94)May include surrounding context.

python
"records": [{"fields": fields}]
        }
        
        resp = requests.post(url, headers=headers, json=payload, timeout=10)
        resp.raise_for_status()
        result = resp.json()

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

Natural-language policy issues apply to all file types, including markdown. This README presents the skill exclusively in Chinese and does not mention whether users can choose another language, which may amount to forcing a specific language without explicit opt-in.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency is specified as requests>=2.28.0, which allows any newer release to be installed and makes builds non-reproducible. This can unexpectedly pull in vulnerable or breaking versions over time, and because the exact installed version is unknown, downstream security posture cannot be reliably assessed.

Content

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

text
requests>=2.28.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
95% confidence
Finding

requests has multiple known advisories, and because the manifest does not pin a specific version, it is impossible to verify whether the installed package is affected. In a skill context, network libraries are often used to fetch remote content, so installing an affected version could expose the agent to credential leakage, TLS/verification issues, or other client-side request handling flaws depending on runtime resolution.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

Comments, docstrings, and returned user-visible messages are written exclusively in Chinese, including success and error responses. This can violate a language/locale policy when the skill does not document that it is Chinese-only or offer users a language choice.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.