Carrying sensitive information in SAML assertions

When SAML is used in conjunction with WS-Security, only an small piece of the token is encrypted, the proof key for the relying party. The rest of the token goes in plain text, that also includes the user's claims.


  <saml:Conditions NotBefore="2009-02-24T19:48:20.500Z" NotOnOrAfter="2009-02-24T19:53:20.500Z"></saml:Conditions>






        <KeyInfo xmlns="">...</KeyInfo>



  <saml:Attribute AttributeName="displayName" AttributeNamespace="">

      <saml:AttributeValue>John Foo</saml:AttributeValue> <--Attribute value-->



  <Signature xmlns="">...</Signature>


Knowing this, you should never include sensitive information as claims in a SAML token. This is also related to the identity law #2, "Minimal Disclosure for a Constrained Use". The Identity provider should only disclose the least amount of identifiying information for executing the operation on the relying party.

Some examples are,

  • A winery only needs to know whether the customer is in a legal age for buying alcohol according to the law, a claim like "over21" should be enough for that purpose, there is not need to know the customer birth date at all.
  • An online store that sells products does not necessary need to know the number of every credit card owned by a customer, a friendly name representing the card and optionally the available balance could be enough for completing a purchase.

SAML 2.0 introduces the concept of "encrypted attribute", which clearly states its purpose, encrypt individual assertions in a SAML token. In this way, a token can now carry the encrypted proof key and optionally one or more encrypted assertions with sensitive information.

You can take a look at this page for more information about the differences between SAML 1.1 and 2.0.

Geneva Framework Beta 1 already implements a subset of SAML 2.0, however, it looks like this feature has been left out in the current release. Not sure either whether this feature will be included as part of the final release (Last quarter of 2009). I created a post in the forums some time ago, I haven't received any feedback yet.


  • Information Card standard, and WS-Trust/WS-Secure allows for the RSTR to be encrypted against the public key of the relying party's SSL certificate (SharpSTS does this by default if realises there's a key to encrypt against in the RST)

    By setting the EncryptingCredentials property on a Scope inside your custom GetScope() implementation it should the Encrypt the message. The certificate for the RP is included in the RST so you don't have to pull it from a certificate store as all the examples I've found seem to show *grin*

  • @barryd,
    Yes, the SAML token may be totally encrypted in the RSTR message. However, when the token is included in the message for relying party, only the saml:SubjectConfirmation element is encrypted (Proof key), the rest of the token is visible. At least, it always worked this way in WSE and WCF.

    I had to implement myself the encrypted assertions feature for SAML tokens in WSE to overcome this issue. That was made as part of a WS-Federation Quickstart for the Patterns & Practices team in Microsoft.


  • How did you come to determine that the tokens weren't encrypted? Did you attach a message inspector to the STS and look at messages as they went out, did you use Fiddler/WireShark, or some other technique?

    Regardless of whether or not the tokens are encrypted, all the messages between subject, STS, and RP should be over SSL, mitigating this problem. If this is the case, then the tokens are scrambled at least once.

  • @Travis,

    Yes, you can confirm this using either a tool like fiddler or the WCF traces.

    SSL is transport security, if you are already using message security with WS-Security, which is required for Active Profile requestors, adding a extra security layer would not make sense at all.

  • In my current work w/ Geneva Framework, SSL is always used because I'm focusing (for the time being at least) on building a passive STS to support browser-based clients. SSL is absolutely required because they are only able to work w/ bearer tokens, requiring SSL to protect against man in the middle attacks. As such, the need to encrypt the tokens in the messages isn't required in this case. It is only necessary for (active) clients that are using an insecure channel. The use of the secure channel also precludes the use of fiddler, WCF tracing, and the like for snooping at messages unfortunately.

  • Ah it could be your use case is different. Certainly when there's a selector in the way then encryption may be done by the selector (if the STS doesn't get the RP identity passed to it as part of the RST)

    I did have to implement those bits myself in SharpSTS.

    Of course an STS may ignore the certificates sent in the RST and encrypt against something else altogether. You look at all the samples and they're pulling certs from the cert store.

  • Pablo, what you describe about "very little" of the SAML token (i.e. just the proof key) being encrypted is not true if you use the Geneva Framework.

    As barryd correctly points out, if scope.EncryptingCredentials are configured on the STS, the Geneva Framework will encrypt the proof key AND the entire token for the relying party. The steps that are taken are:
    1. Encrypt the proof key (using the RP's certificate)
    2. Sign the token (using the STS's certificate)
    3. Encrypt the entire token (using the RP's certificate)

    This did NOT happen in WCF and WSE because of the following:
    1. WCF never shipped with an STS and the STS that was written as part of the sample perhaps never did this.

    2. WSE didn't ship with an STS that issued SAML tokens - the example that did so was written by the PAG team and was really a proof of concept - it was never intended to be the way folks should implement STS's

    You're right in that Geneva Framework does not support Encrypted Attributes - if you think this scenario is important please let us know. BTW - your forum post has just been answered :)

  • Hi Sidd,

    Thanks for giving your tougths on this, I really appreciate it. So, when Geneva is used to develop the STS, the issue token is an encrypted token (Containing the SAML token), interesting. I think the encrypted assertions is a powerful feature to have. It is also important if we want to interop with a STS that already implements this feature. Anyways, if the you leave this feature out, I guess you must have good reasons to do it. From a security point of view, encrypting the whole token as you are doing it now would be enough.


Comments have been disabled for this content.