2

假设您正在编写一个通用doSomething方法,您可以在其中检查字符串参数的有效性:

public void doSomething(String argument) {
   if(!checkArgument(argument)) {
      // Argument is not valid
      throw new IllegalArgumentException("Argument " + argument + " is not valid");
   }

   ...

抛出其消息可能包含任意文本的异常是否安全?或者它可以使程序暴露于日志伪造或其他一些安全问题?

是否有处理此类情况的最佳实践?

4

4 回答 4

1

这实际上取决于抛出异常后您将如何处理它。一般来说,我会说这可能是一个坏主意。根据经验,您永远不应该“使用”未经处理的论点。这里有一些攻击场景,这可能会让您大开眼界。

  1. 这是针对网页的,您正在向用户显示此错误。在这种情况下,攻击者可以执行XSS攻击等。
  2. 此错误将打印到日志中。在这里它看起来很安全,但攻击者仍然对您的文件系统有一些(全部是有限的)访问权限。他们可以使用这种机制来存储代码以供将来使用,或者可能损坏日志(或文件系统的其他方面)。如果将参数逐字节写入文件,则尤其如此。
  3. 此错误将存储在数据库中。这里有足够的模式信息,攻击者可能能够改变或破坏整个数据库。

就其本身而言,这可能不足以让攻击者窃取任何信息,但结合其他错误,这可以用来控制机器。不过,您可以进行一些基本的清理工作并避免大多数这些问题。

  1. 正如@assylias 所建议的,执行长度检查。
  2. 确保参数中的所有字符都是字母数字(或您期望 arg 中的任何内容)。
  3. 如果字母数字是限制性的,请通过任何不包含 html/javascript/sql 语法字符(例如,'<'、'>'、';')的白名单。通常这些字符无论如何都不需要存在以进行调试。
于 2013-08-26T21:43:44.137 回答
1

我大致同意 SilverlightFox 的回答。在注入漏洞发生时担心它们(并确保它们不会发生)。

但是,机密性问题是一个真正的问题,但也有例外。在其他地方(除非我们有全局变量),我们正在处理单层接口上的交互。引入例外,我们有非本地问题。

例如:

  • SSN 是需要严格控制的典型数据示例。一些低级解析库可能会抛出带有字符串详细信息的异常。这可能会被抓住并塞进原木中。通用解析代码和日志代码都不知道 SSN,但它们最终引入了 SSN 漏洞。
  • 将异常消息放入网页的网站(有时在评论中 - 这无济于事!)会披露可能对攻击者有帮助的网站实施信息。网站不应该这样做,但他们会这样做。因此,您需要仔细考虑任何会引发异常并可能最终出现在 Web 应用程序中的代码。
  • 在进程、机器或操作系统之间传播的异常可能会携带机密信息。
  • 在有移动代码的地方,机密信息可能会下滑到特权较低的代码。文件路径是这里的明显候选者。

还值得注意的是,将可变数据添加到异常是一个坏主意,因为它需要深拷贝才能安全。遗憾的是 1.4 使Throwable自己“有用地”可变。

于 2013-08-29T14:10:39.233 回答
1

通常是安全的,但是如果代码在您控制的系统(例如 Web 服务器)上执行,您应该决定是否允许最终用户看到异常。在异常中的错误消息中显示内部信息是信息泄漏的一种形式,因为它可以揭示有关系统构建方式的信息,并且攻击者可以通过强制异常来探测漏洞。如果它是桌面应用程序,这可能不适用,因为无论如何这实际上都在用户控制之下,但是对于任何基于 Web 或 Internet 的内容都需要格外小心。

但是,您可以将逻辑添加到您的自定义错误处理程序页面,以仅显示源自 MyUserExceptionClass您的策略的异常的详细信息,以便仅在最终用户可以纠正错误时使用。在这种情况下,您可能只想显示消息本身而不输出任何堆栈跟踪或其他详细信息,在这种情况下,如果与最终用户相关,您的异常消息应该包含参数名称的详细信息。

为了解决 deadthreetimes 答案中的要点,这些不应该与异常抛出类或异常类本身有关。使用未经处理的数据的类应该针对输出的上下文对其进行处理。

例如

  1. 如果在 HTML 页面中输出,HTML 在输出点而不是在异常抛出点对异常消息进行编码。
  2. 错误记录类应该将未经处理的文本清理为正确的日志格式。如果有字符限制或者它是 CSV 格式的文件,那么这个类应该确保此时消息中的任何逗号和引号字符的格式正确。
  3. 如果写入数据库,则由数据访问层使用参数化查询将信息正确写入数据库。
于 2013-08-28T10:22:40.037 回答
0

您可以记录参数并在异常中包含子字符串。

对于您对安全性的关注,它取决于您的应用程序和基础设施的访问控制模型。

  1. 如果服务器不是所有人都可以访问的,那么日志记录是一个好主意,至少你可以看看是什么参数导致了异常。
  2. 如果安全性是一个更高的问题,我建议将异常详细信息与分析参数一起存储在数据库表中。
  3. 如果你想发疯,你可以加密你的数据库列。

无论如何,我认为人们想看看是什么论点导致了异常。

干杯!!

于 2013-08-26T21:38:03.390 回答