【问题标题】:Are Assertions Insecure in Java?Java中的断言不安全吗?
【发布时间】:2018-07-03 20:11:12
【问题描述】:

在 C# 中,编译器可以通过从调试模式切换到发布模式来去除断言。从安全(和用户体验)的角度来看,这是一件好事,可以避免将堆栈跟踪暴露给最终用户as a stacktrace may lower user-confidence in the stability of the app, and a stacktrace could expose vulnerabilities which can be exploited。此外,堆栈跟踪可以提供一些信息,帮助黑客对软件进行逆向工程。

查看Java 断言后,似乎不存在这样的能力。也就是说,断言保留在编译后的字节码中,Java 编译器没有命令行选项可以将其删除。相反,我们看到了Java runtime permits the enabling of assertions,恶意用户可能会尝试收集堆栈跟踪信息。此外,我什至看到一些encourage the idea that assertions should fail dramatically 吐出AssertionError 和堆栈跟踪。或者简单地说,人们忽略了让应用程序像这样失败的安全方面。

我的初步评估是Java 中的断言会带来安全风险,即使它们有利于调试或维护。

我们是否应该避免在 Java 中为安全关键型应用程序使用断言?或者如果有一个适当且安全的方式包含断言,应该怎么做?


为清晰而编辑: 我在这里假设 Java 应用程序作为桌面应用程序部署给最终用户。即,用户下载/安装应用程序。话虽如此,据我了解,用户能够运行可执行 jar,同时启用具有以下效果的断言:
java -ea -jar "MyJar.jar"

【问题讨论】:

  • AssertionError 可以(并且应该)优雅地处理,并且不允许传播给用户。您的链接答案对于一般代码仍然有效,但仍应有全局错误处理程序来确保正确记录错误。

标签: java security desktop-application stack-trace assert


【解决方案1】:

断言不会降低 Java 程序的安全性。并不是说它是 Java 的一个“特性”,因为在你的计算机上运行的任何用任何语言编写的程序都是不安全的,除非你可以利用 TPM 之类的东西(即使那样它也不是完全安全的,除非你相信营销人员)。

您没有义务向用户显示堆栈跟踪,但这与安全性关系不大。将其写入日志要干净得多。您也没有义务使用断言,我认为与例如 C# 相比,它在 Java 生态系统中可能不太常见。


stacktrace 本身在桌面环境中提供的有用信息非常少¹,因为无论如何您已经可以完全访问代码。有几十种比尝试使用断言更容易收集信息的方法。一方面,您可以反编译这些类。现在你可能会想“我会混淆它,至少它会让它变得更难一点”,但这相当于说“我会建造一个非常低的围栏,至少它会让婴儿远离”。它不比没有好,它什么都没有,但它可以让你认为你有一定程度的保护,这是一个安全风险。

要么您拥有需要保护的信息并且您必须使用有效的方法,要么您拥有不重要的信息并且您不需要保护它。虽然安全端有不同的风格和要求,但规模是二进制的,通常是fancy government names

¹ 在向用户显示堆栈跟踪的 Web 环境中可能存在安全风险,因为它可以显示有关正在使用的库的信息并通过库错误提供攻击向量。这就是为什么你在生产中看不到堆栈跟踪,除非有人搞砸了。

【讨论】:

    【解决方案2】:

    相反,我们看到 Java 运行时允许启用断言,这可能由试图收集堆栈跟踪信息的恶意用户完成。

    如果用户能够在运行其安全性存在问题的应用程序的 JVM 中启用断言,则他们已经拥有一定的访问权限,允许他们实现更严重的攻击。

    确实,将堆栈跟踪暴露给最终用户可能会产生安全隐患,但堆栈跟踪是否以这种方式公开是应用程序设计人员可以控制的。

    我们是否应该避免在 Java 中为安全关键型应用程序使用断言?或者如果有一个适当且安全的方式包含断言,应该怎么做?

    我认为出于安全原因避免使用断言的一个很好的论点是程序员可能会不小心使用具有副作用的断言条件。如果程序是在启用断言的情况下开发和测试的,但在未启用断言的环境中发布,则程序的行为将有所不同。这可能会引入可能造成安全漏洞的错误。

    【讨论】:

    • 如果恶意用户知道如何启用断言,他就会知道许多更简单的方法来从程序中获取信息。启用断言将是获取不相关信息的一种极其低效的方法。
    • @Kayaman 我的 OP 假设这是用于桌面应用程序(现已编辑)。鉴于代码被混淆了,在哪些方面进行逆向工程会更有效?
    • @NickMiller 当然是用于桌面应用程序,你将如何在 Web 应用程序上启用断言?混淆不是真正的安全机制,它是最基本的安全形式,仅能阻止最无能的攻击者。您高估了断言的安全风险,而忽略了所有其他更现实的安全风险。
    • @Kayaman 我同意混淆不是真正安全的。不过,我是从将攻击减慢到不可行的角度来看待这个问题的。由于攻击者已经可以看到混淆的源,因此提供堆栈跟踪对攻击者几乎没有好处,这是真的吗?
    • @NickMiller 要么您处于不需要混淆的情况,因为没有什么值得窃取的,要么您处于不会阻碍攻击者的情况。混淆并不是“聊胜于无”,它实际上更糟,因为它会给人一种虚假的安全感。不过,对于没有经验(安全方面)的人来说,混淆的概念给他们留下了深刻的印象是很常见的,所以这对我来说并不是一个新观点。但是,如果您可以访问计算机上运行的程序,那么您有很多工具可以获取比堆栈跟踪更有用的信息。混淆与否。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-03
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-23
    相关资源
    最近更新 更多