SonarQube is “an open platform to manage code quality.” As security is certainly an aspect of code quality, we wrote a Sonar plugin to allow Sonar users to view ThreadFix security issues alongside results from other Sonar sensors.
While a Fortify plugin already exists allowing users to view Fortify results inside Sonar, the ThreadFix plugin allows users to view results from any scanner ThreadFix supports (about 30, currently.) ThreadFix can add value to the scanners already in use at an organization through this plugin.
Sonar focuses on static analysis and therefore displays results on a per-file basis. ThreadFix can also link dynamic results to files using HAM (part 1), thus providing functionality that dynamic scanner vendors couldn’t provide in a plugin without something like HAM. Pretty cool!
The ThreadFix Sonar plugin provides two methods of operation: server and local.
If you already have a ThreadFix server up and running, the ThreadFix Sonar plugin can integrate with it over the REST API and pull down existing results. They will display alongside normal Sonar results.
If you don’t already have a ThreadFix server up and running with all of your security results loaded up, the ThreadFix Sonar plugin can still help you out. By specifying local files or folders for inclusion, the ThreadFix plugin will start up a mini ThreadFix inside the Sonar analyzer and do everything real ThreadFix does: parse scan files, enhance results using HAM analysis of source code, and merge results together into a unified set.
By using the local version of the ThreadFix Sonar plugin, you can get the vulnerability tracking benefits of ThreadFix without running an actual ThreadFix server. However, you would lose out on several ThreadFix features: reports, SaaS vulnerability scanner integrations, Defect Tracker (Jira, HPQC, VersionOne) integrations, access controls, a robust REST API, etc.
We have a wiki page with details on setting up the ThreadFix Sonar plugin in both modes.
Hibernate Version Problems
Sonar has an interesting and flexible plugin system allowing developers to write new “Sensor” implementations. We used this system for the ThreadFix sensor.
Plugin Architecture Summary
The Sonar plugin uses Inversion of Control to give developers access to the Sonar API classes like FileSystem and Settings. Developers simply define a constructor with those arguments and Sonar will make them available.
Then in order to mark issues in files in Sonar, the API has methods to retrieve Sonar representations of files and also data structures to represent issues. It’s just a matter of retrieving the proper reference to the file and constructing the issue data type properly. More details available in the code on GitHub.
Hibernate and JPA
JPA, or Java Persistence Annotations, are a set of standard annotations that various persistence libraries, including Hibernate, can parse. ThreadFix uses some JPA 2 annotations, including @ElementCollection, @CollectionTable, and @MapKeyColumn. These are very useful because they allow you to skip defining extra classes to hold collections of simple values like String or Integer. For instance, we started storing email addresses for our 2.3 release, and we have email addresses stored as lists of strings in a few of our Hibernate classes. Rather than define a separate class EmailAddress, which would be a wrapper around String anyway, @ElementCollection and friends allow us to define the list directly as a List.
Sounds good, what’s the problem?
The Sonar plugin runner comes bundled with a version of Hibernate that doesn’t support @ElementCollection. I got a lot of errors like this one:
... 9 more Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'annotationSessionFactoryBean' defined in class com.denimgroup.threadfix.importer.util.SpringConfiguration: Invocation of init method failed; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.List, at table: ScheduledEmailReport, for columns: [org.hibernate.mapping.Column(emailAddresses)] ...
for code like this:
After trying a lot of things, I also found out that missing annotation classes at runtime are not a fatal error. Thanks Java! Jerk.
15:00:31.972 DEBUG - Failed to class-load type while reading annotation metadata. This is a non-fatal error, but certain annotation metadata may be unavailable. java.lang.ClassNotFoundException: javax.persistence.CollectionTable
The original use case for annotations was purely as metadata (I think,) but developers quickly found that the same system could be exploited for lots of other more interesting functionality by leveraging reflection. Hibernate and Spring annotation configuration, anyone?
Deprecated Version? Deprecated Annotation!
Anyway, Hibernate in version 3.2.2 had its own version of @ElementCollection, @CollectionOfElements. By adding those along with the proper JPA 2 annotations, we were able to use the advanced functionality in both the normal ThreadFix environment and the Sonar plugin environment. Now the code looks like this:
Note the line through the deprecated annotation. When we upgrade Hibernate in the future, this may stop working and we may have to do some fancy stuff to fool the Java compiler into being ok with the deprecated annotation. For now, this solution works.