Static Analysis of Grails Applications with CodeNarc
Since we last visited Grails (and Grails.nV), the Grails project has updated to a new major version (3.x) that comes with a host of performance improvements, Gradle support, and security enhancements. With these changes, it is a good time to revisit the project.
For Grails applications, one topic that needs attention is the use of static analysis to identify common security vulnerabilities. If developers have access to effective automated tools that alert of security concerns during development, these problems can be fixed before the code is released. Furthermore, these tools reveal issues in large and well-established codebases by automating the code checks performed during code promotion. For example, tracing tainted variables or variables influenced by user-provided input shows the impact of unchecked user input through an application. Stored XSS or SQLi are simple to detect in a majority of cases.
There are currently only two static analysis tools that provide coverage for Groovy: IntelliJ IDEA’s built-in debugger and CodeNarc, an open-source static analysis tool. Since it is not reliant on a single development interface, this post will examine CodeNarc.
CodeNarc functions by running a series of static analysis rules on the relevant code to detect bugs, oversights, and other development errors that may affect the performance of the application. While CodeNarc’s main focus is on Groovy code, it contains a set of Grails rules for web applications. The rules identify various issues in Grails applications, including a rule for identifying some mass assignment vulnerabilities. In addition, CodeNarc also comes with a generic security ruleset focused on general Groovy security tips. It is worth enabling, but the results are not specific to Grails applications.
Image from http://codenarc.sourceforge.net/
For Grails.nV, an insecure-by-design Grails webapp, we were looking for ways to detect the vulnerabilities within the application using CodeNarc rules. Grails.nV was an obvious choice since it has several clear examples of vulnerabilities that should be easily identifiable through static analysis. It also has more complex examples, where variables need to be tracked through a controller action before they reached the vulnerable line of code.
One easy place to start is checking for Insecure Redirects ( OWASP 2013 #10). In Grails, redirects can be created by specifying a controller and action or by directly passing a URL. This snippet from Grails.nV shows how this can be insecure:
To detect this vulnerability, we could check for any instance of
params being passed as the URL argument. However, the user could have assigned
params.field to an intermediate variable earlier in the process flow and use that variable in the URL field instead. This is where tainted variables come into play. By tracking when user input is assigned to any of the
params fields, we can find any other variables that may also contain malicious input. Thankfully, Groovy provides Abstract Syntax Tree (“AST”) calls that make this an uncomplicated process:
Now, whenever a call to redirect is made, we can check to see if it matches any variables known to be tainted and flag it.
Running this CodeNarc rule against Grails.nV successfully identified an insecure redirect condition in the UserController. It also worked on other contrived test cases we threw at it. However, it’s not a complete solution for identifying all instances of the vulnerability. Stored values, like those in a database, are not viewed as tainted and will not be called out. If a redirect passes a URL stored within a database table that a user can access, CodeNarc will not identify the issue. In general, the only input methods checked are the request parameters; values in cookie fields or other places that are still user accessible are up for grabs.
Static analysis is a powerful tool in any developer’s toolkit. While this post only covers redirects in detail, the same concept can be adopted to other forms of injection. During our analysis of the CodeNarc ruleset, nVisium created additional rules for Mass Assignment cases and SQL/HQL injection in Grails. Both work in a similar fashion to the Insecure Redirect rule: user-inputted variables are traced through the code and flagged if they hit the relevant function. In addition, the GitHub repository contains a simplified rule for the usage of insecure hash functions (including MD5 and SHA-1).
All of the discussed rules are available for inclusion in your own CodeNarc setup from the following GitHub folder. If you use the Grails CodeNarc plugin, simply update the ruleSetFiles to include the TestRuleSet contained in the Grails.nV source:
codenarc.ruleSetFiles= [.., "file:test/codenarc/TestRuleSet.groovy"]
Afterwards, run CodeNarc and generate a report: