CVE-2016-10149 (Python, published 2017-03-24T14:59Z)
Description: value: XML External Entity (XXE) vulnerability in PySAML2 4.4.0 and earlier allows remote attackers to read arbitrary files via a crafted SAML XML request or response.
Severity: MEDIUM (CVSS v3 base score: 7.5)
Weakness: CWE-611 \u2014 Improper Restriction of XML External Entity Reference
The product processes an XML document that can contain XML entities with URIs that resolve to documents outside of the intended sphere of control, causing the product to embed incorrect documents into its output.
Repository: https://github.com/rohe/pysaml2
Files changed:
setup.py
src/saml2/__init__.py
src/saml2/pack.py
src/saml2/soap.py
tests/test_03_saml2.py
tests/test_43_soap.py
tests/test_51_client.py
Commit message: Fix XXE in XML parsing (related to #366)

This fixes XXE issues on anything where pysaml2 parses XML directly as part of
issue #366. It doesn't address the xmlsec issues discussed on that ticket as
they are out of reach of a direct fix and need the underlying library to fix
this issue.


Vulnerable code:
    tree = ElementTree.fromstring(xml_string)
    element_tree = ElementTree.fromstring(xml_string)
    envelope = ElementTree.fromstring(text)
    envelope = ElementTree.fromstring(text)
        envelope = ElementTree.fromstring(text)
        envelope = ElementTree.fromstring(text)

Fixed code:
    'defusedxml',
import defusedxml.ElementTree
    tree = defusedxml.ElementTree.fromstring(xml_string)
    element_tree = defusedxml.ElementTree.fromstring(xml_string)
import defusedxml.ElementTree
    envelope = defusedxml.ElementTree.fromstring(text)
import defusedxml.ElementTree
    envelope = defusedxml.ElementTree.fromstring(text)
        envelope = defusedxml.ElementTree.fromstring(text)
        envelope = defusedxml.ElementTree.fromstring(text)
from defusedxml.common import EntitiesForbidden
def test_create_class_from_xml_string_xxe():
    xml = """<?xml version="1.0"?>
    <!DOCTYPE lolz [
    <!ENTITY lol "lol">
    <!ELEMENT lolz (#PCDATA)>
    <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
    ]>
    <lolz>&lol1;</lolz>
    """
    with raises(EntitiesForbidden) as err:
        create_class_from_xml_string(NameID, xml)


def test_ee_xxe():
    xml = """<?xml version="1.0"?>
    <!DOCTYPE lolz [
    <!ENTITY lol "lol">
    <!ELEMENT lolz (#PCDATA)>
    <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
    ]>
    <lolz>&lol1;</lolz>
    """
    with raises(EntitiesForbidden):
        saml2.extension_element_from_string(xml)


from defusedxml.common import EntitiesForbidden

from pytest import raises
from saml2 import soap


def test_parse_soap_enveloped_saml_thingy_xxe():
    xml = """<?xml version="1.0"?>
    <!DOCTYPE lolz [
    <!ENTITY lol "lol">
    <!ELEMENT lolz (#PCDATA)>
    <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
    ]>
    <lolz>&lol1;</lolz>
    """
    with raises(EntitiesForbidden):
        soap.parse_soap_enveloped_saml_thingy(xml, None)


def test_class_instances_from_soap_enveloped_saml_thingies_xxe():
    xml = """<?xml version="1.0"?>
    <!DOCTYPE lolz [
    <!ENTITY lol "lol">
    <!ELEMENT lolz (#PCDATA)>
    <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
    ]>
    <lolz>&lol1;</lolz>
    """
    with raises(soap.XmlParseError):
        soap.class_instances_from_soap_enveloped_saml_thingies(xml, None)


def test_open_soap_envelope_xxe():
    xml = """<?xml version="1.0"?>
    <!DOCTYPE lolz [
    <!ENTITY lol "lol">
    <!ELEMENT lolz (#PCDATA)>
    <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
    ]>
    <lolz>&lol1;</lolz>
    """
    with raises(soap.XmlParseError):
        soap.open_soap_envelope(xml)
from pytest import raises
from saml2.pack import parse_soap_enveloped_saml
from defusedxml.common import EntitiesForbidden

def test_parse_soap_enveloped_saml_xxe():
    xml = """<?xml version="1.0"?>
    <!DOCTYPE lolz [
    <!ENTITY lol "lol">
    <!ELEMENT lolz (#PCDATA)>
    <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
    ]>
    <lolz>&lol1;</lolz>
    """
    with raises(EntitiesForbidden):
        parse_soap_enveloped_saml(xml, None)