路径遍历漏洞容易通过代码审计发现吗

wen 网络安全 1

本文目录导读:

路径遍历漏洞容易通过代码审计发现吗

  1. 为什么路径遍历漏洞相对“容易”发现?
  2. 什么情况下会“不易”发现或容易被忽略?
  3. 工具辅助:自动化的“快”与人工审计的“准”
  4. 总结与建议

路径遍历漏洞(Path Traversal)相对容易被代码审计发现,尤其是在人工审计中,其风险点通常较为直观,但它的“易发现”程度取决于几个关键因素。

在静态代码中,如果代码逻辑直接、清晰,那么漏洞非常明显;但如果逻辑复杂、使用编码或间接调用,则可能被隐藏或遗漏。

下面详细分析其“易发现”程度及原因:

为什么路径遍历漏洞相对“容易”发现?

  1. 核心模式固定且明显:漏洞的根本原因是用户可控的输入被用于文件路径的拼接,且没有进行充分的过滤或验证,审计人员可以重点搜索以下高危函数/操作:

    • 文件读取/包含open()file_get_contents()include()require()readfile()等。
    • 文件写入/删除fwrite()file_put_contents()unlink()rename()move_uploaded_file()等。
    • 目录操作opendir()scandir()glob()DirectoryIterator等。
    • 下载功能:如 download.php?file=xxx
  2. 输入源清晰:审计人员会重点关注接收用户输入的变量,如 $_GET$_POST$_REQUEST$_FILES$_COOKIE、请求头(如 RefererUser-Agent 被用作路径时)等,只要发现用户输入直接或间接地流向了上述文件操作函数,就存在潜在风险。

  3. 手工审查十分有效:精明的代码审计人员会沿着数据流(数据从哪里来,到哪里去)进行跟踪,寻找路径拼接处,如果发现类似 $path = $base_dir . '/' . $_GET['file']; 的代码,且没有对 $_GET['file'] 做任何检查,可以直接判定为高危漏洞。

什么情况下会“不易”发现或容易被忽略?

虽然模式固定,但现代应用开发中存在许多“伪装”手段,使得漏洞更隐蔽。

  1. 不完整的过滤与净化

    • 黑名单过滤:只过滤了 或 ,但攻击者可以使用 ( 和 的简单组合可能绕过)、URL编码(%2e%2e%2f)、双编码(%252e%252e%252f,如果后端有解码操作)、Unicode编码(如 ..%c0%af,在特殊解码下可视为 )等。
    • 未考虑操作系统差异:Windows下使用 作为路径分隔符,Linux下使用 ,过滤了 但没过滤 ,在Windows服务器上可能被利用。
    • 过滤了 但允许 :攻击者使用 就能绕过。
    • 只过滤了绝对路径:认为限制路径必须以 /var/www/ 开头就安全,但用户输入 ../../../etc/passwd 拼接后可能成为 /var/www/../../../etc/passwd,最终指向 /etc/passwd
  2. 复杂的拼接与间接传参

    • 多次赋值$userFile = $_GET['file']; -> $processedFile = sanitize($userFile); -> $finalPath = $base . $processedFile;sanitize() 函数本身有缺陷,审计可能遗漏。
    • 通过数据库或文件配置:用户输入先被存入数据库,然后另一个文件操作从数据库中读取该值进行路径拼接,这种间接的数据流增加了追踪难度。
    • 使用配置或常量:如 define('UPLOAD_DIR', '/uploads/'); 后,程序使用 $path = UPLOAD_DIR . $userInput;,常量看似安全,但 $userInput 仍可能是 ../../etc/passwd
  3. 动态语言特性(PHP、Python等)

    • 变量函数$func = 'file_get_contents'; $result = $func($userInput);,静态分析工具可能难以跟踪这种动态调用的目标函数。
    • 回调函数array_map('file_get_contents', $userInputArray);
    • 反序列化漏洞联动:攻击者通过反序列化漏洞注入一个包含路径遍历的恶意对象,这使得漏洞触发点隐藏在反序列化链中,常规审计难以发现。
  4. 代码量巨大与逻辑分散

    • 在一个大型项目中,文件操作可能分散在几十个甚至上百个文件中,审计人员可能需要手动审查所有调用了文件操作函数的文件,如果输入源(某个接口)与操作点不在同一个文件或模块中,就容易漏掉。
    • 使用了框架(如 Spring、Laravel、Django)的路径处理或资源加载功能,框架可能提供了看似“安全”的抽象层,但如果开发者没有正确使用(如直接使用 new File(uri) 而非借助资源管理器),仍然可能出问题。

工具辅助:自动化的“快”与人工审计的“准”

  • 静态分析工具(SAST)

    • 优点:能快速扫描整个代码库,标记出所有用户输入流向文件操作函数的路径,效率极高,SonarQube、Checkmarx、Fortify、CodeQL 等。
    • 缺点易产生大量误报(False Positive),很多工具无法准确判断开发者是否做了有效的过滤(如正则匹配、白名单验证),会报告理论上存在风险但实际上被安全处理过的代码。可能漏掉(False Negative)上面提到的复杂间接传参或编码绕过情况。
    • 工具是发现初步线索的利器,但不能完全依赖
  • 人工代码审计

    • 优点:能理解上下文、业务逻辑、绕过技巧,判断工具报告的是否真实可利用,善于发现工具难以处理的复杂场景、逻辑缺陷和隐蔽的绕过方式。
    • 缺点:耗时、成本高,对审计人员经验要求高。
    • 人工审计是最终判断和确认漏洞是否存在的关键。

总结与建议

路径遍历漏洞的“易发现”程度:

  • 对经验丰富的审计人员(结合工具)非常容易,通常能快速定位并确认。
  • 对自动化工具容易发现基础样本,但难以完全判定且存在误报和漏报。
  • 对无经验的审计人员或不充分的审计容易被忽视,尤其是面对复杂过滤和间接传参时。
  • 对开发者友好(反方)非常不容易,很多开发者认为自己加了过滤(如 str_replace('../', '', $path))就安全了,但实际上这种“过滤”脆弱不堪。

最佳实践(如何让它更“难”被发现——即如何有效防御):

  1. 使用白名单:最安全的做法是使用固定的、允许的路径值列表(如 switch($action){case 'profile': $file = 'profile.html';...}),用户输入只是一个索引,而非路径。
  2. 验证和规范路径
    • 使用标准库函数(如 Python 的 os.path.realpath()、Java 的 File.getCanonicalPath())将路径解析为绝对路径
    • 然后检查这个绝对路径是否以允许的基目录开头$canonicalPath.startsWith('/var/www/uploads/')),这是最可靠的防御。
  3. 从根源避免:如果可能,不要直接让用户输入影响文件系统路径,使用从数据库中查询文件ID、文件名然后映射到服务器路径的方式。
  4. 最小化权限:运行Web应用的进程使用最低权限账户,即使发生路径遍历,能访问的文件也极其有限。

路径遍历漏洞是代码审计中的高频发现点,对专业审计人员来说相对容易发现,但对自动化工具和浅层面的审计来说也可能被绕过。理解其核心模式、过滤的脆弱性以及间接调用是发现和防范该漏洞的关键。

抱歉,评论功能暂时关闭!