A Second Helping of PIE
In a previous post I introduced PIE, with particular emphasis on how it can be used with the Java Security Manager to build a security policy and protect applications against known and unknown vulnerabilities. In this post, I'm going to elaborate on additional features of PIE such as using PIE with different modules (e.g. CSP and Spring Security), using the PIE Maven plugin to verify and update your security policies as part of the software development lifecycle (SDLC), how you can use PIE to increase your test coverage of security-sensitive parts of your application, and how PIE can be used as an intrusion detection system (IDS).
The Many Flavors of PIE
If you take a look at the PIE group in Maven, you'll notice that there are several JARs available. This represents PIE's modular design as a framework for building and enforcing security policies. The core JAR is responsible for hooking into your container's Servlet 3.0 autoscanning (or hooking into your application another way, such as with the PieBundle for Dropwizard) and driving the policy simplification engine. However, if you included just this JAR with your application it wouldn't do anything; it needs a Policy implementation to work.
At the time of writing, PIE has two implementations out of the box: one for the Java Security Manager, and one for CSP. Each has its own Maven module so that you can include just those implementations you want to use. So if you're interested in using PIE's CSP module to protect your application against XSS attacks, just include its JAR in your container's lib directory!
To dig a bit deeper on the how PIE modules work, each PIE module is responsible for implementing 3 things:
- A PolicyEnforcer which is given a callback with the ServletContext as a parameter. The module can then use the ServletContext to inject itself into the web application in whichever way is appropriate. The intent is for the injected behavior to delegate decisions to the policy returned by the enforcer's getPolicy() method.
- A Policy, which translates between the application's concrete context and the abstract policy definition used by PIE. It achieves this by defining what class to use for its root FactMetaData implementation.
- A tree of FactMetaData implementations, which define the concrete logic of what "facts" are in the context of the security policy (such as the filename being accessed, hostname being resolved, authenticated user's permission group, etc.), how to simplify policies applied to that fact, and how to apply matching according to that fact's language (for example, matching files with "/var/lib/**" requires some different logic that matching hostnames with "*.example.com").
If you're looking to extend PIE with your own module, both CSP (pie-csp) and the Java Security Manager (pie-sm) modules of PIE work as examples. There's also an example of a more application-specific PIE module which uses Spring Security to apply method-level policy decisions about what user roles may invoke a given protected method.
Baking PIE Into Your SDLC
If you're looking at PIE's group in Maven, you'll also notice that there's a Maven plugin for PIE. This plugin allows you to rebuild your policies as part of your build lifecycle using observed policy violations from a running application instance. The summary of this workflow is:
- Launch a development or QA instance of your application, leaving PIE in report-only mode.
- Run your usual end-to-end tests on the latest version of your application.
- The plugin retrieves all the policy violations from the application and updates the local version of your security policy. Optionally, the presence of any observed violations can then trigger the build to fail.
By updating the application's security policy during the development and QA process, you can easily bring these groups into the workflow of defining the security requirements of the application. The plugin empowers these groups to make local updates to the security policy, see what needs to be changed and why, and even keep that policy in source control (which makes it easy to track and audit those changes). By making the build fail when there are violations, you can also gain confidence in the correctness of the security policy before pushing it into the production part of your development lifecycle.
Bring PIE Home
If PIE has made your mouth water but you're not quite ready to commit to enforcing policies in production, there are still lots of ways you could use PIE in your environment in order to gain security insights into your application.
Improving Security Test Coverage
One use-case for PIE is as a tool for deciding how well your tests are exercising security-sensitive parts of your application. Consider the following workflow:
- Generate a security policy using PIE based entirely on the observations seen during automated or security testing.
- Deploy this security policy in a production environment, but leaving PIE in report-only mode.
- Look at the security violations reported by PIE as they occur in your production deployment. Any violations most likely indicate execution of security-sensitive code that wasn't exercised during testing (as opposed to an actual case of your application being exploited).
By looking at these violations, you can decide what parts of the application should be a priority for additional testing. Once new tests are written, you can repeat this cycle and over time gain confidence that there aren't any blind spots in the application that you're failing to test.
PIE for Intrusion Detection
In a similar vein, you can use PIE to as a form of intrusion detection without having PIE effect the functionality of your production application. By leaving PIE in report-only mode, you can watch the log of violations and triage those reports as they come in. In the case that behavior is expected, you can go back and update your policy to reduce the false-positive rate (which depending on how well your application was exercised during policy generation, may begin fairly high). However, any true positives represent a case of a user achieving unintended behavior, offering you critical insight into your application.
How PIE is best used and how effective it can be is something that is still to be defined by its users. One of our goals with PIE is to encourage the community to explore this space of runtime security tools and see where they can provide layers of defense and insight for your applications. By being free and open source, we hope you'll find ways that PIE can be better; pull requests are welcome!