Back to skill

Security audit

Enterprise File Writer

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed local file-writing skill, but its broad overwrite authority and confirmed data-integrity flaws make it something users should review carefully before installing.

Install only if you trust agents to write local files on your behalf and can closely review every path and content payload. Avoid using it for production configs, .env files, scripts, or existing spreadsheets unless you have backups and explicitly approve the write; do not rely on --encoding for non-UTF-8 output or on XLSX append to preserve existing workbook data.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
write_file.py:490
Finding
XLSX append mode silently destroys existing spreadsheet data<![CDATA[ ## Vulnerability Details **File Location**: `write_file.py:490-535` **Vulnerability Type**: Destructive data-integrity flaw in archive append handling **Risk Level**: High ### Vulnerable Code ```python def append_to_xlsx(file_path, rows, force=False): """ 追加数据到 Excel 文件(简化实现:读取现有数据,合并后重新创建) Args: file_path: 文件路径 rows: 二维数组,每行数据 force: 是否跳过安全警告确认 Returns: 写入的字节数 """ # 安全检查 is_safe, warnings = check_path_safety(file_path) if warnings: for warning in warnings: print(f"[安全警告] {warning}", file=sys.stderr) if not force: print(f"[操作中止] 检测到潜在安全风险,请使用 --force 参数确认执行", file=sys.stderr) raise PermissionError("安全警告:写入操作被中止") # 读取现有数据 existing_rows = [] with zipfile.ZipFile(file_path, 'r') as zf: try: shared_strings_content = zf.read('xl/sharedStrings.xml').decode('utf-8') # 提取所有字符串 import re matches = re.findall(r'<t>([^<]*)</t>', shared_strings_content) # 读取 worksheet 获取行列结构 worksheet_content = zf.read('xl/worksheets/sheet1.xml').decode('utf-8') # 简单解析:获取行数 row_matches = re.findall(r'<row r="(\d+)"', worksheet_content) if row_matches: max_row = int(max(row_matches)) # 这里简化处理,假设每行有相同列数 # 实际应该更复杂地解析 else: max_row = 0 except: pass # 合并数据并重新创建 all_rows = existing_rows + rows return create_xlsx(file_path, all_rows if all_rows else rows) ``` ### Technical Analysis The function claims to append rows to an existing XLSX document by reading the current workbook and rebuilding it. However, `existing_rows` is initialized as an empty list and is never populated. Although the code extracts shared-string matches and worksheet row numbers, neither result is converted into the existing cell ...[truncated 2102 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not advertise or permit XLSX append mode until existing workbook content can be preserved reliably. 2. Replace regular-expression parsing with a standards-compliant XLSX library such as `openpyxl`, if adding a dependency is acceptable. 3. If standard-library-only operation is required, correctly parse: - Shared and inline strings. - Cell references and types. - Sparse rows and columns. - Multiple worksheets. - XML entities and namespaces. 4. Preserve all ZIP members not intentionally modified, including styles, formulas, relationships, metadata, and additional worksheets. 5. Remove the bare `except`. Catch specific exceptions and abort without modifying the original file when parsing fails. 6. Generate the modified workbook in a temporary file located on the same filesystem. 7. Validate that the temporary output is a readable XLSX archive before replacement. 8. Atomically replace the original only after successful validation. 9. Retain a backup or require explicit confirmation before reconstructing an existing workbook. 10. Add regression tests proving that append mode preserves existing values and workbook components. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
write_file.py:185
Finding
Sensitive-path protection can be bypassed through symbolic links and path replacement races<![CDATA[ ## Vulnerability Details **File Location**: `write_file.py:185-220, 231-263` **Vulnerability Type**: Symbolic-link following and time-of-check/time-of-use path-validation bypass **Risk Level**: Medium ### Vulnerable Code ```python def check_path_safety(file_path): """ 检查路径安全性 Returns: tuple: (is_safe, warning_messages) """ warnings = [] abs_path = os.path.abspath(file_path) is_windows = sys.platform == 'win32' # 检查敏感系统路径 if is_windows: for pattern in SENSITIVE_PATH_PATTERNS_WINDOWS: if re.search(pattern, abs_path, re.IGNORECASE): warnings.append(f"警告:目标路径位于系统敏感目录:{abs_path}") break else: for pattern in SENSITIVE_PATH_PATTERNS_UNIX: if re.search(pattern, abs_path): warnings.append(f"警告:目标路径位于系统敏感目录:{abs_path}") break # 检查敏感文件类型 for pattern in SENSITIVE_FILE_PATTERNS: if re.search(pattern, abs_path, re.IGNORECASE): warnings.append(f"警告:目标文件可能包含敏感信息:{abs_path}") break # 检查是否覆盖可执行脚本 _, ext = os.path.splitext(file_path) if ext.lower() in EXECUTABLE_EXTENSIONS: warnings.append(f"警告:正在写入可执行脚本文件({ext}),请确保内容安全:{abs_path}") # 检查路径遍历风险 if '..' in file_path: warnings.append("警告:路径中包含 '..',请确保路径安全") is_safe = len(warnings) == 0 return is_safe, warnings ``` ```python def write_text_file(file_path, content, mode='write', force=False): """ 写入文本文件内容 Args: file_path: 文件路径 content: 要写入的内容字符串 mode: 'write' 或 'append' force: 是否跳过安全警告确认 Returns: 写入的字节数 """ # 安全检查 is_safe, warnings = check_path_safety(file_path) if warnings: for warning in warnings: print(f"[安全警告] {warning}", file=sys.stderr) if not force: print(f"[操作中止] 检测到潜在安全风险,请使用 --force 参数确认执行", file=sys.stderr) ...[truncated 3467 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Resolve the target using `os.path.realpath()` and apply sensitive-path rules to the resolved destination. 2. Resolve and validate the parent directory separately when creating a new file. 3. Reject existing targets that are symbolic links by checking them with `os.lstat()` rather than APIs that follow links. 4. On supported Unix-like platforms, open files with `os.open()` and `O_NOFOLLOW`. 5. Use directory file descriptors and relative opens so validation and opening remain anchored to the same trusted parent directory. 6. After opening, compare `os.fstat()` results with the previously inspected object where applicable. 7. Prevent writes through attacker-controlled parent directories when sensitive operations are involved. 8. For overwrite operations, write to a safely created temporary file in the validated directory and perform an atomic replacement. 9. Apply the same hardened path-opening helper to text, DOCX, and XLSX operations. 10. Add tests covering: - Direct symbolic-link targets. - Symbolic links in parent path components. - Dangling links. - Target replacement between validation and opening. - Sensitive destinations reached through non-sensitive aliases. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (14)

Credential Access

High
Category
Privilege Escalation
Content
# 预期输出: [操作中止] 检测到潜在安全风险,请使用 --force 参数确认执行

# 测试 2: 写入敏感文件类型(应被中止)
python write_file.py "/path/to/.env" "SECRET=test"
# 预期输出: [安全警告] 警告:目标文件可能包含敏感信息

# 测试 3: 写入可执行脚本(应输出警告)
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill presents itself as enterprise-safe, but its documented behavior still permits writing to sensitive paths, executable scripts, and credential-related files with only warning-based controls and a bypass flag. This creates a dangerous trust mismatch: an agent may invoke it assuming meaningful policy enforcement, while the tool can still be used to overwrite configs, persistence scripts, or secret-bearing files.

Credential Access

High
Category
Privilege Escalation
Content
|------|--------|----------|
| **文本类** | .txt, .md, .markdown, .rst, .log, .csv, .tsv | UTF-8 文本写入 |
| **代码类** | .java, .py, .js, .ts, .jsx, .tsx, .c, .cpp, .h, .cs, .go, .rs, .rb, .php, .vue | UTF-8 文本写入 |
| **配置类** | .json, .xml, .yaml, .yml, .toml, .ini, .cfg, .properties, .gradle, .config, .env | UTF-8 文本写入 |
| **样式类** | .html, .htm, .css, .scss, .sass, .less | UTF-8 文本写入 |
| **脚本类** | .sh, .bash, .bat, .cmd, .ps1, .sql | UTF-8 文本写入 |
| **Office** | .docx (Word), .xlsx (Excel) | OpenXML ZIP 格式写入 |
Confidence
92% confidence
Finding
Explicitly supporting writes to .env files enables modification of credential-bearing configuration commonly used for secrets, API keys, and service credentials. In the context of a generic file-writing skill, this is especially dangerous because an agent can be induced to plant, replace, or corrupt secrets, redirect services, or weaken security controls with a single file write.

Credential Access

High
Category
Privilege Escalation
Content
'.sql', '.graphql', '.gql',
    
    # 配置文件
    '.config', '.env', '.env.example', '.env.local', '.env.production',
    '.htaccess', '.editorconfig', '.gitignore', '.gitattributes', '.gitmodules',
    '.dockerfile', '.dockerignore',
    '.makefile', '.mk', '.cmake',
Confidence
89% confidence
Finding
Allowing writes to `.env.production` is especially dangerous because production deployments commonly ingest it automatically, so a single file modification can change credentials, service endpoints, feature flags, or execution behavior at runtime. In an enterprise file-writer skill, this raises the impact from ordinary file output to potential production compromise and persistence.

Credential Access

High
Category
Privilege Escalation
Content
'.sql', '.graphql', '.gql',
    
    # 配置文件
    '.config', '.env', '.env.example', '.env.local', '.env.production',
    '.htaccess', '.editorconfig', '.gitignore', '.gitattributes', '.gitmodules',
    '.dockerfile', '.dockerignore',
    '.makefile', '.mk', '.cmake',
Confidence
89% confidence
Finding
Allowing writes to `.env.production` is especially dangerous because production deployments commonly ingest it automatically, so a single file modification can change credentials, service endpoints, feature flags, or execution behavior at runtime. In an enterprise file-writer skill, this raises the impact from ordinary file output to potential production compromise and persistence.

Credential Access

High
Category
Privilege Escalation
Content
'.sql', '.graphql', '.gql',
    
    # 配置文件
    '.config', '.env', '.env.example', '.env.local', '.env.production',
    '.htaccess', '.editorconfig', '.gitignore', '.gitattributes', '.gitmodules',
    '.dockerfile', '.dockerignore',
    '.makefile', '.mk', '.cmake',
Confidence
89% confidence
Finding
Allowing writes to `.env.production` is especially dangerous because production deployments commonly ingest it automatically, so a single file modification can change credentials, service endpoints, feature flags, or execution behavior at runtime. In an enterprise file-writer skill, this raises the impact from ordinary file output to potential production compromise and persistence.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
This markdown file is written entirely in Chinese and does not indicate that language is optional or limited to a justified region-specific context. Under the policy, forcing a specific language without user opt-in is a natural-language locale violation.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The manifest description, activation conditions, safety guidance, and usage instructions consistently require Chinese comprehension. This effectively forces a specific language/locale for users and agents without documenting an opt-in or justified region-specific constraint.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The report explicitly validates overwrite-capable file writing but does not mention any safeguard, warning, or confirmation requirement around destructive writes. In a file-writer skill, this omission can normalize unsafe usage and increase the risk of accidental data loss or abuse to replace important local files, especially in enterprise contexts where sensitive configuration or document files may exist.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The natural-language description is entirely in Chinese and presents the skill's behavior and support scope only in that language. For a general-purpose file writer, this appears to impose a language/locale constraint without user opt-in or a documented region-specific justification, which matches the policy-violation criteria.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The module docstring presents the skill name, usage, supported file types, and operational description entirely in Chinese, which imposes a specific language on users. Under the policy, locale/language constraints should either be optional for the user or explicitly justified as region-specific; this file does neither.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The manifest explicitly claims correct UTF-8/GBK handling to avoid garbled text, and the CLI exposes an --encoding option, but the actual text write path hard-codes content.encode('utf-8'). This means GBK or any non-UTF-8 encoding request is not honored, so the implemented behavior does not match the stated capability.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The argparse description, help text, examples, warning prompts, success messages, and error output are all written in Chinese. This creates a language policy issue because users are not given a choice of language and no business or regional justification is stated in the file.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The help text explicitly documents '--encoding gbk' as a supported usage example, creating a clear expectation that encoding selection affects file output. In practice, the write path ignores the encoding argument and always writes UTF-8 bytes, so the documentation contradicts actual behavior.

Static analysis

No suspicious patterns detected.