Back to skill

Security audit

CP2K Cross-Code Input Studio

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent for CP2K draft generation, but its helper scripts have real file-write and generated-input validation risks that warrant Review before installation.

Install only if you trust the CP2K inputs and request JSON you will process, and avoid running it in automated workflows over untrusted files until project-name path containment and strict generated-input field validation are added. The skill does not show exfiltration, persistence, or hidden network behavior, but its local file-writing helpers need hardening.

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

Warning
Location
scripts/render-cp2k-input.py:115
Finding

Unsanitized Request Fields Permit CP2K Input Directive Injection

Content
View full analysis
str: explicit = raw.get("xc_functional") if isinstance(explicit, str) and explicit.strip(): return explicit.strip().upper() defaults.append("Defaulted xc_functional=PBE") return "PBE" ``` ```python def infer_basis_and_potential(job: Dict[str, Any], raw: Dict[str, Any], defaults: List[str], review: List[str]) -> None: if isinstance(raw.get("basis_family"), str) and raw["basis_family"].strip(): job["basis_family"] = raw["basis_family"].strip() if isinstance(raw.get("potential_family"), str) and raw["potential_family"].strip(): job["potential_family"] = raw["potential_family"].strip() ``` ```python def format_kind_blocks(elements: List[str], basis_family: str, xc: str) -> str: chunks = [] for e in elements: chunks.append( "\n".join([ f" &KIND {e}", f" BASIS_SET {basis_for(e, basis_family)}", f" POTENTIAL {potential_for(e, xc)}", " &END KIND", ]) ) return "\n".join(chunks) ``` ```python sections += [ periodic_poisson(job['periodicity']), " &QS", " METHOD GPW", " &END QS", scf_block(job), " &MGRID", f" CUTOFF {job['cutoff']}", f" REL_CUTOFF {job['rel_cutoff']}", " &END MGRID", " &XC", " &XC_FUNCTIONAL", f" &{job['xc_functional'].upper()}\n &END {job['xc_functional'].upper()}", " &END XC_FUNCTIONAL", ``` ### Technical Analysis The normalizer accepts arbitrary strings ...[truncated 2287 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/convert-cp2k-input.py:241
Finding

CP2K Project Name Enables Output Path Traversal During Gaussian and ORCA Conversion

Content
View full analysis
Dict: lines = inp.splitlines() data = { 'project': 'converted_job', 'run_type': 'ENERGY', 'charge': 0, 'multiplicity': 1, 'periodicity': 'NONE', 'kpoints': [1, 1, 1], 'cell': None, 'coords': [], 'warnings': [], 'xc_functional': 'PBE', } in_coord = False for line in lines: s = line.strip() if s.startswith('PROJECT '): data['project'] = s.split(None, 1)[1] ``` ```python def main() -> None: args = parse_args() data = parse_cp2k(read_text(args.cp2k_input)) out = Path(args.output) out.mkdir(parents=True, exist_ok=True) if args.target == 'gaussian': write_text(str(out / f"{data['project']}.gjf"), render_gaussian(data)) print(out / f"{data['project']}.gjf") elif args.target == 'orca': write_text(str(out / f"{data['project']}.inp"), render_orca(data)) print(out / f"{data['project']}.inp") ``` The write helper overwrites existing files: ```python def write_text(path: str, text: str) -> None: Path(path).write_text(text.rstrip() + '\n', encoding='utf-8') ``` ### Technical Analysis The converter treats the value following the CP2K `PROJECT` directive as a trusted filename component. For Gaussian and ORCA conversion, that value is joined directly to the user-selected output directory. `pathlib` does not neutralize traversal components. A value such as `../../target` results in a destination equivalent to `output_directory/../../target.gjf`. An absolute project path can also cause the left-hand output directory to be discarded by path joining. No basename conversion, character allowli ...[truncated 1612 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The code only implements one narrow slice of the declared description: conversion of an existing CP2K input file into draft inputs for Gaussian, ORCA, VASP, or Quantum ESPRESSO. Even that conversion is limited to a small hand-parsed subset of CP2K syntax and emits placeholder/manual-review warnings. The declared purpose is substantially broader, emphasizing CP2K draft generation, refinement, explanation, review, conservative-default selection, and natural-language/structure-to-CP2K workflow support. None of those capabilities appear in the code. Therefore the description materially overstates and mischaracterizes the actual behavior.

Content

No source excerpt is available for this finding.

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · references/cp2k-task-map.md (reported line 299)May include surrounding context.

md
## 9. Non-goals for automatic routing

These tasks should not be silently auto-generated from a vague one-line prompt without warning:
- NEB / CI-NEB / transition-state search
- excited-state workflows beyond basic documented templates
- GW / RPA / MP2 / double hybrids

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · references/design-rules.md (reported line 29)May include surrounding context.

md
- an xyz file is being treated as a periodic crystal/slab
- a specialized workflow is requested beyond the supported draft space

## Output rules

Always emit or explain:
- what task was inferred

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill explicitly instructs use of local scripts and implies file read, file write, and shell-style execution, but it declares no tool scope or permissions boundaries. That creates unnecessary ambient authority: if the runtime grants broader defaults, the skill could access or modify files beyond what is needed, increasing the blast radius of prompt injection, path abuse, or accidental destructive actions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The policy includes Chinese example requests and Chinese trigger keywords such as “帮我算一下这个结构”, “弛豫”, “动力学”, and “晶格常数”, but nowhere in the file does it state that multilingual handling is optional or limited to a justified region-specific use case. Under the stated policy rules, embedding a specific language/locale expectation without opt-in can be a natural-language policy violation.

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

python
job_inp = outdir / 'job.inp'
    report_md = outdir / 'report.md'

    subprocess.run([sys.executable, str(NORMALIZER), args.raw_request_json, '-o', str(normalized)], check=True)
    subprocess.run([sys.executable, str(RENDERER), str(normalized), args.structure_file, '-o', str(job_inp)], check=True)

    job = load_json(normalized)

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

python
report_md = outdir / 'report.md'

    subprocess.run([sys.executable, str(NORMALIZER), args.raw_request_json, '-o', str(normalized)], check=True)
    subprocess.run([sys.executable, str(RENDERER), str(normalized), args.structure_file, '-o', str(job_inp)], check=True)

    job = load_json(normalized)
    template = REPORT_TEMPLATE.read_text(encoding='utf-8')

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file says these defaults are used by the "CP2K OpenClaw skill," while the provided manifest identifies the skill as "cp2k-crosscode-input-studio." This is an active documentation contradiction about which skill the defaults belong to, creating intent ambiguity for maintainers and auditors.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This markdown file defines defaults 'intended as skill defaults' but does not specify when the skill should apply this mapping versus when it should abstain. Without explicit trigger phrases, scope boundaries, or negative examples, the activation condition is ambiguous for a manifest/markdown-style skill reference.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The natural-language parsing logic includes both English and Chinese trigger terms directly in the task inference tables, but the file does not state that multilingual parsing is intentional or user-selectable. This can create an undocumented language/locale behavior where request handling differs by language without explicit opt-in or justification.

Content

No source excerpt is available for this finding.