CodeQL 文档

不当的代码生成控制

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

点击查看 CodeQL 代码库中的查询

如果应用程序动态编译并运行从用户输入构造的源代码,则恶意用户可能能够运行任意代码。

建议

良好的做法是不生成、编译和运行从不受信任的用户输入构造的源代码。如果必须使用用户输入动态生成代码,则应验证用户输入,以防止任意代码出现在输入中。例如,可以使用白名单来确保输入限制在可接受的值范围内。

示例

在以下示例中,HttpHandler 接受远程用户输入,该输入是用于计算税款的 C# 源代码。它会编译并运行此代码,并返回输出。但是,用户提供的源代码完全未经验证,因此允许执行任意代码。

如果可能,应完全删除动态编译,并将其替换为一组固定的税款计算算法。如果这还不够强大,可以为安全、受限的语言提供解释器。

using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Web;

public class CodeInjectionHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext ctx)
    {
        // Code for calculating tax is provided as unvalidated user input
        string taxFormula = ctx.Request.QueryString["tax_formula"];
        // Used to create C#
        StringBuilder sourceCode = new StringBuilder("");
        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 input
        CSharpCodeProvider c = new CSharpCodeProvider();
        ICodeCompiler icc = c.CreateCompiler();
        CompilerParameters cp = new CompilerParameters();
        CompilerResults cr = icc.CompileAssemblyFromSource(cp, sourceCode.ToString());

        // Compiled input is loaded, and an instance of the class is constructed
        System.Reflection.Assembly a = cr.CompiledAssembly;
        object taxCalc = a.CreateInstance("TaxCalc");

        // Unsafe code is executed
        Type taxCalcType = o.GetType();
        MethodInfo mi = type.GetMethod("CalculateTax");
        int value = int.Parse(ctx.Request.QueryString["value"]);
        int s = (int)mi.Invoke(o, new object[] { value });

        // Result is returned to the user
        ctx.Response.Write("Tax value is: " + s);
    }
}

参考

  • ©GitHub 公司
  • 条款
  • 隐私