与Windows文件路径中的特殊字符相关的安全漏洞

时间:2014-07-01 01:53:23

标签: c# windows special-characters filenames

我可能在Windows应用程序中发现了一个安全漏洞。它接收来自用户的字符串并应用以下逻辑:

string fileName = userInput + ".notSecret";
return new FileStream(fileName, FileMode.Open, FileAccess.Read);

用户是否可以通过提前终止文件名来输入任何允许他们输入新文件扩展名的字符?

例如:

  

" secret_file.Secret \ 0"

1 个答案:

答案 0 :(得分:1)

您指出的方案很可能不是安全漏洞。首先,.NET字符串不是空截断的,可能包含空字符。此外,如果您尝试在StreamWriter构造函数中创建一个包含\0的控制字符的文件,您会发现它会引发异常:

Unhandled Exception: System.ArgumentException: Illegal characters in path.
   at System.IO.Path.CheckInvalidPathChars(String path, Boolean checkAdditional)
   at System.IO.Path.GetFileName(String path)
   at System.IO.StreamWriter.CreateFile(String path, Boolean append, Boolean checkHost)
   at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize, Boolean checkHost)
   at System.IO.StreamWriter..ctor(String path)

请注意,如果.NET IO框架支持备用数据流,成为安全漏洞;用户可以写入“userInput.secret:.notSecret”,强制写入“userInput.secret”的备用数据流。由于System.IO类不支持备用数据流,因此抛出NotSupportedException并且不写入恶意文件。

使用文件扩展名作为安全控件时,可能存在潜在的文件系统影响。例如,如果用户将扩展名为.notSecret的文件作为hard link映射到扩展名为.secret的文件,则写入一个文件也会写入另一个文件(因为在硬链接,单个文件可以有多个具有不同扩展名的路径。)

假设userInput是用户提供的原始代码,代码无法清理用户输入。处理来自不受信任来源的输入时,代码应为all user input is evil until proven otherwise。如果预期用户的输入是某个值(例如,没有特殊字符),则处理输入的代码应该确保它匹配,并且如果不匹配则清理它(或抛出异常)。仅允许已知良好的输入比仅仅禁止已知不良的输入更安全。