How about a Security Layer?

I recently had a great discussion with Wendy Nather from the 451 Analyst Group. She had found one of my previous posts on using a service gateway to protect against the OWASP Top 10 and had some follow up questions. I wanted to share some of the discussion as well as her questions because it really got me thinking more about Enterprise application architecture and security.

Wendy posed a set of interesting questions to me that made me realize a few things: first off, I could have explained the context of Expressway a bit better (it’s really designed for securing Enterprise applications, not any application in general), and second, that it if we are going to take security decoupling seriously, we should think about defining a new Enterprise Application Layer for it. In this post I’ll argue that we can improve the security of Enterprise applications through the use of an additional layer. More specifically, we need to establish that such a layer is logically feasible, and second, that it is practical. Here at Intel we believe it is practical, and we have a product for that, but let’s focus on the first question:Is it logically feasible, and if so, how do we change our mindset to improve application security.

Let’s recap the basic argument:

1. Developers are still getting security wrong, as evidenced by the OWASP top ten. The new list for 2010 contains a rehash of the old 2007 list and though I’m no Nostradamus, I’ll bet the next list (2013?) will be about the same as the 2010 list. Also, OWASP threats apply more broadly - they really apply to any service based application and browser-based applications. Many of the threats aren’t unique to browsers only.

2. Even if developers get security right, or outsource it to a trusted API such as ESAPI (or pick your favorite security API), enterprise applications change rapidly enough that code audits and reviews will be required. Coded in security slows the pace of application changes. As a security architect, it’s hard to manage changing security policies once the policies are bound to your applications in code.

3. Based on #1 and #2, we should look to minimize coded in security and delegate it to its own layer where possible. This provides increased policy consistency, allows security architects to audit policies, and makes the system more resilient to changing requirements. It frees developers from learning about security. If we take a big step back, it’s really the idea of task specialization applied to Enterprise applications. In the same way that you don’t want your security architects writing a search algorithm, you don’t want developer’s managing X.509 certificate lifecyles or understanding the nuances of XSS validation.

Another point here is that for the types of technology we are talking about, they center on web-based technologies – either browsers or HTTP based services. By HTTP based services I am talking really about REST or SOAP. For both cases, we’re now at point where the security standards for the HTTP stack are mature enough to express nearly any security claim in the message or transport and similarly, enforce these claims with a dedicated layer. There is no pressing need to enforce strong authentication, access control, authorization, input validation in the application itself if it can be done outside.

Security as a Layer

One way to add security as a layer is to start with an existing model for Enterprise application architecture and see how to fit it in. One popular view of enterprise application architecture is described by Martin Fowler. In his book, “Patterns of Enterprise Architecture”, Martin Fowler identifies three layers of enterprise applications: The presentation layer, the domain layer, and the data layer. The presentation layer is for information display, provisioning services, handling browser requests, command line APIs and other interfaces that present themselves to a user. The domain layer contains the actual business logic or calculations done for the application had hand based on inputs and outputs. Finally, the data layer is a broad logical layer used to communicate with databases, messaging systems and transaction managers. It is interesting to note that in Fowler’s original book, he doesn’t say much about securing communications to external web services, though he mentions that external services have a similarity in this case to the presentation layer, but doesn’t describe the functionality there. It’s also important to note that he was writing in 2003, which was right before web services really took off.

In any event, I’ve included a picture of these layers as described by Fowler. Click the thumbnail below to expand it

Logical Layers of Enterprise Applications

Here you can see security as an orthogonal concept, shown on the side. The question marks indicate areas that weren't really addressed by the original model (as they didn't really exist like they do today). The purpose here is to show that security was (and currently is) thought of as something to be included at every step along the way – that is, irrevocably enlaced throughout the application. I argued in a previous post that this tight coupling leads to all sorts of problems and we would do better to decouple what we can.

Adding in security moves the box from vertical to horizontal and we can insert it in front of the presentation layer. This is shown in the following thumbnail:

Proposed Logical Layers of Enterprise Applications

Here I’ve added a security layer that handles the following application security functions:
1. Threat prevention- protecting against code injection threats, denial of service, input validation, bi-directional client protection
2. Trust Enablement – Including strong authentication, authorization, access control, data privacy, and controls (SLAs, metering)
3. The same layer can be applied in front of a cloud service or API. As we say, “for the cloud” and “in the cloud”.

Looks Neat, but does it work?

I get a lot of questions about how this security decoupling idea actually works in practice. To see how this works, first consider the following:

1. First, stop thinking about security the “old” way. Security is a layer now. This means that your presentation, domain and data source tiers will only be receiving good requests. Channels of communication from the security layer downwards are trusted (see next point). Think of the layering concept expressed in the TCP/IP stack, where each layer is knows just enough to communicate with the next.

2. Second, the security layer is a trusted layer. Layers below it have a trust relation with the security layer. This means that requests that emanate from the layer are sanitized and trusted – there are many technical ways to achieve this. The security layer could be on a trusted network in the Enterprise, so messages are trusted from this block of IP addresses. This is a very simple way to achieve trust. Other ways include mutually authenticated SSL connections, VPN connections, and trusted, signed assertions. There are endless ways to establish this trust relation. Once it’s setup, we can take advantage of it for the next layer down.

3. Third, consider that for incoming message requests that bear credentials, the security layer can make complex authentication and authorization decisions and couch these decisions in the form of an assertion for downstream layers. The security layer tells the downstream layers, in the form of assertions, which can be either implicit or explicit, what the lower layer should do. This also works "in reverse" which means the security layer can apply policies on outbound messages back to clients as well.

Here are four simple examples:

1. Threats: The security layer receives an HTTP message with a cross-site scripting attack appearing in encoded form in one of the HTTP query parameters. The security layer blocks this message from lower layers. No input validation is needed on the lower layers. Lower layers aren’t even aware that a request was made. Related to this, consider also a persistent XSS attack where we are protecting a script from reaching the client. Here the security layer can also enforce outbound script injection. That is, even if a script got in, let’s make sure it never gets back out to the client. The lower layers don’t need to know about this action – it’s all handled at the layer.

2. Authentication: The security layer receives a request with a username password in the HTTP Basic Authorization header, validates this identity against CA Siteminder for the given URI, retrieves a SM_SESSION from the Siteminder server and packages this session into the request, forwarding the request to the proper downstream application in the domain layer. Lower layers receive a trusted request from the security layer. No re-validation is necessary. The security layer can optionally include additional information about the identity authenticated in the request itself for use by downstream applications. No authentication code is needed by the domain layer – it just “gets” good messages from the security layer.

3. Authorization: The security layer receives a request with an identity (subject), targeted at some resource (could be a URI) and some action (HTTP method or XPath-specified SOAP or REST call), asks an entitlements manager (such as Oracle Entitlements Server or Axiomatics) if this action on the resource is allowed by this subject. If it is allowed, the layer allows the request through, optionally adding an assertion or transforming part of the request with more additional information about the subject (retrieved from a directory). The lower layer just processes the request. No authorization code is needed by the domain layer- again, it just “gets” good messages from the upper layer.

4. Data Protection / Encryption: The enterprise application wishes to initiate an outbound request to a cloud service, such as the Amazon SimpleDB. Parts of the message to be stored in this external service need to be encrypted to meet privacy or compliance requirements. The security layer receives the request from the Enterprise application (note the reversal of the data flow), looks at where it is going (A REST call targeted towards Amazon Web ServiceS), encrypts part of the request with a pre-provisioned encryption key and the request can be stored in the cloud. Notice that the lower layers did not need to manage keys, certificates or integrate OpenSSL, Microsoft’s CryptoAPI or any other complex security API. All of the key management and encryption happens at the security layer directly. No coded-in security is required.

These are just a few simple examples, but the pattern is the same. The security layer receives messages and acts as a policy enforcement point, forwarding “good” messages to the downstream layers or even enforcing security for outbound requests. In this model, the security layer is a trusted layer – no additional coded in security is needed.

Wendy’s Questions

I’ve pasted the questions from Wendy below - I thought they were all quite good and thought provoking.

1. What is the argument for an appliance (or gateway software instance) to solve these problems rather than a set of libraries (such as ESAPI)?

A: ESAPI is a great start on solving application security threats related to OWASP. The problem is, even with a great API like ESAPI, it still has to be integrated by a developer and doesn’t get elevated to the level of an auditable security policy for a security architect. I think it’s a step in the right direction but it doesn’t go far enough. What happens when the application changes? I feel you’ll still be hit with code changes and code audits at this point.

2. Since the gateway is about decoupling, how do you handle security decisions that need to be made in an application context?

A: Why would we assume the gateway or layer doesn’t have the necessary application context? In the language of SOAP and REST services, information such as the function/action, destination (URI), requestor and the full payload are all that’s required by the security layer to make the right decision. As long as the context is expressed in the message exchange, the security layer has what it needs.

3. Along the same lines, wouldn't it be a big performance hit to add context-aware encoding AFTER the application has already rendered the whole page?

A: There are two ways to think about this performance question. One, we at Intel believe we have specific technology tied to low cost commodity servers using general purpose CPUs that scales this problem efficiently. Put another way, if you use our software and hardware products, performance shouldn’t be a top concern. This contrasts other ways of solving the problem that involve custom hardware boards, chips or ASICs, which are expensive to scale. The second way to think about this is to re-phrase the question in terms of Enterprise Application architecture: We don’t object to a decoupled database, or decoupled presentation layer, so why should we be concerned about a decoupled security layer? One the security layer is tied directly to cheap general purpose servers, the application can scale quite easily in the same way any of the other layers would scale.

4. I can see static analysis tools screaming about application flaws that are "handled" in the gateway. How do you advise that enterprises handle that?

A: I feel that one aspect of the gateway (or layer) in this case is that policies should be as declarative as possible and managed by security architects. Sure, the security layer will have to undergo the necessary due-diligence, but you’re centralizing the effort rather in one place rather than splitting it up amongst many different applications throughout the Enterprise. Static analysis applies to “code” and audits apply to policies; I don’t really consider them the same.

5. Can you safely assume that whoever configures the gateway will be able to know where the data is ultimately headed, to avoid second-order injection attacks?

A: The security layer (or gateway to name a specific implementation) knows where each request is going – the policy is pre-provisioned ahead of time. Messages received by the security layer that can’t be identified or classified to a particular policy by the layer should be dropped immediately. This gives the security layer a “white list” type of configuration, also called deny-by-default by some.

6. With A-5, isn't the idea of adding nonces to the application the exact opposite of what you're trying to do with the gateway in the first place?

A. Yes and No. In the context of what I originally wrote, an additional nonce could be used by a web application to protect against a CSRF attack, and this would have to be verified by the application server, which means coded-in security. I do believe, however, that there is a way to do this with a security layer where the layer can verify the nonce or add an additional piece of data to the outgoing page which it checks on a subsequent request.

7. How is this supposed to work with external content delivery systems (such as Akamai)?

A: The security layer should be authenticating the requestor before the response reaches the client. In a system like Akamai, it’s the HTTP response that contains externalized links to the content delivery network. It’s really no different than how it works today, what we’re changing here is the architecture of the Enterprise application.

8. How is this supposed to work with cloud-hosted applications?

A: If we look at the new picture, the security layer can also live in the cloud itself and play the same role as it does in the “on-premise” application. That is, the layer can live on-premise in the Enterprise and enforce security policies out to cloud services. Or, an Enterprise can place their infrastructure off-premise and deploy a security layer in the cloud itself.

Further Thoughts and Objections

One way to argue that a layering approach to security won’t work as a general solution is to find some examples of specific security policies that can’t be expressed in a discrete layer, or that require a coded in approach. One potential objection concerns the need for a minimal amount of “bootstrap code” in the domain layer that is used to trust the security layer. That is, we may not be able to completely decouple every last line of security code, but can we think of others? Any other thoughts or comments on this would be appreciated in the comments.

Pour de plus amples informations sur les optimisations de compilation, consultez notre Avertissement concernant les optimisations.