整个命令是一个巨大的行走漏洞。或不。安全不是非黑即白。它是灰色的阴影。这段代码不是完全白色的,而是浅灰色的(即:它为攻击者提供了一些路由,但这些路由通常在正确配置的系统上不可用,并且“in”的几种方式通常认为给定的要可怕得多和直接路由,这使得开放的攻击面大多没有实际意义)。
TL;DR:警告是愚蠢的,告诉 fortify 忽略这个,另外,您的安全流程可能需要更新。此外,此代码很可能实际上不会执行您想要的操作。不幸的是,没有简单的方法可以编写出你想要的代码。为带来坏消息而道歉。
更详细一点:
特别是,“我将通过不完全遵循一般分析来处理每一个强化警告,而只是通过写出我能想到的最接近的东西来摆脱它”是一种很好的思考方式已经编写了安全代码,但实际上并没有这样做。
您必须了解 fortify 的目的。然后,您必须弄清楚攻击面实际上是什么,要么不接受这个(因此更改/删除暴露它的 ALL 代码),要么接受它,并证明这个攻击面是不相关的。在这种情况下,第二个选项(接受、记录并继续)听起来几乎适用于所有可以想象的场景。
在这个特定实例中,您编写的代码有 2 个不同的攻击面:
磁盘访问导致被盗
您正在运行java。就这样。相对路径。您不知道将运行什么 java,而且您绝对不能保证它与您当前的 JVM 来自同一个 java。它很容易成为恶意脚本。这将要求攻击者找到一种方法将该脚本放在路径上的文件夹中。对于非 root 用户,. 通常在路径上,并且首先在路径上,所以如果这是例如服务器和攻击者可以设法使服务器将文件保存在自己的目录中,繁荣。你去吧。您的服务器现已受到威胁。
强化没有警告这是错误的;一般来说,相对路径只是一个坏主意,如果不是出于安全原因,那么出于稳定性原因:这不适用于许多服务器。不幸的是,以独立于平台和部署的方式从第一个 JVM 可靠地调用第二个 JVM 基本上是不可能的。这就是为什么真正的解决方案通常是直接避免它,或者设置明确的操作系统绑定脚本来处理这个问题(然后使用绝对路径运行脚本)。
破坏系统属性
是的,如果攻击者设法诱使您的 JVM 运行 System.setProperty("java.class.path"),那么他们可能会破坏您的机器。 但这太荒谬了。您应该立即忘记这个攻击面,因为它的长度为零。
您运行System.setProperty(untrustedUserInput, someOtherUntrustedUserInput); 的可能性有多大?来吧,搜索你的代码库。这是.. 高度不太可能在那里。某些攻击者可能会强制您的服务器运行它想要的 any 字节码(这将需要一个开放的安全漏洞,例如具有缓冲区溢出的 PNG 解析器或其他;这意味着它要么是攻击者0-day,或者您确保及时修补服务器的流程已损坏,在这种情况下您会遇到更大的问题)。如果攻击者可以做到这一点,他们可以设置属性,是的。
他们也可以直接上ProcessBuilder 任何想要的东西,所以,这一点完全没有实际意义。您将注意力集中在巨山旁边的岩石上,并将其定为这片土地的最高点。
因此,得出结论:在这种情况下,强化警告愚蠢,应该完全忽略。但是,此代码IS 肯定会打开一些攻击面;不过,不是特别大。特别是,如果没有人可以登录此框或写入运行此 JVM 进程的用户的目录(他们肯定不应该这样做,或者编辑路径!) - 你很好。如果不是这样,你的问题就更大了。
这就是安全性的工作原理:您将这些内容写下来,并在整个过程中不断审查(不仅仅是代码、文档、检查,每两年与系统操作员进行一次面谈,以检查他们是否阅读了文档并且是遵循指令)。您无法关闭所有攻击面。您只能提高对它们的认识并确保它们不会被滥用。
我认为没有一种创造性的方法可以让 fortify 闭嘴(也许通过反射调用 processbuilder,fortify 可能无法解决),但所做的只是降低安全性.这里唯一正确的解决方案是完全放弃 fortify(这可能有点激烈),或者按照人们应该如何使用它的方式使用它:将它找到的位置作为 非详尽 代码列表分析。不像“这是我需要修复的东西列表,然后我的代码是安全的”。这种分析就足够了,因此,贴上适当的注释或评论或任何需要的东西来告诉你已经手动接受了这个分析并且它不应该再告诉你了。
真正的解决方案
不要这样做。完全没有。尝试找到一种方法来做任何需要做的事情,而无需调用新的 JVM。如果这不在桌面上,请重新定义它的工作方式:与其“使用与该 VM 相同的类路径克隆该 VM”,不如考虑“运行一个不一定是该 VM 的克隆的新 VM,因为我启动的实际 JVM 可能与此 VM 所支持的可执行文件不同,并且类路径是显式配置的,或者至少是在其他地方配置的。换句话说,如果必须,请记录此服务器的正确设置需要在特定位置创建一个脚本,并适当配置访问权限,从而引导具有特定类路径的 JVM。