This page describes the design ideas that drove the development of AppSensor version 2.
In version 1 the only language option was to use Java. This was primarily due to the ease of developing for a single language, particularly with the integration of various components necessary to perform all the steps in AppSensor. In addition, the Java-only requirement was related to the embedded and ESAPI issues (see below).
In version 1 the only runtime execution mode was embedded (called "local" in version 2). Embedded mode made sense at the time. We were building a framework to work inside applications, so it would be a library embedded inside an application. Since we also were an extension to ESAPI (below) and had a Java-only requirement (above), it made sense to continue to run in embedded only mode and sacrifice the flexibility of deployment models for simplicity of the framework.
In version 1 AppSensor started as a drop-in replacement for the ESAPI (v1/v2) intrusion detector. It was a viable replacement and added new features. While it wasn't a hard requirement that AppSensor work the same way the ESAPI intrusion detector worked, it made sense and kept things simple.
In version 1 AppSensor was essentially a plug-in for another framework (ESAPI v1/v2). From that perspective, it was not crucial that the framework be particularly extensible. There were mechanisms for dropping in replacement storage providers, but that's about it. At the time, the simple design made sense and was sufficient.
One of the primary design goals for v2 was that any application should be able to interact with AppSensor. To do that, there was a need to support any (ok, almost any) language. There are multiple ways to go about that, but given the current tools and technology landscape, the most common solution is to build an API and allow any language to talk to AppSensor "as a service".
In order to provide wide language support, a model is needed that separates detection of events and execution of responses (client application) from the core AppSensor system (analysis engine) which performs analysis and detection of attacks, and determination of the appropriate response.
In addition to language support, there was also a need for correlation across servers (load balanced) and even applications (different applications sharing the same user base). There was also the recognition that the typical load on an AppSensor system is pretty small given that suspicious events are not "normal" for an application and generally represent a small subset of the requests, particularly in authenticated portions of a website, which is where AppSensor is often used.
For these primary reasons, AppSensor v2 has been re-architected to function as a client-server style system:
There are a number of different implementations available for execution "modes". Some examples are:
While it's still possible to integrate AppSensor with ESAPI, it's no longer a requirement. AppSensor is a fully standalone framework. You can also integrate AppSensor with other security frameworks as well. When ESAPI 3 is completed to a reasonable degree, we'll build an integration adapter to allow you to use AppSensor as the intrusion detection component for ESAPI.
The v2 implementation has made a significant amount of the internal structure pluggable. This means you can swap out implementations much easier for the different components of the system, up to and including the actual analysis engine. Some of the components that are swappable include:
While many of the implementations are pluggable, the core of the system is not. The core of the system is essentially the data model (events, attacks, responses, etc.) and the interfaces for the different pluggable components. The AppSensor core will select the implementation that you plug in and use it as long as it complies with the contract in the interface.
There was a very limited dependency injection (DI) feature in v1 based on ESAPI's DI mechanism. In essence, you would explicitly specify the class you wanted to use in a properties file and that would get constructed and used. There were some limitations, and it was not as nice as the DI mechanism in many popular libraries used today.
To that end, we decided to use the JSR-330 DI spec, with a default implementation provided by Spring. This is a fairly standard configuration for Java applications today, and serves our needs fairly well.
In order to use the DI feature, it's actually simpler since dependencies are auto-injected, so as long as the implementation is on the classpath. In order to do this, you essentially are configuring the DI setup when you setup your dependency management configuration (maven, gradle, etc.) By specifying only the implementations you want, your system will be ready to use those implementations. Changing your system is generally as easy as changing a dependency (excluding obvious additional configuration such as DB credentials, or filesystem paths, etc.)
In version 2, we decided to take the trade-off to make the developer (you) implement authentication, but this adds the flexibility that it can be anything you want (can do basic auth, client cert auth, even roll your own token system), whereas we would have likely supported a small number of options. By leveraging existing web server authentication mechanisms, we feel this trade-off lets us rely on existing systems for authentication and focus our efforts on attack detection and response.
For those interested, we have posted sample instructions for configuring a web server (apache2 in this case) as a reverse proxy for appsensor using HTTP Basic authentication for client applications, which then converts that to the appsensor authentication request header. The notes are posted here.
While the pluggability of the system is a desirable feature, users can have issues when trying to setup dependencies. You are building a system out of different pieces, and if you forget a piece, the system won't start properly. Fortunately there are some simple mitigations we can put in place to solve many of these issues (good error handling with clear messages, getting started guidance, etc.)
For those using ESAPI, v1 had the nice feature that it was built to be drop-in ready. For v2, that's not the case. However, the configuration should be minimal once the adapter is built for ESAPI version 3.