CodeQL documentation

Improper control of generation of code

ID: cs/code-injection Kind: path-problem Security severity: 9.3 Severity: error Precision: high Tags: - security - external/cwe/cwe-094 - external/cwe/cwe-095 - external/cwe/cwe-096 Query suites: - csharp-code-scanning.qls - csharp-security-extended.qls - csharp-security-and-quality.qls 

Click to see the query in the CodeQL repository

If the application dynamically compiles and runs source code constructed from user input, a malicious user may be able to run arbitrary code.

Recommendation

It is good practice not to generate, compile and run source code constructed from untrusted user input. If code must be dynamically generated using user input, the user input should be validated to prevent arbitrary code from appearing in the input. For example, a whitelist may be used to ensure that the input is limited to an acceptable range of values.

Example

In the following example, the HttpHandler accepts remote user input which is C# source code for calculating tax. It compiles and runs this code, returning the output. However, the user provided source code is entirely unvalidated, and therefore allows arbitrary code execution.

If possible, the dynamic compilation should be removed all together, and replaced with a fixed set of tax calculation algorithms. If this is not sufficiently powerful, an interpreter could be provided for a safe, restricted language.

usingMicrosoft.CSharp;usingSystem;usingSystem.CodeDom.Compiler;usingSystem.Reflection;usingSystem.Web;publicclassCodeInjectionHandler:IHttpHandler{publicvoidProcessRequest(HttpContextctx){// Code for calculating tax is provided as unvalidated user inputstringtaxFormula=ctx.Request.QueryString["tax_formula"];// Used to create C#StringBuildersourceCode=newStringBuilder("");sourceCode.Append("public class TaxCalc {\n");sourceCode.Append("\tpublic int CalculateTax(int value){\n");sourceCode.Append("\t\treturn "+taxFormula+"; \n");sourceCode.Append("\t}\n");sourceCode.Append("}\n");// BAD: This compiles the sourceCode, containing unvalidated user inputCSharpCodeProviderc=newCSharpCodeProvider();ICodeCompilericc=c.CreateCompiler();CompilerParameterscp=newCompilerParameters();CompilerResultscr=icc.CompileAssemblyFromSource(cp,sourceCode.ToString());// Compiled input is loaded, and an instance of the class is constructedSystem.Reflection.Assemblya=cr.CompiledAssembly;objecttaxCalc=a.CreateInstance("TaxCalc");// Unsafe code is executedTypetaxCalcType=o.GetType();MethodInfomi=type.GetMethod("CalculateTax");intvalue=int.Parse(ctx.Request.QueryString["value"]);ints=(int)mi.Invoke(o,newobject[]{value});// Result is returned to the userctx.Response.Write("Tax value is: "+s);}}

References

close