Reputation: 4400
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?
java -ea -jar "MyJar.jar"
Upvotes: 0
Views: 166
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
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