This vulnerability was jointly discovered by Klemen Bratec from Šola prihodnosti Maribor , and Ioannis Kakavas from Greek Research and Technology Network and this blog post is cross-posted here and on Klemen's blog .

A vulnerability in Microsoft Office 365 SAML Service Provider implementation allowed for cross domain authentication bypass affecting all federated domains. An attacker exploiting this vulnerability could gain unrestricted access to a victim's Office 365 account, including access to their email, files stored in OneDrive etc.

Upon receiving the SAML Response, the Service Provider can verify its contents and structure, validate the signature and subsequently treat the user as authenticated initiating a web session for them.

The Assertion (and possibly the whole SAML Response) is signed with a XML Signature that protects the integrity of the Assertion (or response) and verifies that it has not been modified in transit.

Upon receiving the SAML Request, the Identity Provider checks that it knows and trusts the Service Provider that sends it, validates the contents of the Request and prompts the user for authentication. If the user authenticates successfully, the Identity Provider generates a SAML response, that looks something like this:

The user's browser is then redirected to the respective URL at the Identity Provider depending on the binding that is used and that SAML Authentication Request is passed as a string query parameter in the HTTP GET ( after it has been deflated , base64 encoded and URL encoded ).

It all starts with a user attempting to access a protected resource at some service (or explicitly asking to log in). The service is configured to allow/enforce federated login and as such presents or redirects the user to a Discovery Service interface in order to select their Identity Provider. Upon user selection, and given that it knows and trusts the selected Identity Provider, the Service Provider creates a SAML Authentication Request that looks like this:

A simple example of the Web Browser SSO Profile is the case where the service provider uses the HTTP Redirect binding and the identity provider uses the HTTP POST binding. The actors involved are

The service provider is the SAML consumer that consumes the information (in the form of assertions) about the users in order to allow them access to resources.

The identity provider is the SAML authority that holds the information about users and can issue assertions for them to use in Service Providers.

SAML bindings describe how a SAML message must be mapped on non SAML related messaging formats and communication protocols. For instance the HTTP Redirect Binding defines how SAML messages are formatted when carried directly in the URL query string of an HTTP GET request. A SAML request is transmitted via an SAMLRequest query parameter, the value of which is deflated, base64 encoded and URL encoded.

SAML protocols describe how certain SAML elements (including assertions) are packaged within request and response elements, and gives the processing rules that SAML entities must follow when producing or consuming these elements. The Authentication Request Protocol is described later on.

Assertions are XML structures that contain packaged security information about the user. The two mostly used assertion types are

This section focuses on SAML 2.0. The most important components of the SAML specification are the following:

SAML stands for Security Assertion Markup Language and is an XML-based standard for exchanging authentication and authorization data between parties. The prominent use of SAML is for Cross Domain Web Single-Sign-On. This is an overview of the SAML 2.0 Web Browser SSO Profile, short enough to get the gist of it so you can understand the following sections, long enough to bore you if you are familiar with SAML already, so feel free to skip to How Office 365 SAML implementation works .

It can also be seen that both the SAML Response and the SAML Assertion are digitally signed.

and the IDPEmail that corresponds to the UPN of the existing account of the user in Azure AD is contained in the Attribute Statement

The ImmutableId that uniquely identifies the user is in the Subject of the Assertion

and subsequently their browser is instructed to make an HTTP POST back to the HTTP-POST binding URL of Office 365, https://login.microsoftonline.com/login.srf with the SAML Response containing the Assertion in the request body. An example of this SAML Response is seen below

If the domain is known and configured as federated, the user's browser is instructed to make an HTTP POST request to the HTTP-POST binding URL of the Identity Provider for that domain with a SAML Response in the body that looks like this:

Upon entering the username and pressing TAB or clicking on the password field, the page makes an XHR to https://login.microsoftonline.com/common/userrealm in order to check if the user's domain corresponds to an Office 365 tenant

The process starts with the user accessing Office 365 portal , being redirected to https://login.microsoftonline.com/login.srf where he is greeted with the following form

One additional thing to keep in mind is that Office 365 does not support Just-In-Time provisioning for accounts authenticating via SAML, so for Signle Sign On to work the account must already be registered in Azure AD for the specific tenant. This can happen via Directory Synchronization or via user provisioning with the help of an IDM system, but this is out of the scope of this post.

However, for the sake of simplicity, for the rest of this section the Office 365 service provider is considered to be a SAML service provider.

The Office 365 service provider implementation is a weird mixture of WS-Trust specification and SAML 2.0 Web Browser SSO Profile. That is, Office 365 supports SSO both with WS-Trust and with SAML 2.0 Web Browser SSO but the two implementations are not isolated. This is why, for example, in the official documentation for SAML 2.0 SSO shibboleth identity provider is referred to as a Security Token Service, terminology that is relevant to WS-Trust specification but not SAML. The SAML service provider is, however, SAML 2.0 compliant-ish (sic) from the perspective of a SAML identity provider and uses a token translation service to convert SAML messages to WS-Trust messages internally. This encapsulation becomes specifically relevant later on, when discussing the attack surface in How could this be exploited? as the vulnerability found in the SAML Service Provider implementation also affects the WS-Trust SSO implementation because of this token translation service.

What was wrong about the Office 365 Implentation?

In the process of integrating Office 365 as a Service Provider in the Greek AAI Federation using the AAI365 solution that Šola prihodnosti Maribor offers we came up with some interesting flaws in how Microsoft implements the SAML Service Provider.

What about SAML NameID? The first thing we noticed is that Office 365 SAML Service Provider disregards the Subject of the Assertion, even though it contains the ImmutableId value that should be the UUID of the user in the Azure AD that would uniquely identify him. A name identifier, represented by the <NameID> element in SAML 2, is generally used to identify the subject of a SAML assertion. Name identifiers can be anything; an email address or a Kerberos principal name are common, every-day examples of such information. SAML 2 also defines more specialized identifier types with particular properties useful in federated applications. Strictly speaking, SAML assertions don't have to contain an identifier. The subject may be implicitly identified as the bearer of the token or anybody able to demonstrate possession of a key. In SSO use cases, one reason for including an identifier is to enable the relying party to refer to the subject later, such as in a query, or a logout request. From an attacker's perspective, the fact that the correctness of the NameID is not checked, makes things easier since the ImmutableID usually comes from AD objectGUID and it's hard to guess or bruteforce.

Scoping That leaves the value of the IDPEmail attribute that corresponds to the UPN of the user in the Azure AD, as the sufficient piece of information to identify the user in the Assertion. Well, ok, this is not necessarily bad in itself as the Assertion also contains the Issuer that generated and signed it, so an unrelated Identity Provider cannot create assertions for other domain's/tenant's users, right? Wrong. As it turns out, the Service Provider used the Issuer of the Assertion only to find the mathing certificate in order to verify the SAML Response/Assertion signature, but didn't perform any sanity checks on the supplied value of the IDPEmail attribute. That basically means that it would happily consume assertions, asserting that Identity Provider X has authenticated users of Identity Provider Y. In SAML world this can be mitigated with the help of scoped attributes. These are attributes that have 2 parts, a value and a scope in the format value@scope. The Identity Provider publishes the scope that it is authoritative for in it's Metadata and Service Providers are supposed to check that when they consume a scoped attribute from an Identity Provider, they check that the scope that came matches the published one. UPN a.k.a. IDPEmail is scoped by definition as the domain part needs to be one of the (sub-)domains that the administrator has verified in an Office365 tenant.