SV.TAINTED.PATH_TRAVERSAL

路径构造中未经验证的输入

如果程序使用外部输入来构造无特殊字符中立化的路径名,则该路径会因保持开放状态而遭受路径遍历攻击。如果未正确检查作为文件路径组成部分的外部字符串,此检查器会报告缺陷。

漏洞与风险

路径遍历攻击的目标是访问包括重要系统或应用程序数据的所有文件和目录。路径遍历攻击也可用于为程序提供恶意配置。路径遍历攻击在前 25 种最危险的编程错误中排第 13 位。

缓解与预防

为了避免此问题,建议在将原始输入用作路径名之前添加验证代码。验证代码必须包含针对下列项的检查:

  • 点-点-斜杠 ( ../ ):通过使用此序列及其变体,攻击者可浏览您的文件系统并获得任何文件的访问权限。
 请注意,( ../ ) 可出现在不同的编码中,例如“ ../../../etc/shadow ”。
  • 绝对路径:在预计相对路径也可能提供对系统中任意文件访问权限的情况下,使用绝对路径,例如“ /etc/shadow ”。
  • 空符号:当应用程序通过检查或附加特定扩展名来限制可能的文件扩展名时,如果使用空符号,则可能使攻击者能够截断所生成的文件名,从而扩大攻击范围,例如“ application.cfg%00.pdf ”。

漏洞代码示例

复制
  main.c
  #include <stdio.h>
  int main(int argc, char **argv) {
    char *name = argv[1];
    FILE *user_config = fopen(name, "r");
    if (user_config == NULL) {
      return 1;
    }
    fclose(user_config);
    return 0;
  }

Klocwork 在此示例中报告一个缺陷,因为 name 字符串通过 argv 参数接收且在未经验证的情况下用作路径名。

修正代码示例

复制
  check.h
  char* neutralize(char *);
  main.c
  #include <stdio.h>
  #include "check.h"
  int main(int argc, char **argv) {
     char *name = argv[1];
     name = neutralize(name);
     FILE *user_config = fopen(name, "r");
    if (user_config == NULL) {
       return 1;
    }
    fclose(user_config);
    return 0;
    }

      check.kb
      neutralize - TSCheckPT 1 : $1 : 1

Klocwork 在此示例中将不报告缺陷,因为外部输入已传递给 neutralize 函数且经过验证,能够保证路径安全。

扩展

此检查器可通过 Klocwork 知识库进行扩展。有关详情,请参阅调整 C/C++ 分析。