Nicholas Miller
Nicholas Miller

Reputation: 4400

Are Assertions Insecure in Java?

In C#, assertions can be stripped out by the compiler by switching from debug mode to release mode. From a security (and UX) standpoint, this is a good thing in order to avoid exposing a stacktrace to the end-user, as a stacktrace may lower user-confidence in the stability of the app, and a stacktrace could expose vulnerabilities which can be exploited. Further, a stacktrace could give some information that can help hackers reverse-engineer the software.

After looking at Java assertions, it appears that no such capability exists. That is, assertions remain in the compiled bytecode, and there are no command-line options to the Java compiler to strip them away. Rather, we see that the Java runtime permits the enabling of assertions, something which could be done by a malicious user attempting to glean stacktrace information. Also, I've even seen some encourage the idea that assertions should fail dramatically to spit out an AssertionError and a stacktrace. Or simply, people are neglecting to talk about the security aspects of letting an application fail like this.

My initial assessment is that the assertions in Java pose a security risk, even if they provide advantages for debugging or maintenance.

Should we stay away from using assertions in Java for security-critical applications; or if there is a proper, and secure, way include assertions, how should it be done?


Edit for Clarity: I'm assuming here that the Java application is being deployed to the end-user as a desktop application. That is, the user downloads/installs the application. That being said, it is my understanding that the user is able to run an executable jar while enabling assertions with something to the effect of:

java -ea -jar "MyJar.jar"

Upvotes: 0

Views: 166

Answers (2)

Kayaman
Kayaman

Reputation: 73558

Assertions don't make Java programs any less secure than they already are. Not that it would be a "feature" of Java, as any program written in any language running on your computer is insecure, unless you can take advantage of something like TPM (and even then it's not completely secure, unless you believe the marketing people).

You're not obligated to show the stacktrace to a user, but that has very little to do with security. Writing it to a log is a lot cleaner. You're not obligated to use assertions either, I think it might be less common in the Java ecosystem compared to for example C#.


The stacktrace itself provides very little useful information in a desktop environment¹, as you already have full access to the code anyway. There are dozens of easier ways to glean information than try trickery with assertions. For one you could just decompile the classes. Now you might think "I'll obfuscate it, at least it will make it a bit harder", but that's the equivalent of saying "I'll build a very low fence, at least it will keep babies away". It's not better than nothing, it is nothing, but it can make you think you have some level of protection and that's a security risk.

Either you have information that needs to be secure and you have to use effective methods, or you have information that isn't important and you don't need to secure it. The scale is binary in that way although the secure end has different flavours and requirements, usually with fancy government names.

¹ In a web environment showing the stacktrace to a user may be a security risk, as it can show information about libraries being used and provide an attack vector through library bugs. That's why you don't see stacktraces in production, unless someone screwed up really bad.

Upvotes: 1

Mark Maurice Williams
Mark Maurice Williams

Reputation: 217

Rather, we see that the Java runtime permits the enabling of assertions, something which could be done by a malicious user attempting to glean stacktrace information.

If a user is able to enable assertions in the JVM running the application whose security is in question, they already have a level of access that allows them to achieve even more consequential exploits.

It is true that exposing stack traces to an end user can have security implications, but whether stack traces are exposed or not in this way is something the application designers have control over.

Should we stay away from using assertions in Java for security-critical applications; or if there is a proper, and secure, way include assertions, how should it be done?

I think one good argument for avoiding the use of assertions for security reasons is that the programmer may accidentally use an assertion condition having side effects. If the program is developed and tested with assertions enabled, but released in an environment where they are not, the behavior of the program will be different. This might introduce bugs that could pose security vulnerabilities.

Upvotes: 1

Related Questions