Monthly Archives: July 2014

Secure Static Code Analysis with the Maven PMD Plugin

Similar to Checkstyle, PMD is a static code analysis tool that is targeted more toward improving code quality than explicitly scanning for security problems. PMD does promote certain aspects that have indirect effects on product security, which is why I usually recommend using it regularly during development.

Many security defects are introduced because code is overly complex or because developers do not deeply care about or understand the code that they are writing. Copy and pasting (e.g. from blogs, Stack Overflow, …) contributes to this effect. I have had the experience that with increasing code quality, the number of security defects decreases. This is not because a tool like PMD makes developers smarter, I think this is because a tool like PMD can help force developers to think about the code they are writing, and to spot obvious blunders that may later on lead to security issues.

 

PMD is applying “rules” on the code, with each “rule” describing desired (or: undesired) code structures. PMD comes with a huge set of rules, and choosing the best rules for a project is not always easy: some of the rules are controversial in the first place (they are conveniently placed in the “controversial” ruleset package), others may be contradicting. Users can create additional (custom) rules, and add them to the rule set as needed.

Security reviewers are generally very appreciate of code that is easy to follow. The “basic”, “code size”, “coupling”, and “design” rule sets are particularly helpful for creating easily readable code. This also has the nice benefit that such code is easy to maintain. No more “what did I want to achieve with this somewhat overly optimized block of code that has more double negotiations in it than the CEO’s last speech on salary increases” situations after coming back from vacation.

PMD is very good at discovering dead code, overly complicated expressions, and code that has a high formal complexity (e.g. NCSS, cyclomatic complexity, NPath complexity, field and parameter counts, etc) – all of which can eventually lead to security problems due to complexity-induced incorrect code usage. PMD helps developers to truly remove of this hand-optimized code, and leave that kind of work to the compiler. At the same time, PMD can also spot inefficient code, and help the developer to manually optimize where a human brain is actually smarter than the compiler.

In combination with Checkstyle, PMD can catch a lot of bad coding habits.

 

The available rules change frequently with new PMD releases. A current list (for the 5.1.1 release) is available here.

Edit: See the “build-tools” project in https://github.com/mbeiter/util for a starting point for creating a PMD ruleset definition. The rules configured in this project are the ones that I personally find generally useful. Keep in mind that this really is only a starting point, as each project may have individual needs for an optimal rule set depending on the data it is processing, how it is operated, etc pp.

Configure Checkstyle in Multi-Module Maven Builds

Properly configuring Checkstyle is a good first step, and encapsulating the Checkstyle rules into a resusable configuration resource jar file really helps setting up centralized rules control and auditing in enterprise build environments. The next step is to automate Checkstyle execution in both developer builds and in the CI/CD environment.

There is a plugin available for Maven that allows executing Checkstyle as part of every build. The plugin can be configured to either fail or not fail the build if rule violations have been discovered. In combination with Maven’s profiles, this allows configuring Checkstyle to create a report of violations in local developer builds, and fail the build in case of rule violations when the artifact is built on a centralized continuous integration build system.

The configuration below sets up the developer build as the “default build”, which allows a developer to execute the Checkstyle checks with the “mvn clean install” they use on their local system. This developer build is configured not failing the build. It also uses the Checkstyle configuration resource file. Note that some of the configuration settings (e.g. the versions of the artifacts) are parameterized, but the configuration works the same way when no parameters, but hardcoded values, are being used.

In the example below, the “dependency” section pulls in the configuration artifact, and the “configLocation” parameter points to the Checkstyle rules configuration in the resource configuration artifact. This filename must match the actual rules filename used in the dependency.

<build>
  ...
  <plugins>
    ...
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-checkstyle-plugin</artifactId>
      <version>${mavenCheckstylePluginVersion}</version>
      <dependencies>
        <dependency>
          <groupId>${buildToolsGroupId}</groupId>
          <artifactId>${buildToolsArtifactId}</artifactId>
          <version>${buildToolsVersion}</version>
        </dependency>
      </dependencies>
      <executions>
        <execution>
          <phase>validate</phase>
          <configuration>
            <configLocation>checkstyle.xml</configLocation>
            <encoding>${project.build.sourceEncoding}</encoding>
            <consoleOutput>true</consoleOutput>
            <failOnViolation>false</failOnViolation>
            <failsOnError>false</failsOnError>
          </configuration>
          <goals>
            <goal>check</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    ...
  </plugins>
  ...
</build>

The CI/CD build uses a very similar plugin configuration in a profile, with the difference that the build is configured to fail in case of a rules violation:

<profiles>
  ...
  <profile>
    <id>release</id>
    ...
    <build>
      <plugins>
        ...
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-checkstyle-plugin</artifactId>
            <version>${mavenCheckstylePluginVersion}</version>
            <dependencies>
              <dependency>
                <groupId>${buildToolsGroupId}</groupId>
                <artifactId>${buildToolsArtifactId}</artifactId>
                <version>${buildToolsVersion}</version>
              </dependency>
            </dependencies>
            <executions>
              <execution>
                <phase>validate</phase>
                <configuration>
                  <configLocation>checkstyle.xml</configLocation>
                  <encoding>${project.build.sourceEncoding}</encoding>
                  <consoleOutput>true</consoleOutput>
                  <failOnViolation>true</failOnViolation>
                  <failsOnError>true</failsOnError>
                </configuration>
                <goals>
                  <goal>check</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          ...
        </plugins>
        ...
      </build>
    ...
    </profile>
  ...
</profiles>

Maven optionally provides the functionality to create nice graphical reports by invoking “mvn site”. The Maven Checkstyle plugin can be configured to turn the results discovered in the anlysis phase into an html report that is automatically included in the project’s site report. To enable this functionality, the Checkstyle plugin is additionally added to the “reporting” section in the POM file:

<reporting>
  ...
  <plugins>
    ...
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-checkstyle-plugin</artifactId>
      <version>${mavenCheckstylePluginVersion}</version>
      <configuration>
        <configLocation>checkstyle.xml</configLocation>
        <encoding>${project.build.sourceEncoding}</encoding>
      </configuration>
      <reportSets>
        <reportSet>
          <reports>
            <report>checkstyle</report>
          </reports>
        </reportSet>
      </reportSets>
    </plugin>
    ...
  </plugins>
  ...
</reporting>

Note that the plugin configuration in the “reporting” section does not have a reference to the Checkstyle configuration resource file. The way that reporting plugins often work in Maven is that they take analysis results that are already present in the “target” directory of an artifact, and then transform them into a graphical representation. The Checkstyle plugin is no exception to this rule.

Note that this plugin needs the JXR plugin to be executed beforehand if it should provide cross-references to the source code in its reports.

Edit:See https://github.com/mbeiter/util for an example on how to configure the Maven Checkstyle Plugin as described in this post for a multi-module build.