T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/main.py:248
- Finding
- R Code Injection Through Unescaped CLI Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py`, lines 248-292 **Vulnerability Type**: Generated-code injection **Risk Level**: High ### Vulnerable Code ```python r_script = f'''# Volcano Plot Script (R/ggplot2) # Generated by volcano-plot-script library(ggplot2) library(dplyr) # Read data data <- read.csv("{args.input}") # Parameters log2fc_col <- "{args.log2fc_col}" pvalue_col <- "{args.pvalue_col}" gene_col <- "{args.gene_col}" log2fc_thresh <- {args.log2fc_thresh} pvalue_thresh <- {args.pvalue_thresh} # Process data data$negLog10_pvalue <- -log10(data[[pvalue_col]]) data <- data %>% mutate(regulation = case_when( .data[[pvalue_col]] < pvalue_thresh & .data[[log2fc_col]] > log2fc_thresh ~ "up", .data[[pvalue_col]] < pvalue_thresh & .data[[log2fc_col]] < -log2fc_thresh ~ "down", TRUE ~ "ns" )) # Create plot p <- ggplot(data, aes(x=.data[[log2fc_col]], y=negLog10_pvalue, color=regulation)) + geom_point(alpha=0.6, size=1.5) + scale_color_manual(values=c("up"="{args.color_up}", "down"="{args.color_down}", "ns"="{args.color_ns}"), labels=c("up"="Upregulated", "down"="Downregulated", "ns"="Not significant")) + geom_hline(yintercept=-log10(pvalue_thresh), linetype="dashed", color="gray") + geom_vline(xintercept=c(-log2fc_thresh, log2fc_thresh), linetype="dashed", color="gray") + labs(x="{args.xlabel}", y="{args.ylabel}", title="{args.title}") + theme_minimal() + theme(legend.position="bottom") # Save plot ggsave("{output_path}", p, width=10, height=8, dpi={args.dpi}) print(paste("Plot saved to:", "{output_path}")) ''' ``` ### Technical Analysis The optional R exporter constructs executable R source code through direct Python f-string interpolation. Several attacker-controllable command-line values are placed inside quoted R string literals without escaping or val ...[truncated 2121 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not generate executable R source by directly interpolating untrusted strings. 2. Prefer a fixed R script that receives values through command-line arguments, environment variables, or a separate JSON/CSV configuration file. 3. If source generation is unavoidable, encode every string using a dedicated serializer that produces a valid R string literal. Do not rely on simple quote replacement. 4. Reject newline characters, carriage returns, NUL bytes, and other control characters in all text arguments. 5. Apply allowlist validation where possible: - Require column names to exist in the parsed dataset. - Validate colors with a strict accepted color format or a trusted color parser. - Restrict output extensions to supported formats. - Enforce reasonable length limits on labels and titles. 6. Resolve and validate file paths according to the intended workspace policy. 7. Add adversarial tests for double quotes, single quotes, backslashes, newlines, R comments, statement separators, and embedded function calls. 8. Clearly mark generated scripts as untrusted until all embedded values have been safely encoded. ]]>
