T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/generate_pipeline.py:276
- Finding
- Untrusted Experiment Plan Values Are Embedded into Executable Python Code## Vulnerability Details **File Location**: `scripts/generate_pipeline.py`, source extraction at lines 62–67, 75–79, and 89–96; vulnerable code-generation sink at lines 276–288 **Vulnerability Type**: Python code injection through unsafe string interpolation **Risk Level**: High ### Vulnerable Code The generator extracts attacker-controlled strings directly from the experiment plan: ```python config['dataset'] = { 'name': name_match.group(1).strip() if name_match else 'unknown', 'type': type_match.group(1).strip() if type_match else 'unknown', 'scale': scale_match.group(1).strip() if scale_match else 'unknown', 'input_shape': input_match.group(1).strip() if input_match else None, 'output_shape': output_match.group(1).strip() if output_match else None, } ``` ```python config['model'] = { 'backbone': backbone_match.group(1).strip() if backbone_match else 'resnet18', 'num_layers': int(layers_match.group(1)) if layers_match else None, 'hidden_size': int(hidden_match.group(1)) if hidden_match else 128, } ``` ```python config['training'] = { 'optimizer': optimizer_match.group(1).strip().lower() if optimizer_match else 'adamw', 'learning_rate': float(lr_match.group(1)) if lr_match else 0.001, 'batch_size': int(batch_match.group(1)) if batch_match else 32, 'epochs': int(epochs_match.group(1)) if epochs_match else 100, 'loss': loss_match.group(1).strip().lower() if loss_match else 'cross_entropy', } ``` These strings are then embedded verbatim inside quoted Python literals: ```python class Config: # 任务类型 task_type = "{config.get('task_type', 'classification')}" # 数据集配置 dataset_name = "{dataset_info.get('name', 'unknown')}" dataset_type = "{dataset_info.get('type', 'image')}" num_classes = {num_classes} # 模型配置 model_name = "{model_info.get('backbone', 'resnet18')}" pre ...[truncated 2593 chars]
- Remediation
- ## Remediation Suggestions 1. Do not construct Python string literals by directly interpolating untrusted text. 2. Serialize every generated Python string with a safe representation: ```python dataset_name = repr(dataset_info.get('name', 'unknown')) dataset_type = repr(dataset_info.get('type', 'image')) model_name = repr(model_info.get('backbone', 'resnet18')) optimizer = repr(training_info.get('optimizer', 'adamw')) ``` The template should then insert those already escaped literals without adding another pair of quotation marks. 3. Prefer generating a non-executable configuration file such as YAML or JSON using `yaml.safe_dump()` or `json.dump()`, and load it as data rather than Python source. 4. Apply strict allowlists to fields with a finite set of supported values: - Dataset type: supported dataset categories only. - Optimizer: `adamw`, `adam`, or `sgd`. - Model name: explicitly supported model identifiers. - Task type: explicitly supported task identifiers. 5. Reject line breaks, control characters, and invalid syntax in fields intended to be simple identifiers. 6. Add regression tests using quotation marks, backslashes, multiline values, comments, and Python expressions in every interpolated plan field. 7. Treat generated code as untrusted until it has passed syntax validation and security review.
