·Sun自己也会犯错: 我非常尊敬Sun的工程师。然而,尽管他们都是很有天赋的人,但还是如你我一样会犯错误。 在2月23号,Sun宣布它发现了JDK中的一处漏洞。下面是他们的声明: “在某些Java运行时版本中的漏洞可能会允许恶意Java代码执行未经授权的命令。然而,恶意命令代码一定已经取得了代码执行的授权。” 如果这种代码在某种环境下被给予执行至少一条可执行命令(如echo),这个漏洞会允许不被信任的Java代码激活任何可执行命令(如格式化FORMAT)。这样的错误很可能隐藏很久而不被发现。 下面就让我们来看看具体的代码:这个漏洞是位于java.lang.Runtime类里的exec()方法中: public Process exec(String [] arstringCommand, String [] arstringEnvironment) throws IOException { // Ensure that the array parameters aren't null, their elements // aren't null, etc. . . . // Do some stuff. . . . // Get the security manager. SecurityManager securitymanager = System.getSecurityManager(); // Check the first element of the command array -- which should // be the name of the executable to invoke. Ensure that it has // executable privilege. if (securitymanager != null) securitymanager.checkExec(arstringCommand[0]); // Now, invoke the executable. return execInternal(arstringCommand, arstringEnvironment); } 你看出问题了吗? 这个错误位于最后三行中(注释和空格除外)。首先,安全管理器检查可执行名,看其是否在配置文件中有执行的授权。接下来,代码执行命令。哎哟!在一个多线程环境中,参数数组内容在这两步之间就可以改变。由于这两个输入参数数组被直接使用,调用者仍然掌握着它们的引用,并且可以修改其内容。 更正:立即复制输入数组并在拷贝中进行操作。