Back to skill

Security audit

支持发送文件到飞书,大于20MB自动分卷裁切

Security checks for vulnerabilities and agentic risk

Overview

Review recommended: the skill is mainly a Feishu file sender, but it automatically installs code dependencies and can duplicate or leave processed copies of local files while uploading data externally.

Install only if you are comfortable with this skill reading the exact local files you specify, using Feishu app credentials, uploading those files to Feishu, and sending messages as the configured app. Preinstall reviewed dependencies instead of relying on runtime pip install, avoid storing broad secrets in the skill .env file, and use caution with large non-media files because the ZIP splitting behavior can create persistent duplicate archives.

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/feishu_send.py:15
Finding
Automatic Installation of an Unpinned Python Dependency<![CDATA[ ## Vulnerability Details **File Location**: `scripts/feishu_send.py:15-30, 61-65, 111`; `scripts/feishu_send_ascii.py:15-30, 61-65, 111` **Vulnerability Type**: Unsafe runtime dependency installation **Risk Level**: Medium ### Vulnerable Code ```python PYTHON_DEPS = ['requests'] def check_python_package(package): try: __import__(package) return True except ImportError: return False def install_python_package(package): print(f'正在安装 Python 依赖: {package}...') try: subprocess.check_call( [sys.executable, '-m', 'pip', 'install', package], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL ) print(f'{package} 安装成功') return True except subprocess.CalledProcessError: print(f'{package} 安装失败,请手动执行: pip install {package}') return False ``` ```python if missing_python: print(f'检测到缺失的 Python 依赖: {", ".join(missing_python)}') if auto_install: for pkg in missing_python: install_python_package(pkg) ``` ```python if not check_environment(): print('环境检测未通过,请先安装缺失的依赖') sys.exit(1) ``` ### Technical Analysis Both sender scripts automatically invoke `pip install requests` when the dependency is absent. The package has no pinned version, locked transitive dependency set, or hash verification. The installation also relies on the active pip index and configuration, which may have been changed to use an untrusted mirror or proxy. Python package installation can execute package build and installation logic. Consequently, installing an unverified package is a code-execution operation rather than a simple data download. Suppressing standard output and standard error further reduces visibility into the selected package version, source, and installation behavior. Runtime package installation is not required for the core function of uploading a file to Feishu. Dependencies should be installed as a separate, ex ...[truncated 1287 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic package installation from runtime code. 2. Declare dependencies in a dedicated requirements or project configuration file. 3. Pin `requests` and its transitive dependencies to reviewed versions. 4. Use a lock file and require package hashes, such as `pip install --require-hashes`. 5. Restrict installation to an approved package index and validate pip configuration in deployment environments. 6. Perform dependency installation during a controlled build or administrator-approved setup phase. 7. Do not suppress installation output in deployment logs; retain enough information to audit the resolved versions and sources. 8. Run the Skill in a minimally privileged virtual environment or container. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/feishu_send.py:273
Finding
Incorrect ZIP Splitting Causes Disk and Network Resource Amplification<![CDATA[ ## Vulnerability Details **File Location**: `scripts/feishu_send.py:273-288, 328-333`; `scripts/feishu_send_ascii.py:273-288, 328-333` **Vulnerability Type**: Improper file chunking and uncontrolled resource consumption **Risk Level**: Medium ### Vulnerable Code ```python def split_zip_by_size(zip_path, max_size_mb=MAX_FILE_SIZE_MB): size_mb = os.path.getsize(zip_path) / (1024*1024) if size_mb <= max_size_mb: return [zip_path] print(f'ZIP {size_mb:.1f}MB 超过 {max_size_mb}MB,需要分割...') base_name = os.path.splitext(zip_path)[0] original_size = os.path.getsize(zip_path) num_parts = math.ceil(original_size / (max_size_mb * 1024 * 1024)) part_files = [] for i in range(num_parts): part_path = f"{base_name}_part{i:03d}.zip" with zipfile.ZipFile(part_path, 'w', zipfile.ZIP_DEFLATED, compresslevel=6) as zf: zf.write(zip_path, arcname=os.path.basename(zip_path)) part_files.append(part_path) print(f'ZIP 分割完成: {len(part_files)} 段') return part_files ``` ```python zip_path = compress_to_zip(filepath) zip_size = os.path.getsize(zip_path) / (1024*1024) if zip_size > MAX_FILE_SIZE_MB: print(f'压缩后 {zip_size:.1f}MB 仍超出限制,分割 ZIP...') parts = split_zip_by_size(zip_path, MAX_FILE_SIZE_MB) files_to_send.extend(parts) else: files_to_send.append(zip_path) ``` ### Technical Analysis The function does not divide the oversized ZIP into bounded chunks. Every generated “part” is a new ZIP archive containing the entire original ZIP: ```python zf.write(zip_path, arcname=os.path.basename(zip_path)) ``` For an archive of size `S` and a configured part limit `L`, the function creates approximately `ceil(S/L)` complete copies. Total generated data is therefore approximately: ```text S × ceil(S/L) ``` This grows roughly quadratically relative to the input size. Each generated archive remains larger than the configured limit because it contains the complete oversized archive, so the ...[truncated 2027 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the current logic with genuine byte-range chunking or a standards-compliant multipart archive implementation. 2. Ensure every produced upload part is strictly below the Feishu size limit, including archive overhead. 3. Write all generated archives and chunks into a managed temporary directory rather than beside the source file. 4. Remove generated files in a `finally` block on success, upload failure, interruption, or processing error. 5. Impose explicit limits on accepted source size, total generated output size, part count, processing time, and temporary disk usage. 6. Check available disk capacity before compression and splitting. 7. Verify each part's size before uploading and abort safely if any part exceeds the configured limit. 8. Avoid recompressing an already compressed ZIP inside multiple additional ZIP archives. 9. Apply the correction to both identical sender scripts or consolidate them into one maintained implementation to prevent security fixes from diverging. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (50)

Tainted flow: 'APP_ID' from os.getenv (line 117, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
if not APP_ID or not APP_SECRET:
        raise Exception('未配置 FEISHU_APP_ID 或 FEISHU_APP_SECRET 环境变量。请设置后重试。')
    url = 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal'
    resp = requests.post(url, json={'app_id': APP_ID, 'app_secret': APP_SECRET}, timeout=10)
    data = resp.json()
    if data.get('code') != 0:
        raise Exception(f'获取 token 失败: {data}')
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'APP_ID' from os.getenv (line 117, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
if not APP_ID or not APP_SECRET:
        raise Exception('未配置 FEISHU_APP_ID 或 FEISHU_APP_SECRET 环境变量。请设置后重试。')
    url = 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal'
    resp = requests.post(url, json={'app_id': APP_ID, 'app_secret': APP_SECRET}, timeout=10)
    data = resp.json()
    if data.get('code') != 0:
        raise Exception(f'获取 token 失败: {data}')
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
This duplicate mismatch finding highlights the same core risk: the skill promises non-reencoding 20MB segmentation and simple ZIP handling, but may instead transcode audio, auto-merge separate streams, and create misleading ZIP parts. In a tool that transmits local data externally, behavior mismatches are security-relevant because users may expose more content than intended or trust incorrect handling guarantees.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
This duplicate mismatch finding highlights the same core risk: the skill promises non-reencoding 20MB segmentation and simple ZIP handling, but may instead transcode audio, auto-merge separate streams, and create misleading ZIP parts. In a tool that transmits local data externally, behavior mismatches are security-relevant because users may expose more content than intended or trust incorrect handling guarantees.

Credential Access

High
Category
Privilege Escalation
Content
## 配置

### 方式一:.env 文件(推荐)

在技能目录下创建 `.env` 文件:
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def load_env_from_skill_dir():
    script_dir = os.path.dirname(os.path.abspath(__file__))
    skill_dir = os.path.dirname(script_dir)
    env_path = os.path.join(skill_dir, '.env')
    if os.path.isfile(env_path):
        with open(env_path, 'r', encoding='utf-8') as f:
            for line in f:
Confidence
82% confidence
Finding
The script accesses a .env file in the skill directory and loads any key/value pairs into process environment variables automatically. In an agent or shared workspace context, this can cause unintended secret consumption from local files and makes credential use less visible to operators, increasing the risk of misuse or accidental exposure through subsequent network actions.

Credential Access

High
Category
Privilege Escalation
Content
def load_env_from_skill_dir():
    script_dir = os.path.dirname(os.path.abspath(__file__))
    skill_dir = os.path.dirname(script_dir)
    env_path = os.path.join(skill_dir, '.env')
    if os.path.isfile(env_path):
        with open(env_path, 'r', encoding='utf-8') as f:
            for line in f:
Confidence
91% confidence
Finding
The script automatically loads secrets from a plaintext .env file in the skill directory, which increases the chance of credential exposure through weak file permissions, accidental inclusion in archives, or unintended reuse by other local processes. In a skill that already performs outbound file transfer, colocating and auto-loading credentials from the working tree enlarges the blast radius if the directory contents are mishandled.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill can read local files, access environment secrets, invoke shell tools, and send data over the network, but it does not declare an explicit tool scope such as allowed-tools or permissions. That omission reduces transparency and weakens policy enforcement, making it easier for a caller to invoke a data-exfiltration-capable skill without clear guardrails.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill description says it sends local files to Feishu, but it lacks a prominent explicit warning that local filesystem contents will be transmitted to an external service. For exfiltration-prone functionality, this missing warning makes accidental disclosure more likely, especially when paths may reference sensitive documents or media.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
Automatically installing dependencies from pip during execution is a dangerous behavior for a skill whose stated purpose is file transfer. It introduces supply-chain risk and causes external code to be installed and potentially executed without explicit approval, which is especially risky in automated agent environments.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def install_python_package(package):
    print(f'正在安装 Python 依赖: {package}...')
    try:
        subprocess.check_call([sys.executable, '-m', 'pip', 'install', package], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        print(f'{package} 安装成功')
        return True
    except subprocess.CalledProcessError:
Confidence
89% confidence
Finding
The script automatically installs Python packages at runtime via pip, which exceeds the stated file-sending purpose and causes code from external package repositories to be fetched and executed on the host. Even though the package name is hardcoded, auto-installing dependencies during skill execution expands the attack surface and can lead to unintended code execution or supply-chain exposure.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script silently reads credentials from the environment and a local .env file without prominent disclosure. In an agent skill setting, undeclared secret access is risky because operators may not realize the skill consumes sensitive authentication material from the workspace or runtime environment.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The script uploads arbitrary local files and recipient identifiers to Feishu but does not provide an explicit safety warning, confirmation step, or clear disclosure at the point of transfer. In an agent skill context, this increases the chance of accidental exfiltration of sensitive local data because the capability is broad and the destination is external.

External Transmission

Medium
Category
Data Exfiltration
Content
url = f'https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type={receive_id_type}'
    body = {'receive_id': receive_id, 'msg_type': 'file', 'content': json.dumps({'file_key': file_key}), 'uuid': str(uuid.uuid4())}
    headers = {'Authorization': f'Bearer {token}', 'Content-Type': 'application/json; charset=utf-8'}
    resp = requests.post(url, headers=headers, json=body, timeout=60)
    return resp.json()

def process_and_send_file(token, filepath, receive_id, receive_id_type):
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
def check_python_package(package):
    try:
        __import__(package)
        return True
    except ImportError:
        return False
Confidence
75% confidence
Finding
Dynamic __import__() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
def check_python_package(package):
    try:
        __import__(package)
        return True
    except ImportError:
        return False
Confidence
75% confidence
Finding
Dynamic __import__() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def install_python_package(package):
    print(f'正在安装 Python 依赖: {package}...')
    try:
        subprocess.check_call([sys.executable, '-m', 'pip', 'install', package], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        print(f'{package} 安装成功')
        return True
    except subprocess.CalledProcessError:
Confidence
89% confidence
Finding
The script automatically installs Python packages at runtime via pip without explicit user confirmation or pinning versions. In a skill whose purpose is to move local files off-host, silent dependency installation expands the trust boundary and can execute unreviewed package install hooks or pull tampered packages from the package index.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def check_system_command(cmd):
    try:
        result = subprocess.run([cmd, '-version'], capture_output=True, timeout=5)
        return result.returncode == 0
    except (FileNotFoundError, subprocess.TimeoutExpired):
        return False
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def check_system_command(cmd):
    try:
        result = subprocess.run([cmd, '-version'], capture_output=True, timeout=5)
        return result.returncode == 0
    except (FileNotFoundError, subprocess.TimeoutExpired):
        return False
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
'ffmpeg': {
            'win32': 'choco install ffmpeg 或 winget install ffmpeg',
            'darwin': 'brew install ffmpeg',
            'linux': 'sudo apt install ffmpeg 或 sudo yum install ffmpeg'
        },
        'ffprobe': {
            'win32': 'choco install ffmpeg 或 winget install ffmpeg',
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
'ffmpeg': {
            'win32': 'choco install ffmpeg 或 winget install ffmpeg',
            'darwin': 'brew install ffmpeg',
            'linux': 'sudo apt install ffmpeg 或 sudo yum install ffmpeg'
        },
        'ffprobe': {
            'win32': 'choco install ffmpeg 或 winget install ffmpeg',
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
'ffmpeg': {
            'win32': 'choco install ffmpeg 或 winget install ffmpeg',
            'darwin': 'brew install ffmpeg',
            'linux': 'sudo apt install ffmpeg 或 sudo yum install ffmpeg'
        },
        'ffprobe': {
            'win32': 'choco install ffmpeg 或 winget install ffmpeg',
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
'ffmpeg': {
            'win32': 'choco install ffmpeg 或 winget install ffmpeg',
            'darwin': 'brew install ffmpeg',
            'linux': 'sudo apt install ffmpeg 或 sudo yum install ffmpeg'
        },
        'ffprobe': {
            'win32': 'choco install ffmpeg 或 winget install ffmpeg',
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

External Transmission

Medium
Category
Data Exfiltration
Content
if not APP_ID or not APP_SECRET:
        raise Exception('未配置 FEISHU_APP_ID 或 FEISHU_APP_SECRET 环境变量。请设置后重试。')
    url = 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal'
    resp = requests.post(url, json={'app_id': APP_ID, 'app_secret': APP_SECRET}, timeout=10)
    data = resp.json()
    if data.get('code') != 0:
        raise Exception(f'获取 token 失败: {data}')
Confidence
80% 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
if not APP_ID or not APP_SECRET:
        raise Exception('未配置 FEISHU_APP_ID 或 FEISHU_APP_SECRET 环境变量。请设置后重试。')
    url = 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal'
    resp = requests.post(url, json={'app_id': APP_ID, 'app_secret': APP_SECRET}, timeout=10)
    data = resp.json()
    if data.get('code') != 0:
        raise Exception(f'获取 token 失败: {data}')
Confidence
80% 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.