路径操作(安全漏洞)

6
一个Fortify安全审查告知我们存在一些路径操纵漏洞。大部分都很明显且容易修复,但我不知道如何修复以下问题。
string[] wsdlFiles = System.IO.Directory.GetFiles(wsdlPath, "*.wsdl");

"wsdlPath" 是从文本框中输入的。这是不可修复的吗?我可以验证路径是否存在,但这有助于解决漏洞问题吗?

1
那段代码是如何运行的?如果它是一个在输入“wsdlPath”的用户凭据下运行的Windows应用程序,我看不出有什么问题。但如果它作为Windows服务或网站的一部分运行,那就有问题了。 - Anders Abel
Fortify审查是否提供了注入的字符串? - Tung
@AndersAbel - 网络应用程序。经过身份验证的用户输入路径,如果路径有效,则被接受。 - Induster
@Tung - 他们没有提供字符串,他们认为任何字符串都有可能是有问题的。 - Induster
4个回答

8
如果数据总是从由用户确定内容的文本框中获取,并且代码使用该用户的权限运行,则唯一的威胁是用户攻击自己。这不是一个有趣的威胁。
该工具试图警告您的漏洞是,如果低信任恶意代码可以确定该字符串的内容,则恶意代码可以尝试发现关于用户计算机的事实,例如“我恰好知道有安全漏洞的某个程序是否已安装和未修补?”或“此计算机上是否有名为'admin'的用户?”,等等。

@Induster - 通过确保输入被过滤以仅允许有效的路径和文件名,您可以使其更加强大。是的,仅限管理员访问确实可以缓解问题,但如果攻击者获得管理员访问权限,这可能会使他们能够访问服务器本身,而不仅仅是您的应用程序。 - Erik Funkenbusch
1
@MystereMan:如果攻击者通过某种方式获得管理员访问权限,那么攻击者就不需要通过应用程序进行攻击。木马已经进入特洛伊城墙内,攻击者正在为他们的迈米东军队开启大门入侵。深度防御是一个好主意,但敌对管理员将简单地绕过您的防御;这就是成为管理员的含义:拥有越过保持系统安全的正常规则的能力。 - Eric Lippert
@EricLippert - 确定文件名可能有助于猜测用户名,攻击者随后可以通过远程桌面或其他远程连接尝试使用字典密码攻击。或者如果GetFiles API存在漏洞,允许任意代码执行怎么办? - Erik Funkenbusch
@MystereMan:是的,完全正确。但是如果攻击者已经是网站管理员,那么他们就不需要使用此应用程序来枚举用户名。他们可以直接枚举用户名。而且,如果攻击者已经是管理员,那么他们不需要使用漏洞来执行任意代码:他们已经是管理员了,可以直接执行任意代码。 - Eric Lippert
大家好 (@EricLippert @MystereMan),请帮我解决以下问题,因为我在修复Coverity问题时遇到了困难 - [https://stackoverflow.com/questions/66455078/how-to-solve-the-path-manipulation-vulnerabilities-issue-coverity-scan-asp-n?noredirect=1#comment117509646_66455078] - Chandu
显示剩余6条评论

1

您永远不应该直接将任何内容馈送到未经过滤的操作系统API中。您应该对输入进行清理,确保它不包含路径(例如"../../../somefile"),并确保截断长名称,并仅包含有效的文件名字符(例如,与国际字符相关的各种错误已经存在)。


输入正在按照应有的方式处理。显然,这是因为它来自用户输入而被标记为红旗。但这需要保持不变。在我看来,除了消除用户输入(这不是一个选项),似乎我们无法在这里做任何事情。也许有人能够看到我看不到的东西。 - Induster
2
@Induster - 你的回复让人困惑。你所说的“输入已被处理为应该处理的方式”是什么意思?你的评论表明它并没有被正确处理。你必须对输入进行清理,以确保你不会将非法数据或不允许的文件路径输入到操作系统API中。如果你认为用户可以随意输入系统密码文件之类的内容,那就算了吧。 - Erik Funkenbusch

1

使用该代码,任何已经通过身份验证和授权使用该功能的用户都可以访问服务器上的文件系统。访问将使用运行Web应用程序的服务帐户的凭据进行。

根据返回的数据如何使用,恶意用户可能能够获取更多信息或使服务器以不预期的方式运行。

您应该将允许的路径集限制为仅包含一个或少数精选目录。使用Path类中的函数将字符串组合成路径-它们会处理用户为您输入c:\allowedpath\..\windows\system32等情况。


0
这种情况需要进行编码和解码,以确保数据在任何地方都没有被篡改。因为如果在解密过程中数据被更改,你将得到错误的结果。
你可以创建自己的编码和解码方式。我使用了System.Security.Cryptography提供的RijndaelManaged和PasswordDeriveBytes类来实现。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接