T09 · Insecure Skill Coding Practices
- Location
scripts/main.py:154- Finding
Unescaped User Input Enables Command Injection in Generated Rendering Scripts
- Content
View full analysis
Vulnerability Details
File Location:
scripts/main.py:154-160,scripts/main.py:283-295,scripts/main.py:412-417,scripts/main.py:480-494, andscripts/main.py:514-535
Vulnerability Type: Command injection through generated PyMOL and ChimeraX scripts
Risk Level: HighVulnerable Code
python def _generate_load(self) -> List[str]: """Generate structure loading commands.""" pdb = self.config['pdb'] lines = ["# Load structure"] # Check if PDB ID or file path if len(pdb) == 4 and pdb.isalnum() and not Path(pdb).exists(): lines.append(f"fetch {pdb}, async=0") else: lines.append(f"load {pdb}") lines.append("") return linespython else: # Specific residue lines.extend([ f"# Focus on {dof_focus}", f"select dof_target, {dof_focus}", "center dof_target", "set dof_focus, 0", ])python def _generate_load(self) -> List[str]: """Generate structure loading commands.""" pdb = self.config['pdb'] lines = ["# Load structure"] if len(pdb) == 4 and pdb.isalnum() and not Path(pdb).exists(): lines.append(f"open {pdb}") else: lines.append(f"open {pdb}") lines.append("") return linespython dof_focus = self.config.get('dof_focus', 'center') if dof_focus == "center": lines.append("# Focus on center (default)") elif dof_focus != "selection": lines.extend([ f"# Focus on {dof_focus}", f"select {dof_focus}", "view selection", ])python def _generate_render(self) -> List[str]: """Generate render and save commands.""" resolution = self.config.get('resolution', 2400) output = self.config.get('output', 'output.png') # Change extension if needed if output.endswith('.cxc'): output = output.rep ...[truncated 3332 chars]- Remediation
View remediation
Remediation Suggestions
- Define strict allow-list grammars for every value embedded in generated commands:
- Accept remote PDB identifiers only when they match a precise pattern such as
^[A-Za-z0-9]{4}$. - Validate residue selectors against a documented, minimal selector grammar.
- Restrict background colors to known color names or validated numeric color formats.
- Accept remote PDB identifiers only when they match a precise pattern such as
- Reject carriage returns, line feeds, null bytes, quotes, and target-language command delimiters in all command-bound values.
- Use target-specific quoting and escaping functions for local input and output paths. Do not rely on generic shell quoting because PyMOL and ChimeraX use their own command syntaxes.
- Keep the script output filename separate from the rendered image filename. Validate each independently and enforce the expected extension.
- Prefer APIs or structured script-generation interfaces over concatenating command strings where the target software supports them.
- Add automated tests using values containing newlines, quotes, spaces, separators, and Unicode control characters. Generation must either escape them safely or fail closed.
- Clearly indicate whether a generated script can perform network access, particularly when a remote PDB identifier produces
fetchoropen.
- Define strict allow-list grammars for every value embedded in generated commands:
