In 2018, Duo Security found a new vulnerability class that affects SAML-based single sign-on (SSO) systems and this led to the following
vulnerabilities being disclosed: CVE-2017-11427, CVE-2017-11428, CVE-2017-11429, CVE-2017-11430, CVE-2018-0489, CVE-2018-7340.
From a specially crafted <SAMLResponse>
file, an attacker having already access to the SAML system with his own account can
bypass the authentication mechanism and be authenticated as another user.
This is due to the fact that SAML protocol rely on XML format and how the underlying XML parser interprets XML comments.
If an attacker manage to change the <NameID>
field identifying the authenticated user with XML comments, he can exploit the
vulnerability.
Here is an example of a potential payload:
<SAMLResponse>
[...]
<Subject>
<NameID>admin@domain.com<!---->.evil.com</NameID>
</Subject>
[...]
</SAMLResponse>
The attacker will manage to generate a valid <SAMLResponse> content with the account "admin@domain.com.evil.com". He will modify it with XML
comments to finally be authenticated as "admin@domain.com". To prevent this vulnerability on application using Spring Security SAML relying on
OpenSAML2, XML comments should be ignored thanks to the property ignoreComments
set to true
.
Noncompliant Code Example
import org.opensaml.xml.parse.BasicParserPool;
import org.opensaml.xml.parse.ParserPool;
import org.opensaml.xml.parse.StaticBasicParserPool;
public ParserPool parserPool() {
StaticBasicParserPool staticBasicParserPool = new StaticBasicParserPool();
staticBasicParserPool.setIgnoreComments(false); // Noncompliant: comments are not ignored during parsing opening the door to exploit the vulnerability
return staticBasicParserPool;
}
public ParserPool parserPool() {
BasicParserPool basicParserPool = new BasicParserPool();
basicParserPool.setIgnoreComments(false); // Noncompliant
return basicParserPool;
}
Compliant Solution
public ParserPool parserPool() {
return new StaticBasicParserPool(); // Compliant: "ignoreComments" is set to "true" in StaticBasicParserPool constructor
}
public ParserPool parserPool() {
return new BasicParserPool(); // Compliant: "ignoreComments" is set to "true" in BasicParserPool constructor
}
See