6.3. PMDAnyone who has ever performed a code review of C or C++ code is probably familiar with tools such as Flawfinder and RATS, which rely on pattern matching and have some understanding of the target code. Unfortunately, these tools have vulnerability databases geared primarily toward C and C++ and they are limited in scope.[1]
PMD is a static source code analysis tool for Java maintained by Tom Copeland at http://pmd.sourceforge.net. It performs a number of checks for poor coding practices, but it doesn't provide any rules for identifying common web application vulnerabilities. A detailed explanation of how PMD works is outside the scope of this chapter. Besides, Tom has already done a good job of it (see http://www.onjava.com/pub/a/onjava/2003/02/12/static_analysis.html). PMD's analysis engine converts each Java source file into a nodelike tree structure called an Abstract Syntax Tree (AST). Then rules can traverse or "visit" the AST using the Visitor pattern, looking for object patterns that represent problems in the code. The advantage of this technique over pattern-matching tools is that the source is broken into logical chunks or tokens, allowing for intelligent automated analysis of surrounding code. 6.3.1. PMD RulesetsPMD comes prepackaged with a number of rules, but this tool's real strength is the ease with which you can create custom rules. The prepackaged rulesets deal primarily with software quality issues and include the following categories:
The next section builds an example rule to identify code symptomatic of SQL injection vulnerabilities. Although the focus is PMD, the important point is that any static analysis tool that supports custom rule creation can be extended in a similar way. The tester can leverage the existing analysis engine and rules of a particular tool and simply extend the rule base to incorporate web application code signatures. Ideally, you can add to the rule base (i.e., symptom code database) any code that causes application security issues by describing it in the tool's rule definition syntax. A PMD ruleset is a XML file that consists of one or more rule elements. Each rule element consists of attributes and child elements, such as the following:
The Class attribute points to the implementation of the rule logic, which can be written as a Java class file or as an XPath expression. A discussion of xpath is outside the scopt of this chapter, but plenty of good xpath resources are available on the internet. The other elements and attributes are informational and can be included in the resulting report. The following example describes a ruleset looking for dynamic SQL: <?xml version="1.0"?> <ruleset name="Dynamic SQL Ruleset"> <desciption> This ruleset contains a collection of rules that find instances of potentially exploitable dynamic SQL. </description> <rule name="DynamicSqlSelectStmts" message="DYNAMIC SQL ''{0}'' DETECTED" class="net.sourceforge.pmd.security.web.DynSqlSelectStmts"> <description> Dynamic SQL or "string building" techniques that rely on unsanitized input are potentially vulnerable to SQL Injection. </description> <priority>1</priority> <example> <![CDATA[ ... int id = request.getParameter("id"); ... String sql = "select * from employees where employeeid = " + id; ... ]]> </example> </rule> <!-- MORE RULES --> </ruleset> We'll visit this example rule in more detail in the Section 6.4 later in this chapter. 6.3.2. Installing and Running PMDPMD runs on any Windows or *nix system with the following installed:
You can download PMD as either a binary or a source distribution at http://sourceforge.net/project/showfiles.php?group_id=56262. To install PMD from the command line: C:\>unzip -q pmd-src-x.y.zip C:\>cd pmd-x.y To test PMD from the command line: C:\pmd-x.y>cd etc C:\pmd-x.y\etc> pmd ..\mysourcefile.java html ..\rulesets\basic.xml > out.html You can also install PMD as a plug-in to many popular IDEs. Refer to the PMD SourceForge.net home page for a current list of supported IDEs. It's advantageous to run PMD within an IDE because the tester can immediately jump to vulnerable code, whereas from the command line PMD shows the line number and description of the offending code. |