Wednesday, May 22, 2013

Apache CXF 2.7.5 released

Apache CXF 2.7.5 has been released. The list of issues fixed is available here. The following security fixes of note have been made in this release:
  • The OpenSAML dependency has been upgraded from 2.5.1 to 2.5.3.
  • A change was made to the logic the STS uses to encrypt tokens that it issues. Previously it threw an exception if a key could not be found (at either service or at a more generic level) to use to encrypt the token. Now it only encrypts the token if a matching key can be found. This allows the ability to only encrypt tokens to specific "AppliesTo" endpoint addresses.
  • LDAP groups are now (better) supported as claims in the STS. See the following blog entry for more detail.
  • The CryptoCoverageChecker interceptor has been enhanced so that you can disable coverage checking for SOAP Faults. This is useful for testing/debugging if you want to figure out the root cause of a remote exception.

Thursday, April 25, 2013

Apache CXF 2.7.4 released

Apache CXF 2.7.4 (and 2.6.7 + 2.5.10) have been released. Users are strongly encouraged to upgrade to the latest versions, due to a critical security issue which must remain undisclosed for the moment. These latest releases pick up Apache Santuario 1.5.4 and Apache WSS4J 1.6.10. In addition to the fixes in these projects, CXF 2.7.4 contains a number of security fixes of interest.

1) WS-SecurityPolicy fixes

A large number of negative tests for WS-Security(Policy) were added to CXF to try to smoke out some remaining issues surrounding validating a request against a defined security policy. The following issues were fixed as a result:
  • Layout policies "LaxTimestampFirst" and "LaxTimestampLast" were not validated correctly.
  • X509Token "PKI" policies were not validated correctly.
  • The "OnlySignEntireHeadersAndBody" policy was not validated correctly.
  • The "ProtectTokens" policy was not validated correctly in conjunction with EndorsingSupportingTokens.
  • SAML Token versions weren't validated against policy versions in certain circumstances.
2) Populating the SecurityContext from a JAAS Subject from WSS4J

An additional improvement to the WS-Security layer in CXF is that the SecurityContext is now populated from a JAAS Subject from WSS4J, if one is available. For example, if you are using a custom UsernameTokenValidator with WSS4J to validate a received UsernameToken via JAAS, and are returning the Subject (as per WSS4J's JAASUsernameTokenValidator), then CXF will attempt to extract roles from the Subject and populate the SecurityContext accordingly. The advantage of this is that a user can check the standard SecurityContext methods (e.g. "isUserInRole") to perform authorization.

This is controlled by two JAX-WS properties (see the documentation for more information):
  • ws-security.role.classifier - The Subject Role Classifier to use.  If this value is not specified, then it tries to get roles using the DefaultSecurityContext in cxf-rt-core. Otherwise it uses this value in combination with the "ws-security.role.classifier.type" property to get the roles from the Subject.
  • ws-security.role.classifier.type - The Subject Role Classifier Type to use. Currently accepted values are "prefix" or "classname". Must be used in conjunction with the "ws-security.role.classifier". The default value is "prefix".
3) STS fixes

The SecurityTokenService (STS) fixes contained in this release are:
  • The STS Client was not always sending an "AppliesTo" address in a request to the STS, depending on how the STS Client was deployed.
  • The STS Client was always using the "old" WS-Policy namespace for "AppliesTo", instead of getting the namespace from the policy.
  • The STS now supports processing Claims in a request that are retrieved from a security policy as "IssuedToken/Claims". Previously, it would only issue claims that were contained in a "RequestSecurityTokenTemplate" policy. 
4) CVE-2012-5575

Finally, a note on security advisory CVE-2012-5575 was added to the CXF security advisories page. This attack exploits the fact that Apache CXF will attempt to decrypt arbitrary ciphertexts, without first checking to see if the algorithm corresponds to the given encryption algorithm defined by the WS-SecurityPolicy AlgorithmSuite definition. This can be exploited by chosen ciphertext attacks to retrieve the plaintext. Please note that this issue has been fixed since CXF 2.5.7, 2.6.4, and 2.7.1.


Friday, April 19, 2013

Apache Santuario 1.5.4 and Apache WSS4j 1.6.10 released

Two new bug-fix releases of note in Apache security products:

Apache Santuario 1.5.4 has been released. Amongst the issues fixed is a thread-safety problem when secure validation is enabled, and a possible NPE due to ThreadLocal storage when an application is deployed in certain containers.

Apache WSS4J 1.6.10 has also been released. The issues fixed are available here. A performance issue was fixed in the MemoryReplayCache, which is used to guard against replay attacks. An interop issue was fixed with older Axis 1.x stacks. UsernameTokens with no password elements have been explicitly disallowed by default (although this is configurable). Finally, "time-to-live" functionality has been added to disallow "stale" UsernameTokens (with older Created values).

Thursday, March 14, 2013

Signature and Encryption Key Identifiers in Apache WSS4J

The Apache WSS4J configuration allows you to specify how to reference a public key or certificate when signing or encrypting a SOAP message via the following configuration items:
This blog entry will explain what values are valid for each of these configuration items, and will explain what each of these values means. Firstly, let's look at what these configuration items refer to.

When creating a Signature you have the option of adding content to the Signature KeyInfo Element. This lets the recipient know what certificate/public key to use to verify the signature. Specifying a value for WSHandlerConstants.SIG_KEY_ID allows you to change how to refer to the key.

When encrypting some part of the message, a session key is typically generated and used to encrypt the message part, which is then wrapped in an EncryptedData Element. This refers (typically via a Direct Reference) to a EncryptedKey Element in the security header, where the session key is encrypted using the public key of the recipient. Specifying a value for WSHandlerConstants.ENC_KEY_ID allows you to change how to refer to the public key of the recipient in the EncryptedKey KeyInfo element.

The following valid values for these configuration items are:
  • IssuerSerial (default)
  • DirectReference
  • X509KeyIdentifier
  • Thumbprint
  • SKIKeyIdentifier
  • KeyValue (signature only)
  • EncryptedKeySHA1 (encryption only)
1) IssuerSerial

This (default) key identifier method means that the Issuer Name and Serial Number of a X.509 Certificate is included directly in the KeyInfo Element. For example:

<ds:KeyInfo>
    <wsse:SecurityTokenReference>
        <ds:X509Data>
            <ds:X509IssuerSerial>
                <ds:X509IssuerName>CN=XYZ</ds:X509IssuerName>
                <ds:X509SerialNumber>124124....</ds:X509SerialNumber>
            </ds:X509IssuerSerial>
        </ds:X509Data>
    </wsse:SecurityTokenReference>
</ds:KeyInfo>

The certificate is not included in the message and so the recipient will have to have access to the certificate matching the given Issuer Name and Serial Number in a keystore.

2) DirectReference

This key identifier method is used when the X.509 Certificate is included in the message, unlike the IssuerSerial case above. The certificate is Base-64 encoded and included in the request via a BinarySecurityToken element, e.g.:

<wsse:BinarySecurityToken EncodingType="...#Base64Binary"
    ValueType="...#X509v3">MIIBY...
</wsse:BinarySecurityToken>

This Certificate is then referred to directly from the KeyInfo Element as follows:

<ds:KeyInfo>
    <wsse:SecurityTokenReference>
        <wsse:Reference URI="#X509-..." ValueType="...#X509v3"/>
    </wsse:SecurityTokenReference>
</ds:KeyInfo>

3) X509KeyIdentifier 

This key identifier method is similar to DirectReference, in that the certificate is included in the request. However, instead of referring to a certificate, the certificate is included directly in the KeyInfo element, e.g.:

<ds:KeyInfo>
    <wsse:SecurityTokenReference>
        <wsse:KeyIdentifier EncodingType="...#Base64Binary"
            ValueType="...#X509v3">MIIB...
        </wsse:KeyIdentifier>
    </wsse:SecurityTokenReference>
</ds:KeyInfo>

4) Thumbprint

This Key Identifier method refers to the Certificate via a SHA-1 Thumbprint. The certificate may or may not be included in the request. For example:

<ds:KeyInfo>
    <wsse:SecurityTokenReference>
        <wsse:KeyIdentifier EncodingType="...#Base64Binary"
            ValueType="...#ThumbprintSHA1">
            5epW9GhL6s0kC9X9egsRZ90ooeE=
        </wsse:KeyIdentifier>
    </wsse:SecurityTokenReference>
</ds:KeyInfo>

5) SKIKeyIdentifier

This Key Identifier method refers to a Certificate via a Base-64 encoding of the Subject Key Identifier, e.g.:

<ds:KeyInfo>
    <wsse:SecurityTokenReference>
        <wsse:KeyIdentifier EncodingType="...#Base64Binary"
            ValueType="...#X509SubjectKeyIdentifier">
            2DUoN4ppxJz/RNgcCDsJ4SocPdk=
        </wsse:KeyIdentifier>
    </wsse:SecurityTokenReference>
</ds:KeyInfo>

6) KeyValue

This Key Identifier method only applies for Signatures. It includes the (RSA) PublicKey directly in the Signature KeyInfo Element as follows:

<ds:KeyInfo>
    <ds:KeyValue>
        <ds:RSAKeyValue>
            <ds:Modulus>tfJ29N0G1...</ds:Modulus>
            <ds:Exponent>AQAB</ds:Exponent>
        </ds:RSAKeyValue>
    </ds:KeyValue>
</ds:KeyInfo>

7) EncryptedKeySHA1

This Key Identifier method only applies for Encryption. Unlike the previous methods it refers to the way the EncryptedData references the EncryptedKey Element, rather than the way the EncryptedKey Element refers to the public key. For example:

<ds:KeyInfo>
    <wsse:KeyIdentifier EncodingType="...#Base64Binary"   
        ValueType="...#EncryptedKeySHA1">
        X/8wvCY...
    </wsse:KeyIdentifier>
</ds:KeyInfo>

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/calatina.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.