CS.SV.TAINTED.INJECTION

C# 中的命令注入

每当从用户或外部环境接受字符串输入时,都应该在使用前验证类型、长度、格式和范围。在得到妥善验证之前,数据将被视为已被污染。CS.SV.TAINTED 系列检查器会查找代码中使用已污染数据的情况。

CS.SV.TAINTED.INJECTION 检查器会标记代码,其中可能会将被污染的字符串用作调用外部进程的例程的参数。

漏洞与风险

当代码输入未经妥善验证时,攻击者可以精心地将输入编制为并非应用程序所预期的格式。接收意外的输入可能会导致控制流改变、任意的资源控制以及任意的代码执行。通过此类机会,攻击者可以
  • 提供无法预料的值并导致程序崩溃
  • 导致过度的资源消耗
  • 读取机密数据
  • 使用恶意输入来修改数据或改变控制流
  • 执行任意命令
  • 运行攻击者可能想运行的任何进程

缓解与预防

要避免受污染输入错误

  • 了解不受信任的输入进入软件的所有可能区域:参数或自变量、cookie、从网络读取的输入、环境变量、反向 DNS 查找、查询结果、文件名、数据库以及任何外部系统。
  • 运用允许列表或“已知正确”策略来监控输入,而不是只依赖阻止列表或“已知错误”策略。
  • 对输入的所有相关属性进行验证,包括长度、输入类型、范围、缺失或额外输入、语法以及一致性。
  • 如果应用程序的客户端有安全性检查,请确保在服务器端也进行安全性检查。
  • 如果应用程序将来自多个来源的输入组合在一起,请在组合来源之后执行验证。

漏洞代码示例 1

复制
  using System;
  using System.Diagnostics;
  namespace TaintedResource
  {
    class TestTaintedInjection
    {
      public static void TaintedResourceExample1()
      {
              string taintedString1 = Console.ReadLine();
          Process.Start(taintedString1);              // CS.SV.TAINTED.INJECTION
     }
   }
 }

Klocwork 针对第 10 行生成问题报告,这表示“在第 9 行通过调用 ReadLine 从外部函数接收了未验证的字符串 taintedString1,而该字符串可在第 10 行通过调用 Start 而作为命令行运行。用户输入的使用可能会导致主机系统上出现任意命令执行。用于命令执行时,请检查字符串的长度和内容。”在这种情况下,如果使用可能被污染的数据启动进程,便可能会遭到恶意用户利用。

漏洞代码示例 2

复制
  using System;
  using System.Diagnostics;
  namespace TaintedResource
  {
    class TestTaintedInjection
    {
      public static void TaintedResourceExample1()
      {
       string taintedString = Console.ReadLine();        // tainted source
      ProcessStartInfo psi = new ProcessStartInfo();
      psi.FileName = taintedString;
      Process proc = new Process();
      proc.StartInfo = psi;
      proc.Start();                                     // CS.SV.TAINTED.INJECTION
     }
   }
 }

Klocwork 针对第 10 行生成问题报告,这表示“在第 9 行通过调用 ReadLine 从外部函数接收了未验证的字符串 taintedString,而该字符串可在第 14 行通过调用 Start 而作为命令行运行。用户输入的使用可能会导致主机系统上出现任意命令执行。用于命令执行时,请检查字符串的长度和内容。”在这种情况下,如果使用可能被污染的数据启动进程,便可能会遭到恶意用户利用。

安全培训

应用程序安全培训材料由 Secure Code Warrior 提供。