Back to skill

Security audit

Protein Key Fragment Analysis

Security checks for vulnerabilities and agentic risk

Overview

The skill is a legitimate protein-analysis tool, but unsafe path handling can write analysis files outside the intended results directory.

Install only if you are comfortable running local bioinformatics scripts that create files in your workspace. Use a disposable or project-specific output directory, avoid running the analysis as root, and do not pass species names containing path separators, '..', or absolute paths. Treat the biological function and disulfide-bond claims as heuristic until supported by explicit domain hits, structural prediction, or experimental evidence.

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
scripts/protein_key_fragment_analysis.py:423
Finding
Path Traversal Through Unsanitized Species Name Allows Writes Outside the Output Directory<![CDATA[ ## Vulnerability Details **File Location**: `scripts/protein_key_fragment_analysis.py`, lines 423–484 **Vulnerability Type**: Path traversal / arbitrary-location file write **Risk Level**: High ### Complete Vulnerable Code Snippet ```python species_dir = Path(output_dir) / species_name species_dir.mkdir(exist_ok=True) # ... aln_path = species_dir / f"{species_name}_aligned.fasta" # ... consensus_path = species_dir / f"{species_name}_consensus.fasta" clean_consensus = "".join(aa for aa in consensus_seq if aa != '-') with open(consensus_path, 'w') as f: f.write(f">{species_name}_consensus\n") for i in range(0, len(clean_consensus), 60): f.write(clean_consensus[i:i+60] + "\n") # ... fragments_path = species_dir / f"{species_name}_key_fragments.json" with open(fragments_path, 'w', encoding='utf-8') as f: json.dump({ "species": species_name, "date": DATE_STR, "consensus_length": len(clean_consensus), "key_fragments": key_fragments }, f, ensure_ascii=False, indent=2) report_path = generate_report( species_name, sequences, consensus_seq, conservation_scores, key_fragments, species_dir ) ``` The value reaches this function directly from the command-line positional argument: ```python parser.add_argument("species_name", nargs="?", help="物种名称") # ... result = analyze_species(args.species_name, fasta, out_dir, precomputed_aligned=args.precomputed_aligned) ``` ### Technical Analysis The user-controlled `species_name` is used as both a directory component and part of several output filenames without validation. `pathlib.Path` does not automatically constrain a joined path to its intended base directory. A value containing parent-directory components, such as `../target`, can escape `output_dir`. An absolute value can also cause the preceding base path to be discarded during path composition. The resulting paths are subsequently passed to directory creation, Py ...[truncated 2723 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat the species name as a display label, not as a filesystem path. 2. Convert it to a strict filename-safe identifier. Prefer an allowlist such as ASCII letters, digits, underscores, and hyphens. 3. Reject absolute paths, `.` and `..` components, path separators, control characters, and empty identifiers. 4. Resolve every output path and verify that it remains beneath the resolved output root before creating or writing it. 5. Use the sanitized identifier consistently for all directories and filenames while preserving the original species name only inside report content. 6. Avoid running this analysis with elevated privileges. 7. Add tests for traversal values, absolute paths, mixed separators, and encoded or Unicode separator-like characters. A hardened implementation could use: ```python import re from pathlib import Path def safe_species_id(species_name: str) -> str: if not re.fullmatch(r"[A-Za-z0-9_-]+", species_name): raise ValueError( "Species name must contain only letters, digits, underscores, and hyphens" ) return species_name def confined_path(base: Path, *parts: str) -> Path: base = base.resolve() candidate = base.joinpath(*parts).resolve() if candidate != base and base not in candidate.parents: raise ValueError("Output path escapes the configured output directory") return candidate species_id = safe_species_id(species_name) output_root = Path(output_dir).resolve() output_root.mkdir(parents=True, exist_ok=True) species_dir = confined_path(output_root, species_id) species_dir.mkdir(parents=False, exist_ok=True) aln_path = confined_path( species_dir, f"{species_id}_aligned.fasta" ) consensus_path = confined_path( species_dir, f"{species_id}_consensus.fasta" ) fragments_path = confined_path( species_dir, f"{species_id}_key_fragments.json" ) ``` If spaces or non-ASCII biological names must be supported, create a deterministic safe slug or ...[truncated 163 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (79)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
代码整体仍属于蛋白关键序列/片段分析流程的一部分,因此与声明存在一定相关性;但声明强调“适用于任何蛋白质家族”“对任意多物种FASTA执行完整分析流程”,而实际脚本是一个面向固定数据集的批处理驱动器,输入来源、物种列表和处理策略都被硬编码,不是通用入口。此外,声明中的若干能力(跨物种差异比较、氨基酸组成统计、功能预测)在该代码片段中没有明确实现;这里主要做的是按物种逐个分析并汇总结果。因此描述对能力范围和通用性有明显夸大,属于描述与实际行为不完全一致。

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill documents shell execution and file-writing behavior but does not declare any explicit tool scope or permissions boundaries. In an agent environment, that increases the chance of over-broad tool access, unintended command execution, or filesystem modification beyond what users expect.

Description-Behavior Mismatch

Medium
Confidence
90% confidence
Finding
Manifest 在 L003 以及正文 L008 直接声称本流程适用于“任何蛋白质家族”。但 L064、L068 和 L158-L172 说明关键功能块识别依赖预先配置的 Pfam/特征序列,新蛋白家族需要手工编辑 `KNOWN_MOTIFS` 等配置后才能完成该部分功能预测,因此“适用于任何家族”的表述比实际能力更宽。

Vague Triggers

Medium
Confidence
93% confidence
Finding
An overly broad trigger description can cause the skill to activate for unrelated protein-related requests, leading to unnecessary shell/file operations and unexpected handling of user data. In agent systems, over-triggering expands the effective attack surface and can route benign queries into higher-risk execution paths.

Natural-Language Policy Violations

Medium
Confidence
83% confidence
Finding
文件中的名称、描述和用户可见说明全部固定为中文,未说明是否支持按用户语言偏好切换,也未提供显式语言选择。对于未明确选择中文的用户,这可能构成默认强制特定语言的 locale 策略问题。

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Ubuntu/Debian
sudo apt install clustalo

# 或 conda
conda install -c bioconda clustalo
Confidence
88% confidence
Finding
Including `sudo apt install` in skill instructions normalizes privileged command execution and may lead operators or agents to run root-level package installation in environments where such elevation is unsafe or prohibited. While this is framed as dependency setup, encouraging sudo increases the blast radius if commands are copied blindly or adapted unsafely.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The entire skill document is written in Chinese and does not indicate that language selection is optional or configurable. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy concern unless the locale restriction is clearly documented and justified.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"-v"
    ]
    print(f"\n[MSA] 运行 ClustalOmega...")
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        print(f"  错误:{result.stderr}")
        return False
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
This manifest-style JSON mixes English field names with Chinese-only user-facing values such as fragment identifiers, criticality labels, function descriptions, and physicochemical-property text. Because the file provides no indication that the skill is region-specific or that users can opt into this locale, it creates a language/locale policy concern.

Intent-Code Divergence

Medium
Confidence
90% confidence
Finding
L182 明确声明“关键片段功能解读基于已知蛋白家族注释”,而正文中多数片段在 L34-L39、L48-L53、L62-L67 等仅给出“可能涉及结构稳定或功能活性位点”“倾向埋藏于蛋白质疏水核心”等通用性描述。文档的方法部分虽在 L178 提到基于 Pfam/InterPro,但结果区没有给出任何具体 Pfam/InterPro 命中、家族名或注释证据,形成文档意图与实际内容的明显偏差。

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This manifest-style JSON uses Chinese natural-language field values throughout, including fragment identifiers, criticality labels, function descriptions, evidence text, and physicochemical descriptions. Because the file provides no indication that Chinese is optional or required for a justified region-specific purpose, it appears to impose a specific language/locale without user choice.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
For fragment 高保守连续区_371_378, the composition reports Hydrophobic 50.0% and Acidic 50.0%, yet the fragment is documented as having dominant_category "Hydrophobic" and a hydrophobic physicochemical interpretation. That documentation conflicts with the underlying data because there is no unique dominant category at 50/50 split.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
L193-L195声称关键片段识别包含“匹配已知保守块(Pfam注释特征序列)”,但L25-L162列出的片段全是按位置命名的连续保守区和保守Cys检测,没有任何Pfam家族/结构域命中、特征序列名称或对应证据。该文档的说明与实际呈现的分析结果存在直接意图层面的不一致,容易让读者误以为已完成数据库特征匹配。

Intent-Code Divergence

Medium
Confidence
89% confidence
Finding
L201和L205表示功能解读基于Pfam/InterPro及已知蛋白家族注释,但L34、L48、L62等位置的功能描述均为“可能涉及结构稳定或功能活性位点”这类泛化推断,且多数片段标注为“功能待确认”。这与“基于数据库注释”的表述不符,因为文档没有展示任何数据库条目、家族名、结构域名或匹配证据。

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The report states the conserved cysteines 'form disulfide bonds' as a factual conclusion, while the documented method only detects conserved Cys residues as potential disulfide participants. This overstates evidence and can mislead downstream biological interpretation, experimental design, or annotation decisions by presenting an unverified structural claim as confirmed.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
L158将该步骤描述为‘检测保守Cys残基(潜在二硫键)’,说明方法本身只能发现可能相关的半胱氨酸位点;但L132却直接写成‘形成二硫键,维持蛋白三维构象稳定性’,把潜在性结论表述为已成立功能。这是文档中的明确意图-结论升级,超出了所述方法能支持的内容。

Intent-Code Divergence

Medium
Confidence
90% confidence
Finding
L164和L168说明功能注释应基于Pfam/InterPro及已知蛋白家族注释生成,但L33-L39、L47-L53、L61-L67、L75-L81、L89-L95、L103-L109、L117-L123中的“功能”实际只是通用的‘可能涉及结构稳定或功能活性位点’和理化性质描述,没有展示任何具体家族注释证据。这属于文档对分析依据的表述与实际报告内容不一致,而非单纯信息不完整。

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The report equates conserved cysteines with disulfide-bond formation even though the described method only detects conserved Cys residues and provides no structural, localization, redox, or bond-prediction evidence. This can mislead users into believing a structural constraint has been established, potentially distorting experimental design or biological interpretation.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The report claims that functional interpretation is based on known protein family annotations, but the actual region descriptions remain generic and speculative. This creates a scientific integrity and trustworthiness issue: users may overestimate the evidentiary basis of the annotations and make downstream research decisions on unsupported functional claims.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The report states that conserved cysteines form disulfide bonds, but the documented method only detects conserved Cys residues and does not perform disulfide-bond prediction. This overstates biological certainty and can mislead downstream users into making incorrect structural or functional inferences from unsupported claims.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The report directly infers disulfide-bond formation from the mere presence of conserved cysteines, without structural, subcellular, or redox-environment evidence. In a protein analysis context this can materially mislead downstream biological interpretation, especially for likely intracellular proteins where disulfide bonds are less plausible.

Intent-Code Divergence

Medium
Confidence
92% confidence
Finding
The report claims the pipeline matches known conserved blocks from Pfam, but the results section does not show any actual Pfam-derived hits, identifiers, boundaries, or evidence. This creates a provenance and overclaiming problem: users may trust that database-backed functional annotation occurred when the output appears to be based only on generic conservation detection.

Intent-Code Divergence

Medium
Confidence
88% confidence
Finding
方法部分 L119 仅说明检测保守 Cys 残基作为‘潜在二硫键’,属于候选线索;但结果部分 L89-L90 将该片段标为‘结构关键’并直接赋予‘形成二硫键,维持蛋白三维构象稳定性’的功能解释。对仅凭保守 Cys 检测得出的结果来说,这种表述比方法描述更确定,构成文档意图与实际结论强度的不一致。

Static analysis

No suspicious patterns detected.