C#处理文件路径遍历漏洞 C#如何安全地构建文件路径防止攻击

煙雲

煙雲

2026-04-01

701人浏览

原创

必须用 path.getfullpath 归一化路径后再校验:先拼接用户输入与根目录,再调用 path.getfullpath 得到规范绝对路径,最后用 startswith 检查是否以安全根目录开头(结尾加路径分隔符防前缀误匹配)。

c#处理文件路径遍历漏洞 c#如何安全地构建文件路径防止攻击

Path.GetFullPath 校验路径是否超出预期目录

用户传入的文件名(比如通过 URL、表单或配置)如果含 .. 或绝对路径,直接拼接可能读写系统任意位置。光靠字符串替换或正则过滤不可靠——绕过方式太多。

正确做法是:先拼出完整路径,再用 Path.GetFullPath 归一化,然后检查它是否仍在允许根目录之下:

  • 调用 Path.GetFullPath 后,路径一定是规范化的绝对路径(如 C:data..config ile.txtC:config ile.txt
  • 必须用 StartsWith 检查归一化后的路径是否以你设定的“安全根目录”开头(注意结尾加 防止前缀匹配误判,如 C:safe 不能匹配 C:safeguard
  • 不要用 Path.Combine 后直接判断原始字符串——它不处理 ..,也不做归一化
string userSupplied = "..\..\windows\system32\cmd.exe";
string rootDir = @"C:ppdata";
string candidate = Path.Combine(rootDir, userSupplied);
string fullPath = Path.GetFullPath(candidate); // → C:windowssystem32cmd.exe
if (!fullPath.StartsWith(rootDir + Path.DirectorySeparatorChar, StringComparison.Ordinal))
{
    throw new InvalidOperationException("非法路径访问");
}

别用 string.Replace 或正则删 ..

手动清理 .. 看似简单,实则漏洞百出:URL 编码绕过(%2e%2e)、Unicode 点号(..)、混合斜杠(../..)、空字节截断等都能逃逸。

C函数速查手册(CHM版)
C函数速查手册(CHM版)

C函数速查手册(CHM版)

下载

这类“消毒”逻辑在应用层永远追不上攻击变种,且和 .NET 的路径解析行为不一致。

  • Path.GetFullPath 是 .NET 运行时内部路径解析的真实实现,它才代表最终操作系统看到的路径
  • 所有自定义过滤都只是“预判”,而真实路径解析由 GetFullPath 决定,必须以它为唯一权威
  • 即使你删了 ..,后续 Path.Combine 仍可能因参数含绝对路径而跳出去(例如 Path.Combine("C:\safe", "C:\evil\file.txt") 结果仍是 C:evil ile.txt

读文件前务必校验路径,写文件更要严格

读文件漏洞常被当成信息泄露,但写文件漏洞更危险——攻击者可覆盖 web.config、写入 WebShell、篡改日志伪造痕迹。

  • 读操作至少要防止越界读敏感配置或源码;写操作必须额外禁止写到非数据目录、禁止覆盖关键文件(如检查目标文件是否已存在且不在白名单内)
  • 不要依赖文件扩展名黑名单(如禁止 .aspx)——Windows 允许长文件名+短名,web<code>.aspx 可能被识别为 WEB~1.ASP
  • 对上传场景,建议用随机文件名+独立存储目录,原始文件名只存数据库,不参与路径构造

File.ExistsDirectory.Exists 不是安全栅栏

这两个方法只是查询存在性,它们本身不触发路径校验,也不阻止后续操作越权。更糟的是,它们可能被竞态条件利用:你检查 Exists 返回 true,紧接着 File.ReadAllText 却打开另一个同名但不同路径的文件(符号链接、重解析点等)。

  • 路径校验必须在任何 I/O 操作之前完成,且基于 Path.GetFullPath 的结果
  • 避免“先检查后执行”模式(TOCTOU),尤其在多线程或有符号链接的环境里
  • 如果必须用符号链接,确保挂载点本身也在你的安全根目录控制下,并启用 FileOptions.OpenReparsePoint 显式控制解析行为
路径归一化不是可选步骤,是必须前置的强制关卡。只要跳过 Path.GetFullPath 直接拼接或信任原始输入,就等于把文件系统大门钥匙交给了用户。

相关专题

更多
c#是什么意思
c#是什么意思

C#是一种通用的面向对象编程语言,它在.NET框架上运行,可用于开发各种类型的应用程序。本专题为大家提供c#相关的各种文章、以及下载和课程。

2023.08.08

526

5

什么是c#
什么是c#

C#(读作C Sharp)是一种现代的、通用的、面向对象的编程语言。它由微软公司开发,于2000年首次发布,主要用于开发Windows桌面应用程序、Web应用程序、移动应用程序以及游戏开发等领域。C#是一种类型安全和托管的编程语言,它结合了C++的强大性能和C语言的简单易学特点,并引入了许多新的特性和概念,如委托、属性、泛型和异步编程等,以提高开发效率和代码可维护性。

2023.08.31

1132

3

C#中base关键字的用法
C#中base关键字的用法

在C#中,base关键字用于访问当前类的基类成员,这包括基类的字段、属性、方法、构造函数、索引器以及事件。想了解更多C#的相关内容,可以阅读本专题下面的文章。

2024.03.13

556

8

C#Task用法
C#Task用法

Task在C#中是用于表示异步操作的对象,它位于System.Threading.Tasks命名空间中。想了解更多C#中各种用法的相关内容,可以阅读本专题下面的文章。

2024.03.14

1028

11

C# 并发与异步编程
C# 并发与异步编程

本专题系统讲解 C# 异步编程与并发控制,重点介绍 async 和 await 关键字、Task 类、线程池管理、并发数据结构、死锁与线程安全问题。通过多个实战项目,帮助学习者掌握 如何在 C# 中编写高效的异步代码,提升应用的并发性能与响应速度。

2026.02.03

147

18

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

2026.02.06

202

20

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

2026.03.11

526

24

C# Unity游戏开发与ECS架构实践
C# Unity游戏开发与ECS架构实践

本专题聚焦 C# 在 Unity 游戏开发中的应用,系统讲解 ECS(Entity-Component-System)架构设计、游戏对象管理、性能优化与内存控制策略。通过实际游戏案例,帮助开发者构建高性能、结构清晰的游戏系统,提高游戏开发效率与运行性能。

2026.04.13

136

20

字符串常量的表示方法
字符串常量的表示方法

字符串常量的表示方法:1、使用引号;2、转义字符;3、多行字符串;4、原始字符串;5、字符串连接;6、字符串字面量和对象;7、编码问题。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.12.26

454

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
RabbitMQ 教程手册
RabbitMQ 教程手册

共0课时 | 0人学习

Linux man-pages 项目
Linux man-pages 项目

共0课时 | 0人学习

C# 教程
C# 教程

共94课时 | 20.1万人学习