Best Practices for Securing Your SOA: A Holistic Approach

Service-Oriented Architectures offer a number of potential benefits: They can provide new opportunities to connect enterprises with customers, partners, and suppliers; improve efficiency through greater reuse of services across the enterprise; and offer greater flexibility by breaking down IT silos. But these benefits make security more critical than ever. Why? Services are highly distributed, multi-owner, deployed to heterogeneous platforms, and often accessible across departments and enterprises - and this creates major security issues for developers, architects, and security and operations professionals. Fortunately, there are ways to make your SOA more secure. If you're building applications to SOA using J2EE, BPEL, or XML, you can build security into an SOA by addressing security throughout the entire application lifecycle - not just at deployment time.

We'll examine the types of attacks applications are vulnerable to, and then outline a holistic approach to protecting applications and services that encourages secure coding practices and the use of Web Services security infrastructure. You'll learn how to protect services from the outside (with infrastructure) and inside (through static analysis of your code). Finally, you'll see how all the pieces come together as we work through an example of an auto loan application.

Typical Attacks
What types of attacks do you need to be aware of when you're building applications to SOA using Web Services? As it turns out, the key aspects that make your SOA more successful - the ability for developers across your departments and trading partners to be able to find applications exposed as services, and the way that WSDL documents define operations that can be invoked - may also make it appealing to hackers.

Here are some potential vulnerabilities:

You'll recognize many of these items, as they equally apply to both Web Services and Web applications.

A Holistic Approach To Protecting Services
To protect against these potential vulnerabilities, you should take a holistic approach to security that includes infrastructures, tools, and software development practices:

Let's look at all of these except monitoring (since the latter is more operationally focused).

Protecting Services from the Outside
Most Web Services are based on the same technology as the Web, namely HTTP. As a result, all common technologies used to secure the Web, such as Web authentication and SSL, work equally well with Web Services - for point-to-point security. With SSL alone, you can do authentication (the communication is established between two trusted parties); confidentiality (the data exchanged is encrypted); and, message integrity (the data is checked for possible corruption). However, solutions such as SSL are a little heavy-handed since they secure the entire channel. Furthermore, for many message-based interactions, intermediary steps are required before the messages arrive at their target endpoint. This leaves XML messages unsecured at each intermediary checkpoint - exposed to tampering, information disclosure, and message altering.

To get a finer level of control and avoid intermediary security issues, it's best to secure the message rather than the complete transport. The idea is to replace SSL capabilities with message-level security, where the security information is carried in the message itself. This way, unless the intermediary or endpoints have the correct security infrastructure in place and are trusted, the message will remain secure and unreadable and can be forwarded to the next endpoint.

So how do you secure the message rather than the transport? WS-Security defines a mechanism for adding three levels of security to SOAP messages:

  1. Authentication tokens. WS-Security authentication tokens let the client provide a user name and password or X509 certificate for the purpose of authentication headers.
  2. XML encryption. WS-Security's use of W3C's XML encryption standard enables the XML body or portion of it to be encrypted to ensure message confidentiality.
  3. XML digital signatures. WS-Security's use of W3C's XML digital signatures lets the message be digitally signed to ensure message integrity. The signature is based on the content of the message itself (by applying the hash function and public key), so if the message is altered en route, the signature becomes invalid.
A final thought on this - don't forget that you can use transport and message-level security together, e.g., use a WS-Security Username token without encryption and use SSL to encrypt the transaction.

There are two ways to implement this: You can embed the logic for processing tokens, handling encryption, and applying hash functions and digital signatures in the service implementation itself, or you can use a WSM solution. The first option is shown in Figure 1.

WSM solutions intercept incoming and outgoing service communications and apply a set of policies in a pipeline fashion, including authentication, authorization, decryption, signature validation, and XML schema validation. They move the active enforcement of the policies and agreements to the boundaries of an application, letting the application developer concentrate on the business logic. These solutions typically provide a policy management tool for building new security and operations policies, storing policies, and managing distribution and updates to runtime policy enforcement points. In this way, policies are defined and changed centrally but enforced locally. If you have to authenticate to an Identity Management System that's not supported by the WSM solution out-of-the box, such as a JAAS login module, Oracle Web Services Manager, as well as many WSM products, provides an SDK for developing policy steps. They provide operational dashboards for monitoring policies as they execute to ensure service levels, incorporating alerts so corrective actions can be taken in a timely fashion.

WSM solutions typically provide two types of enforcement components and policy enforcement points: Gateway and Agents. Gateways are deployed in front of a group of applications or services. They can intercept inbound requests to these applications to enforce policy steps, adding application security and other operation rules to applications that are already deployed. They also allow (or deny) inside users access to predetermined outside services. Agents provide an additional fine-grained level of security by plugging directly into an application or service.

Service virtualization is also a key capability. Typically an Internet user makes a service request using a username and password combination, but the service may be expecting a SAML assertion. With a WSM solution, you can have a gateway on the requester side that intercepts the request, authenticates the user with the username/ password combination, and inserts a SAML assertion that can be validated at the service by a WSM agent. In effect, the user calls a service in a virtual way through the credentials that he knows, not the credentials that the Web Service is expecting.

Figure 2 shows the context in which a WSM solution can be deployed. Note that you could deploy an XML firewall or appliance before the gateway. These appliances are typically good at applying macro policies and protecting against attacks such as buffer overflow attacks, which don't require application context.

Securing Services from the Inside
Securing applications from the outside isn't enough to protect your application. Web Services gateway solutions, whether implemented in an appliance or software, can't confidently check the content of XML messages since they don't have the application context. Hackers use this knowledge to embed malicious content in the XML documents that pass straight through the WSM software to the service interface of the application.


Common Hacking Techniques
Hackers use common techniques such as SQL injection, stack and heap buffer overflows, command injection, and cross-site scripting to find pathways into applications. Their intention is to have the software return information that it wasn't designed to give, letting them access sensitive data they're not authorized to see or cause a denial of service by crashing applications. These techniques work on any type of software - it's a Web-based application or a Web Service with any kind of attack surface exposed.

XML Injection
Two of the more common hacking techniques with Web Services are XML and XPath injections, where a hacker manipulates or injects malicious input into an XML document or an XPath query.

In SQL injection attacks, a hacker injects malicious input (SQL statements) disguised as data into an application via an XML document or Web form, hoping that the input will end up in a WHERE clause of a SQL query that's executed against a backend database. The intention is to gain access to data that the hacker isn't authorized to see. You can easily address this by checking the data in the XML document for SQL statements.

XPath Exploits
XPath exploits are much like SQL injection attacks. In this case a hacker injects malicious input into an XML document, hoping that it will go through a dynamically created XPath query against an XML document in a native XML database and retrieve data that the developer didn't intend for it to retrieve. A typical malicious input for XPath exploits is OR 1=1 OR "=. This expression, when executed in the content of an XML document, will always return true and end up returning some data along the way!

Let's use a computer element in an XML document as an example:

<computer>
     <manufacturer>Toshiba</manufacturer>
     <name>T200</name>
     <ram>1GB</ram>
     <cpu>1.83MHz</cpu>
     <monitor>14.2</monitor>
</computer>

Here are some Xpath expression examples that could be issued against this element:

"/computer" returns the root computer element
"//computer" returns all computer elements in the document
"computer//ram" returns all RAMs under computer element

Now, here's how an XPath injection attack would work:

//computer[name = 'T200' and ram = '1GB'] will return the computer with this name and ram.

Here's the same expression with an XPath exploit:

//computer[name= 'T200' or 1=1 or '' = '' and ram = '1GB'] will return all of the computers.

Imagine replacing this scenario with one in which we have HR records that embed Social Security numbers!

Command Injection and Cross-Site Scripting
Command injection exploits occur when a hacker embeds an XML document with a script, such as a shell script, in hopes that the script will be executed.

With cross-site scripting, a hacker also embeds a script into an XML document - but this time, he hopes the script will be stored (for example, in a database) and then served to someone's Web browser as part of a subsequent Web interaction. The script is executed in the browser of the unknowing user and can do things such as steal usernames and passwords. In both of these examples, the hacker ends up "smuggling" some code through the firewall, Web Service Gateway, and XML appliance (if deployed), and relies on it being run at a later date - on either the server or client side.

Solution
The way to secure applications from inside and protect against the type of attacks we've discussed is to do input cleansing in the application code. You can use your development skills to do this, but there's help at hand.

Static analysis tools are evolving to provide an automated way to check large amounts of code and data flows to find common software security vulnerabilities related to malicious input during the software development phase. They can help you easily catch and fix common mistakes such as those mentioned above. Using proper threat analysis and abuse-case modeling during the software requirements and design phases to identify security flaws architecturally can also mitigate potential security risks during deployment - as well as in the future.

Simulating Known Attack Patterns
Another good technique to deploy in combination with those mentioned above is dynamic software analysis. This step could easily fit into the quality assurance and testing phase of the software development lifecycle.

Much like static analysis, which analyzes source code statically, dynamic or runtime analysis analyzes software at runtime. The dynamic analyzer simulates attacks against the application and tries to exploit it. When it succeeds, it gives the result and identifies which areas of the application are vulnerable to the simulated attacks.

Dynamic analysis tools target a different class of exploits that static analysis tools can't catch since they are runtime attacks. Examples of these attacks include probing, forceful browsing, and time-based attacks such as click fraud. In the latter case, the number of times a page is hit in a given amount of time is of interest. This metric can't be extracted during static analysis. In fact, you must add checks in your code to detect them or use a solution that discovers such behavior at runtime.

Ideally you should use both dynamic and static analysis tools. Aside from increased security, this lets you pinpoint the root cause of the vulnerabilities caught during dynamic analysis and correlate them back to the exact sector in the code that's vulnerable.

Case Study: Auto Loan Application Processing
Let's take the example of a loan procurement application implemented by a loan broker named AutoLoan that offers its application as a Web Service invoked from a portal or directly by any of its trading partners. The loan application process (service) is implemented as an orchestration of services provided by internal systems and services provided by two trading partners - Star Loan and United Loan - that provide the financing. These companies provide Web Services for accepting loan applications, returning loan offers, and issuing loan policies when an offer is accepted. The setup is shown in Figure 3.

AutoLoan implemented this process using a service orchestration platform based on Business Process Execution Language (BPEL). The message flow for this scenario is shown in Figure 4.

As part of the loan application, the customer, Mr. Smith, must provide certain sensitive data, such as his Social Security number. Without an appropriate security infrastructure in place, as the loan application request (message) flows through the various services, the SSN is sent in clear text - exposing sensitive information and potentially leading to unwarranted information disclosures. The message may be subject to attacks that include tampering. Besides tampering, there may be replay attacks where the message is hijacked and re-submitted multiple times. Since Mr. Smith logs onto a Web site and submits the application online, the identity of Mr. Smith must be part of the message sent from the loan portal to the Web Services. This requires the ability to propagate the identity of Mr. Smith as part of the service request and the ability to enable single-sign on and identity propagation in the backend systems.

Certain checks may also have to be done to make sure the customer is authorized to request a loan (for example, loans may be available only to existing customers). Since Mr. Smith may claim that he never submitted the loan application, the system must support non-repudiation through message auditing. In the new regulatory environment, companies may be required to adhere to audit compliance standards that would require the system to be able to audit events such as authentication and authorization.

Since AutoLoan exposes its application to trading partners, messages flowing back and forth could potentially contain SQL injection, XML injection, or other attacks aimed at AutoLoan's systems.

These security vulnerabilities are shown in Figure 5.

Securing the BPEL Loan Application Process
To develop the loan application process, we advocate using a WSM solution so you avoid embedding security policies in the service code. You would then do static and dynamic analysis on the application to make sure it's protected from the inside and simulate some attack patterns.

Applying Security Policies to the Service
The developer of the loan application service or the operational manager must select the appropriate security scenario policy from the policy library provide by the WSM software. In general, security scenario policies capture security patterns that have emerged from common best practices when providing end-to-end message security to services. For example, a security scenario policy includes authentication information such as whether the service accepts username/password or X509 certificates, whether the message should be signed and encrypted, and the information needed for authorization and auditing. Since the body of the message must be integrity-protected and encrypted for the message exchange, the developer specifies this by editing the message protection attributes of the X509 security scenario.

Once the scenario policies are associated with the service, the WSM software will automatically enforce them when a message is received at this service.

Applying Matching Policies on the Client Side
Now let's look at the developer who creates the client/service consumer that calls the loan application service.

The developer discovers the Loan Flow Service from a UDDI registry and retrieves the WSDL containing the service provider policies. The server hosting the loan application service will return the WSDL, which contains the policies, and policy references that are attached at various levels in the WSDL based on the WS-Policy Attachment specification. These policies, based on the WS-Policy specification, describe in an interoperable way the capabilities and constraints that the consumer must meet to communicate successfully with the loan application process. The client developer finds a policy from the policy library governing the interaction for the client side that adheres to constraints specified by the service provider policy. In some environments, the integrated development environment (IDE) may be integrated with a centralized metadata repository; if so, the developer can browse for policies through a resource catalog. (If one isn't available, the policy information has to be provided to the developer of the service consumer by some other means, such as text.)

The client developer uses the policy designer (part of the WSM solution) to specify the exact parameters - for example, the algorithm to be used for encryption/decryption and the order in which the message should be signed and encrypted - and attaches it to the service consumer through the IDE. The policies will be automatically enforced by the WSM software on both the client and server side when the client sends the message to the service. If no WSM software is available on the client side, the application server software on which the client runs will implement the policies, as long as it conforms to the WS-* specifications noted above.

Runtime View of WSM in Action
Let's explore the interactions between the messages and infrastructure components shown in Figure 6.

The service consumer’s call to the service is intercepted by the WSM policy enforcement agent on the client side (1). The agent enforces the security policy scenario that was attached to the service consumer. For instance, the agent inserts a security token, such as username and password, for authentication purposes and signs and encrypts the message body to satisfy the service’s integrity and confidentiality requirements. The security information is attached to the SOAP request using standard WS-Security mechanisms. The request traverses firewalls and Web servers to reach the virtual end point of the service, exposed typically through a Web services gateway. The gateway contacts the policy manager to query the security policy requirements associated with the service end point and enforces these requirements on the incoming service request in a pipeline fashion.

In this case, the SOAP request is first decrypted and its signature is validated (2). Subsequently, the claims presented in the authentication token are validated against a locally configured Identity Management system (3). Optionally, the agent may perform an authorization check to determine if the authenticated user has access to the service. Once the user identity and access is established, it’s asserted to the service implementation to facilitate additional service-specific authorization checks. The WSM gateway may then propagate the user’s identity to the actual service by inserting a SAML assertion into the message (4). Once the message is received by the actual service, the identity in the message is retrieved by the WSM agent and is asserted to the container as a JAAS subject (5).

Conclusion
We hope we've convinced you that it's best to take security policies out of service implementations and capture them in a WSM solution that implements authentication, authorization, and encryption, applies digital signatures;,and performs schema validation.

As developers, we can't always purport to be security (or identity management) experts. As a result, the more security policies are kept out of the application code, the better - externalizing security allows better assert management and makes the developers' lives easier! Static and dynamic analysis tools help you cover the bases by making sure your code does the right checks on the input XML data. Simulating attacks before deploying, and monitoring your setup afterward, helps you obviate risk. We didn't talk much about monitoring. Suffice to say that it's an integral part of the feedback loop for continuously improving security. A holistic approach to security in SOAs that combines infrastructures, tools, and secure coding practices, and builds security early - from design through deployment - will make SOA security less of a headache, and may even simplify it.

Acknowledgements
The authors would like to thank Marc Chanliau for providing many helpful comments on this paper.

© 2008 SYS-CON Media