Thursday, February 28, 2013

Recent security advisories for Apache CXF

Apache CXF 2.7.3 (release notes), 2.6.6, and 2.5.9 have been released and are available for download. These releases contain fixes for a number of critical security issues, which I will describe below.

1) CVE-2012-5633

A security advisory has been issued in relation to a possible circumvention of WS-Security processing of an inbound request, due to the URIMappingInterceptor in CXF. This is a legacy interceptor (largely made redundant by JAX-RS) that allows some basic "rest style" access to a simple SOAP service. The vulnerability occurs when a simple SOAP service is secured with the WSS4JInInterceptor. WS-Security processing is completely by-passed in the case of a HTTP GET request, and so unauthenticated access to the service can be enabled by the URIMappingInterceptor.

This is a critical vulnerability if you are using a WS-Security UsernameToken
or a SOAP message signature via the WSS4JInInterceptor to authenticate users
for a simple SOAP service. Please note that this advisory does not apply if
you are using WS-SecurityPolicy to secure the service, as the relevant policies
will not be asserted. Also note that this attack is only applicable to
relatively simple services that can be mapped to a URI via the URIMappingInterceptor.

Although this issue is fixed in CXF 2.5.8, 2.6.5 and 2.7.2, due to a separate
security vulnerability (CVE-2013-0239), CXF users should upgrade to either 2.5.9, 2.6.6, or 2.7.3.

2) CVE-2013-0239

A security advisory has been issued in relation to an authentication bypass involving a UsernameToken WS-SecurityPolicy requirement. If a UsernameToken element is sent with no password child element, then authentication is bypassed by default. This is due to the use-case of supporting deriving keys from a UsernameToken, where a password element would not be sent in the token.

The vulnerability does not apply in any of the following circumstances:
  • You are using a custom UsernameTokenValidator which does not allow the 'verifyUnknownPassword' use-case, or that otherwise insists that a password must be present in the token (such as the 'JAASUsernameTokenValidator' in WSS4J).
  • You are using a 'sp:HashPassword' policy that requires a hashed password to be present in the token.
  • You are using the older style of configuring WS-Security without using WS-SecurityPolicy.
If you are relying on WS-SecurityPolicy enabled plaintext UsernameTokens to
authenticate users, and if neither points a) nor b) apply, then you must
upgrade to either CXF 2.5.9, 2.6.6 or 2.7.3, or else configure a custom
UsernameTokenValidator implementation to insist that a password element must
be present.

3) Note on CVE-2011-2487

A security advisory 'note' was also published to the CXF Security Advisories page, giving details on an attack against XML Encryption that affects users of older versions of CXF (prior to 2.5.3 and 2.4.7). It carries the following recommendation:
It is recommended that the use of the RSA v1.5 key transport algorithm be discontinued. Instead the RSA-OAEP key transport algorithm should be used. This algorithm is used by default from WSS4J 1.6.8 onwards. If you are using WS-SecurityPolicy, then make sure not to use the AlgorithmSuite policies ending in "Rsa15.

Saturday, February 23, 2013

WS-Federation support in Apache CXF

Apache CXF is a leading web services stack with excellent support for a long list of security protocols such as WS-Security, OAuth, etc. A recent addition to this list is support for WS-Federation via the Apache CXF Fediz subproject. In this post, we will introduce Fediz and illustrate how to secure a web application with Fediz via an example.

1) Introducing Apache CXF Fediz

The Apache CXF Fediz subproject provides an easy way to secure your web applications via the WS-Federation Passive Requestor Profile. A good place to start in understanding this profile is to look at the Fediz architecture page. A typical scenario is that a client browser will attempt to access a web application secured with a Fediz plugin. Fediz will redirect the brower to an Identity Provider (IdP) for authentication, if no token/cookie is present in the request. In this way, authentication is externalized from the web application to a third party IdP.

Fediz ships with an IdP component, but naturally the Fediz container plugin is also tested with other implementations. The IdP prompts the user for her credentials, and authenticates them via a Security Token Service (STS). The IdP requests that the STS issues a signed SAML Token on successful authentication. The IdP is configured to request that the STS inserts certain "Claim" attributes in the SAML Token, where the specific "Claim" types are configured per-realm. The client brower is then redirected back to the application server with the inclusion of the SAML Token.

The Fediz plugin parses the received SAML Token. Authentication is established via the trust verification of the signature on the token. Role-based Access Control (RBAC) is supported by configuring the plugin with a "roleURI" attribute (which should correspond to the standard Claims URI for a role). The corresponding attribute values are extracted from the SAML Token and stored as the role(s) of the user. The actual security enforcement is delegated to the underlying container / application server. The containers that are (planned to be) supported are:
  • Apache Tomcat - See here.
  • Jetty - See here, available in the forthcoming 1.1 release.
  • Spring - See here, available in the forthcoming 1.1 release.
  • JBoss - Planned for the forthcoming 1.1 release. 
An important point to note is that the Fediz container plugin is actually protocol-agnostic. WS-Federation is the only protocol supported to date, but support for the SAML Web SSO Profile may be added at a later date. For more detailed information on Fediz you should refer to the documentation, and also to the excellent series of blog articles by Oliver Wulff, who is the main developer on Fediz.

2) Fediz example

Download the latest Apache CXF Fediz release (currently 1.0.3) here, and extract it to a new directory (${fediz.home}). It ships with two examples, 'simpleWebapp' and 'wsclientWebapp'. We will cover the former as part of this tutorial. We will use a Apache Tomcat 7 container to host both the Idp/STS and service application - this is not recommended, but is an easy way to get the example to work. Please see the associated README.txt of the simpleWebapp example for more information about how to deploy the example properly. Most of the deployment information in this section is based on the Fediz Tomcat documentation, which I recommend reading for a more in-depth treatment of deploying Fediz to Tomcat.

a) Deploying the IdP/STS

To deploy the Idp/STS to Tomcat:
  • Create a new directory: ${catalina.home}/lib/fediz
  • Edit ${catalina.home}/conf/catalina.properties and append ',${catalina.home}/lib/fediz/*.jar' to the 'common.loader' property.
  • Copy ${fediz.home}/plugins/tomcat/lib/* to ${catalina.home}/lib/fediz
  • Copy ${fediz.home}/idp/war/* to ${catalina.home}/webapps
Now we need to set up TLS:
  • Copy ${fediz.home}/examples/samplekeys/tomcat-idp.jks to ${catalina.home}.
  • Edit the TLS Connector in ${catalina.home}/conf/server.xml', e.g.: <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" keystoreFile="tomcat-idp.jks" keystorePass="tompass" clientAuth="false" sslProtocol="TLS" URIEncoding="UTF-8"  />
Now start Tomcat, and check that the STS is live by opening the STS WSDL in a web browser: 'https://localhost:8443/fediz-idp-sts/STSService?wsdl'

b) Deploying the service

To deploy the service to Tomcat:
  • Copy ${fediz.home}/examples/samplekeys/tomcat-rp.jks to ${catalina.home}.
  • Copy ${fediz.home}/examples/simpleWebapp/src/main/config/fediz_config.xml to ${catalina.home}/conf/
  • Edit ${catalina.home}/conf/fediz_config.xml and replace '9443' with '8443'.
  • Do a "mvn clean install" in ${fediz.home}/examples/simpleWebapp
  • Copy ${fediz.home}/examples/simpleWebapp/target/fedizhelloworld.war to ${catalina.home}/webapps.
c) Testing the service

To test the service navigate to:
  • https://localhost:8443/fedizhelloworld/  (this is not secured) 
  • https://localhost:8443/fedizhelloworld/secure/fedservlet
With the latter URL, the browser is redirected to the IDP and is prompted for a username and password. Enter "alice/ecila" or "bob/bob" or "ted/det" to test the various roles that are associated with these username/password pairs.

Finally, you can see the metadata of the service via the standard URL:
  • https://localhost:8443/fedizhelloworld/FederationMetadata/2007-06/FederationMetadata.xml

Thursday, January 24, 2013

Recent security enhancements in Apache CXF 2.7.x

In this post, I will cover some new security features and enhancements that are contained in Apache CXF 2.7.2 (release notes), as well as the previous 2.7.1 release (release notes).

1) STS Enhancements
  • The STS ClaimsManager used to call all ClaimsHandler implementations for processing. Now it only calls the implementations that support the requested claim (CXF-4461).
  • New functionality was added to the STS to support processing 'primary' and 'secondary' claims, and to merge claims with the same dialects (CXF-4664).
  • It is now possible for the STSClient to send a 'Claims' Element to the STS via a CallbackHandler (CXF-4638).
  • You can now configure signature + encryption Crypto objects in the STS via a URL or properties object, as per the runtime (CXF-4705).
2) SAML Enhancements
  • SAML SubjectConfirmation requirements are now enforced for the non-policy case (CXF-4655).
  • The JAX-RS SAML interceptors have been enhanced to allow sending an existing SAML Token, rather than always creating one (CXF-4639).
3) XACML Enhancements

A new 'cxf-rt-security' module was introduced in CXF 2.7.1, for security functionality that is common to several of the runtime modules (WS-Security, RS-Security, etc.). For now this module contains some new security functionality based around XACML:
  • It contains some helper classes to construct XACML Request statements using OpenSAML for the XACML 2.0 core specification (see here), as well as the SAML Profile of XACML 2.0 (and here).
  • It contains an interface to create an XACML request given a Principal, list of roles and a CXF Message object, as well as a default implementation. This implementation follows the SAML 2.0 profile of XACML 2.0. The principal name is inserted as the Subject ID, and the list of roles associated with that principal are inserted as Subject roles.  The action to send defaults to "execute". The resource is the WSDL Operation for a SOAP service, and the request URI for a REST service. The current DateTime is also sent in an Environment.
  • An abstract interceptor is provided that wraps the XACML request creation functionality given above. It can perform an XACML authorization request to a remote PDP, and make an authorization decision based on the response. It takes the principal and roles from the CXF SecurityContext, and uses the XACMLRequestBuilder to construct an XACML Request statement.

Monday, January 7, 2013

Apache WSS4J 1.6.9 released

Apache WSS4J 1.6.9 has been released. This release contains a single (critical) fix for a bug which prevented WSS4J 1.6.8 from working correctly in an OSGi container.

Monday, December 10, 2012

Apache WSS4J 1.6.8 released

Apache WSS4J 1.6.8 has been released. The list of issues fixed is available here. One of the most significant improvements is a fix for using WSS4J with XML Signature on Websphere. A new feature has also been added to WSS4J 1.6.8, namely the ability to define which algorithms are acceptable when processing an inbound request. This functionality has already been integrated into CXF and will be available in the 2.7.1, 2.6.4 and 2.5.7 releases. This essentially means that rather than check the algorithms against the relevant AlgorithmSuite used as part of WS-SecurityPolicy after WSS4J has finished processing the security header, the algorithms will be checked by WSS4J in real-time when processing the header.

A new page has been added to the WSS4J website which describes 'security best practices' when using WSS4J. The points are summarised as follows:
  • Upgrade from WSS4J 1.5.x to WSS4J 1.6.x
  • Upgrade to the latest minor release as soon as possible
  • Use WS-SecurityPolicy to enforce security requirements
  • Use RSA-OAEP for the Key Transport Algorithm
  • Avoid using a cbc Symmetric Encryption Algorithm
  • Use Subject DN regular expressions with chain trust
  • Specify signature algorithm on receiving side

Monday, October 22, 2012

Apache XML Security for Java 1.5.3 released

Apache XML Security for Java 1.5.3 has been released. This release features support for new XML Signature 1.1 KeyInfo extensions. It also fixes a number of bugs including a problem when message sizes are greater than 512 MB. The list of issues fixed is available at the Apache JIRA.

Wednesday, October 3, 2012

XML Signature Wrapping attacks on Web Services

The previous blog post looked at SOAP Action spoofing attacks on Web Services and discussed a recent security advisory in this area in Apache CXF. This vulnerability was uncovered with the help of the WS-Attacker tool referenced here. This paper also covers a different type of attack on WS-Security enabled Web Services, namely XML Signature Wrapping attacks. The WS-Attacker tool also offers some functionality to test Web Service endpoints for vulnerability against these types of attacks. In this post we will look at how to protect against XML Signature Wrapping attacks in Apache CXF.

1) XML Signature wrapping attacks

It is possible to sign a portion of a SOAP Web Service request or response at the message level using XML Signature. The message contains a security header with a Signature Element, that references one or more message parts that have been signed. Typically, the message parts are referenced by an Id, and so to validate the signature the recipient must find the Element in the request that has the corresponding Id. An XML Signature wrapping attack essentially exploits the fact that the Signature Element does not convey any information as to where the referenced Element(s) is(are) in the Document tree.

Consider a scenario where the SOAP Body of a request is signed by a signature placed in the security header of the request. The message recipient checks that the signature is correct and validates trust in the signing credential. Finally, the recipient checks to see that the required Element (in this case the SOAP Body) was actually signed, by comparing the wsu:Id of the SOAP Body to the Reference URI in the Signature.

An XML Signature wrapping attack against this scenario could work as follows. A malicious (man-in-the-middle) user could take a valid request and copy the SOAP body and insert it as part of a header in the request. The malicious user then freely alters the SOAP Body, but preserves the same wsu:Id. The message recipient must search for the Reference URI as part of the signature validation process, and hits the copied SOAP Body Element first. This verifies correctly as it has not been changed. Finally, the recipient checks to see if the Id of the SOAP Body was actually referenced in the signature (which it was, even though the SOAP Body itself was not signed).

Apache WSS4J has a built-in guard against this kind of attack, whereby an ID referenced in an XML Signature cannot appear more than once in a SOAP Envelope. However, there are more sophisticated types of wrapping attacks which can defeat this defence. The crucial thing to realise is that for XML Signature you must check to see that what you are expecting to be signed was actually signed. Apache WSS4J does not perform this kind of check, instead it is left up to the third party application (Apache CXF for the purposes of this article). 

2) Protecting against XML Signature wrapping attacks in Apache CXF

There are two ways to configure WS-Security in Apache CXF, the recommended approach based on WS-SecurityPolicy, and the older and less sophisticated approach of specifying individual security actions to perform.

2.1) WS-SecurityPolicy

The WS-SecurityPolicy approach offers easy protection against signature wrapping attacks via the WS-SecurityPolicy SignedParts and SignedElements policies. The SignedElements policy takes a number of XPath expressions corresponding to the Elements that must be signed, should they be included in the request. The XPath expression must not be a relative expression for the purposes of protection against this attack.

A more common approach is to use the WS-SecurityPolicy "SignedParts" policy. This policy allows the user to specify that the SOAP Body and any number of SOAP Headers must be signed. For example:

<sp:SignedParts>
<sp:Body />
<sp:Header Name="..." Namespace="..."
</sp:SignedParts>

Apache CXF makes sure that the SOAP Body and any specified SOAP header is actually signed, rather that just comparing Id's as outlined in the attack scenario above, this circumventing any XML Signature wrapping attack.

2.2) Older WS-Security approach

The older non-policy based approach to configuring WS-Security does not perform any checking by default of what Elements were signed, and so is vulnerable to XML Signature wrapping attacks out of the box. One way to remedy this since CXF 2.2.8 is to install the CryptoCoverageChecker interceptor. This allows you to define an XPath Expression corresponding to an Element that must be signed (or encrypted). Installing this interceptor defeats an XML Signature Wrapping attack (see the wiki for more details).

However, the CryptoCoverageChecker is somewhat complex to set up for the most common use-cases for signature verification and decryption, as it involves adding XPath expressions and the corresponding prefix/namespace pairs. In Apache CXF 2.4.9, 2.5.5 and 2.6.2, a new subclass of CryptoCoverageChecker has been introduced. The DefaultCryptoCoverageChecker provides an easy way to ensure that the SOAP Body is signed or encrypted, that the Timestamp is signed, and that the WS-Addressing ReplyTo and FaultTo headers are signed (if they are present in the message payload).

The default configuation is that the SOAP Body, (WSU) Timestamp and WS-Addressing ReplyTo and FaultTo headers must be signed (if they exist in the message payload). This provides an out-of-the-box way of preventing XML Signature wrapping attacks. All that is required is that the DefaultCryptoCoverageChecker be added to the in-interceptor chain. I strongly recommend that you consider doing this if you are still using the older configuration for a WS-Security enabled endpoint. For example:

<jaxws:inInterceptors>
    <bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
        <constructor-arg>
            <map>
                <entry key="action" value="Signature Timestamp"/>
                <entry key="signaturePropFile" value="..."/>
                <entry key="passwordCallbackClass"value="..."/>
           </map>
        </constructor-arg>
    </bean>
    <bean class="org.apache.cxf.ws.security.wss4j.DefaultCryptoCoverageChecker"/>
</jaxws:inInterceptors>