Back to skill

Security audit

Web To Feishu

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches its stated document-conversion purpose, but it asks users to run unpinned external code and grant broader cloud permissions than the implementation appears to need.

Review before installing. Use a dedicated Feishu/ima app or API key with minimal permissions, remove unnecessary Feishu folder access unless you need it, avoid converting sensitive local files unless you intend to upload them, and pin or vendor the x-tweet-fetcher dependency before using Twitter/X conversion.

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/web_to_md.py:23
Finding

Unpinned and Externally Managed Executable Dependencies

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-2, SKILL.md:119-131, scripts/web_to_md.py:23-32, scripts/web_to_md.py:62-84
Vulnerability Type: Third-party supply-chain exposure through unpinned packages and execution of a mutable external script
Risk Level: Medium

Vulnerable Code

requirements.txt:1-2:

text
requests
python-dotenv

scripts/web_to_md.py:23-32:

python
SKILLS_DIR = os.path.expanduser("~/.aily/workspace/skills")
TWEET_FETCHER = os.path.join(SKILLS_DIR, "x-tweet-fetcher/scripts/fetch_tweet.py")
TWEET_TO_MD = os.path.join(SKILLS_DIR, "web-to-feishu/scripts/tweet_to_md.py")


def _run(cmd, check=True):
    result = subprocess.run(cmd, capture_output=True, text=True, check=check)
    return result.stdout.strip()

scripts/web_to_md.py:62-84:

python
def _convert_twitter(url: str, output_path: str = None, replies: bool = False) -> str:
    fetch_cmd = [sys.executable, TWEET_FETCHER, "--url", url, "--pretty"]
    if replies:
        fetch_cmd.append("--replies")

    try:
        json_str = _run(fetch_cmd)
    except subprocess.CalledProcessError as e:
        print(f"Failed to fetch tweet: {e.stderr}", file=sys.stderr)
        sys.exit(1)

    with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as tmp:
        tmp.write(json_str)
        tmp_json = tmp.name

    convert_cmd = [sys.executable, TWEET_TO_MD, "--input", tmp_json]
    if output_path:
        convert_cmd.extend(["--output", output_path])

    try:
        result = _run(convert_cmd)

Technical Analysis

The Python dependencies are declared without exact versions or integrity hashes. Package resolution can therefore select different releases over time, including a compromised future release.

More significantly, Twitter conversion executes fetch_tweet.py from a mutable workspace directory outside the reviewed Skill package. T ...[truncated 1687 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin every Python dependency to an exact, reviewed version.
  2. Use a lockfile or hash-checked requirements file, such as pip install --require-hashes.
  3. Add the actual runtime conversion dependency to the dependency manifest rather than relying only on installation prose.
  4. Identify the canonical x-tweet-fetcher repository explicitly and pin it to a reviewed commit.
  5. Verify the external script using a cryptographic checksum or signature before execution.
  6. Prefer vendoring the reviewed converter inside this Skill so the audited package contains the complete executable implementation.
  7. If external execution remains necessary, run it in a restricted subprocess without unrelated cloud credentials and with limited filesystem and network access.
  8. Document a controlled dependency-update and security-review process.

T05 · Unauthorized Access and Privilege Escalation

Note
Location
references/feishu-setup.md:17
Finding

Feishu Setup Requires an Unnecessary Folder Permission

Content
View full analysis

Vulnerability Details

File Location: references/feishu-setup.md:17-22
Vulnerability Type: Excessive cloud API permissions that violate least privilege
Risk Level: Low

Vulnerable Configuration

English rendering of the permission table at references/feishu-setup.md:17-22:

markdown
| Permission | Purpose | Necessity |
|---|---|---|
| `docx.document:readonly` | Read cloud documents | Optional |
| `docx.document:write` | Create and edit cloud documents | Required |
| `drive:drive:folder` | Cloud document folder operations | Required |
| `sheets:Spreadsheet:readonly` | Read spreadsheets | Optional |

Technical Analysis

The setup guide marks drive:drive:folder as mandatory. However, the reviewed Feishu implementation only creates a document, inserts document blocks, and retrieves document information through Docx endpoints. It does not perform a folder creation, movement, enumeration, or management operation.

Requiring folder-management authorization therefore exceeds the minimum privileges necessary for the implemented document-upload workflow. This does not independently bypass Feishu authorization, but it increases the capabilities available to a stolen or misused application credential.

The network transmission of FEISHU_APP_ID and FEISHU_APP_SECRET to the official Feishu token endpoint is necessary for the declared cloud-document functionality. The excessive-permission issue concerns the setup scope, not that credential exchange.

Attack Path

  1. A user follows the setup guide and grants the application the required document-write permission plus the unnecessary folder permission.
  2. The application secret or resulting tenant access token is exposed through a separate compromise, malicious dependency, or unsafe host environment.
  3. An attacker uses the credential or token to invoke Feishu Drive folder APIs.
  4. The attacker obtains folder-related capabilities that were not ...[truncated 551 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove drive:drive:folder from the permissions documented as mandatory.
  2. Require only the minimum Feishu Docx write permission needed to create documents and insert blocks.
  3. Keep read-only document and spreadsheet permissions disabled unless a separately documented feature uses them.
  4. If folder placement is added later, present folder access as an optional, feature-specific permission.
  5. Document the exact API operation associated with every requested scope.
  6. Encourage credential rotation and use of a dedicated Feishu application restricted to this workflow.
  7. Re-test document creation with the reduced permission set before publishing the revised setup guide.
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The workflow claims optional save/export to Feishu and Tencent ima, but the implementation reportedly only writes locally or to stdout. Security-sensitive workflows must accurately describe data egress paths; otherwise users and operators may misunderstand whether content is being retained locally, sent to cloud services, or both.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The workflow claims optional save/export to Feishu and Tencent ima, but the implementation reportedly only writes locally or to stdout. Security-sensitive workflows must accurately describe data egress paths; otherwise users and operators may misunderstand whether content is being retained locally, sent to cloud services, or both.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The workflow claims optional save/export to Feishu and Tencent ima, but the implementation reportedly only writes locally or to stdout. Security-sensitive workflows must accurately describe data egress paths; otherwise users and operators may misunderstand whether content is being retained locally, sent to cloud services, or both.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The workflow claims optional save/export to Feishu and Tencent ima, but the implementation reportedly only writes locally or to stdout. Security-sensitive workflows must accurately describe data egress paths; otherwise users and operators may misunderstand whether content is being retained locally, sent to cloud services, or both.

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

python
安全说明:
- 所有凭证通过环境变量读取,不硬编码
- 支持 .env 文件加载(需 python-dotenv)
- 凭证不写入日志或任何输出

Usage:

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill advertises and documents use of network access, shell execution, environment variables, and file reads/writes, but it does not declare an explicit tool scope such as permissions or allowed-tools. That omission weakens least-privilege controls and can allow the skill to run with broader capabilities than users or the platform expect, especially given it processes arbitrary URLs and local files.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The listed trigger phrases are generic and unconstrained, making accidental activation likely. In a skill that can access local files, fetch arbitrary URLs, and potentially publish content to third-party services, accidental triggering can expose or move data without sufficiently clear user intent.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The activation condition triggers on essentially any user request involving a URL or local file and asks to convert/store it, which is too broad for a skill with file, network, and cloud-publishing behavior. Over-broad activation increases the chance of unintended invocation on ordinary conversations, sensitive files, or links the user did not intend to process with this skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The entire skill document is written in Chinese and all user-facing instructions assume Chinese without any opt-in, alternative language, or explanation that the skill is region- or locale-specific. This is a natural-language policy concern because it imposes a language choice on users rather than offering one or documenting why the restriction is necessary.

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

python
"app_secret": self.app_secret
        }

        resp = requests.post(url, json=payload, timeout=30)
        resp.raise_for_status()
        data = resp.json()

Tainted flow: 'url' from requests.post (line 224, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/feishu_client.py (reported line 56)May include surrounding context.

python
"app_secret": self.app_secret
        }

        resp = requests.post(url, json=payload, timeout=30)
        resp.raise_for_status()
        data = resp.json()

Tainted flow: 'url' from requests.post (line 224, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/feishu_client.py (reported line 95)May include surrounding context.

python
"""
        url = f"{self.BASE_URL}/docx/v1/documents"
        payload = {"title": title}
        resp = requests.post(url, headers=self._headers(), json=payload, timeout=30)
        resp.raise_for_status()
        data = resp.json()

Tainted flow: 'url' from requests.post (line 224, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/feishu_client.py (reported line 121)May include surrounding context.

python
"""
        url = f"{self.BASE_URL}/docx/v1/documents"
        payload = {"title": title}
        resp = requests.post(url, headers=self._headers(), json=payload, timeout=30)
        resp.raise_for_status()
        data = resp.json()

Tainted flow: 'url' from requests.post (line 224, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/feishu_client.py (reported line 225)May include surrounding context.

python
def get_document_info(self, document_id: str) -> Dict[str, Any]:
        """获取文档信息"""
        url = f"{self.BASE_URL}/docx/v1/documents/{document_id}"
        resp = requests.get(url, headers=self._headers(), timeout=30)
        resp.raise_for_status()
        return resp.json()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The create_note path sends arbitrary note title/content and optional folder identifiers to Tencent's remote API, but this client code provides no explicit disclosure, consent check, or sensitivity gating before transmission. In the context of a skill designed to convert arbitrary web pages and local files into cloud notes, users may unintentionally upload sensitive or proprietary data to a third-party service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The CLI create flow accepts a local file path, reads the file contents, and then uploads that content to the remote ima service without any warning, preview, or confirmation. Because this skill explicitly supports local files such as PDF, Office documents, images, and audio-derived content, the lack of disclosure materially increases the risk of accidental exfiltration of sensitive local data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file hard-codes Chinese section headers and later emits Chinese labels such as 作者, 发布时间, 附图, and 评论, which forces generated output into a specific language. The policy allows locale constraints only when they are user-selectable or clearly justified as region-specific, neither of which is present here.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/web_to_md.py (reported line 31)May include surrounding context.

python
def _run(cmd, check=True):
    result = subprocess.run(cmd, capture_output=True, text=True, check=check)
    return result.stdout.strip()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The converter fetches and processes arbitrary remote URLs with no allowlist, warning, or network-boundary controls. In a skill that explicitly accepts user-supplied URLs, this increases SSRF-style risk, including access to internal services or unintended outbound requests from the host environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code writes to an arbitrary output path and automatically creates parent directories without any confirmation or path restrictions. In an agent context, if a user or upstream workflow can influence --output, this can overwrite files or place content in sensitive locations on the host filesystem.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency on requests is unpinned, so installs may resolve to different versions over time, including versions with known security issues or breaking changes. In a skill that fetches arbitrary web content and possibly handles authentication material, dependency drift increases supply-chain risk and can expose the skill to known requests flaws if an unsafe version is installed.

Content

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

text
requests
python-dotenv

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
88% confidence
Finding

The manifest does not pin requests, and requests has multiple known advisories across versions, so the project may install an affected release without any visibility. This is more concerning in this skill because it retrieves attacker-controlled URLs and remote content, making HTTP-client weaknesses more relevant than in an offline-only tool.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

python-dotenv is also unpinned, which makes builds non-reproducible and can silently introduce vulnerable or incompatible releases. Because this skill likely uses environment variables for API tokens or document service credentials, unsafe dependency resolution could affect secret handling or file operations performed by the library.

Content

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

text
requests
python-dotenv

Unverifiable Dependency: python-dotenv has 2 known advisory(ies) (CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
84% confidence
Finding

python-dotenv has known advisories, but the current manifest leaves the effective installed version unknowable, so vulnerable versions may be pulled in during deployment. While dotenv is typically less exposed than a network parser, this skill may run in environments with local files and secrets, so flawed dotenv behavior could still affect configuration integrity or secret safety.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The manifest describes a skill whose purpose is converting URLs or local files into structured Markdown and then optionally saving the result to Feishu or ima. This file also implements a general-purpose get_document_info API wrapper, which is not part of the stated conversion/save workflow and broadens behavior from 'convert and save' to additional document API access.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/ima-setup.md:24