|
7 | 7 | from future.backports.urllib.parse import parse_qs |
8 | 8 | from future.backports.urllib.parse import urlencode |
9 | 9 | from future.backports.urllib.parse import urlparse |
| 10 | +from pytest import raises |
10 | 11 |
|
11 | 12 | from saml2.argtree import add_path |
12 | 13 | from saml2.cert import OpenSSLWrapper |
|
25 | 26 | from saml2.authn_context import INTERNETPROTOCOLPASSWORD |
26 | 27 | from saml2.client import Saml2Client |
27 | 28 | from saml2.config import SPConfig |
| 29 | +from saml2.pack import parse_soap_enveloped_saml |
28 | 30 | from saml2.response import LogoutResponse |
29 | 31 | from saml2.saml import NAMEID_FORMAT_PERSISTENT, EncryptedAssertion, Advice |
30 | 32 | from saml2.saml import NAMEID_FORMAT_TRANSIENT |
|
38 | 40 | from saml2.s_utils import factory |
39 | 41 | from saml2.time_util import in_a_while, a_while_ago |
40 | 42 |
|
| 43 | +from defusedxml.common import EntitiesForbidden |
| 44 | + |
41 | 45 | from fakeIDP import FakeIDP |
42 | 46 | from fakeIDP import unpack_form |
43 | 47 | from pathutils import full_path |
@@ -1552,6 +1556,17 @@ def test_negotiated_post_sso(self): |
1552 | 1556 | 'http://www.example.com/login' |
1553 | 1557 | assert ac.authn_context_class_ref.text == INTERNETPROTOCOLPASSWORD |
1554 | 1558 |
|
| 1559 | +def test_parse_soap_enveloped_saml_xxe(): |
| 1560 | + xml = """<?xml version="1.0"?> |
| 1561 | + <!DOCTYPE lolz [ |
| 1562 | + <!ENTITY lol "lol"> |
| 1563 | + <!ELEMENT lolz (#PCDATA)> |
| 1564 | + <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> |
| 1565 | + ]> |
| 1566 | + <lolz>&lol1;</lolz> |
| 1567 | + """ |
| 1568 | + with raises(EntitiesForbidden): |
| 1569 | + parse_soap_enveloped_saml(xml, None) |
1555 | 1570 |
|
1556 | 1571 | # if __name__ == "__main__": |
1557 | 1572 | # tc = TestClient() |
|
0 commit comments