lib: add lxml wrapper

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2022-06-02 13:25:24 +02:00
parent 8cd1a42fb9
commit 558c7bba2a
5 changed files with 19 additions and 7 deletions

12
authentik/lib/xml.py Normal file
View file

@ -0,0 +1,12 @@
"""XML Utilities"""
from lxml.etree import XMLParser, fromstring # nosec
def get_lxml_parser():
"""Get XML parser"""
return XMLParser(resolve_entities=False)
def lxml_from_string(text: str):
"""Wrapper around fromstring"""
return fromstring(text, parser=get_lxml_parser())

View file

@ -7,9 +7,9 @@ from xml.etree.ElementTree import ParseError # nosec
import xmlsec
from defusedxml import ElementTree
from lxml import etree # nosec
from structlog.stdlib import get_logger
from authentik.lib.xml import lxml_from_string
from authentik.providers.saml.exceptions import CannotHandleAssertion
from authentik.providers.saml.models import SAMLProvider
from authentik.providers.saml.utils.encoding import decode_base64_and_inflate
@ -95,7 +95,7 @@ class AuthNRequestParser:
verifier = self.provider.verification_kp
root = etree.fromstring(decoded_xml) # nosec
root = lxml_from_string(decoded_xml)
xmlsec.tree.add_ids(root, ["ID"])
signature_nodes = root.xpath("/samlp:AuthnRequest/ds:Signature", namespaces=NS_MAP)
# No signatures, no verifier configured -> decode xml directly

View file

@ -6,6 +6,7 @@ from lxml import etree # nosec
from authentik.core.tests.utils import create_test_cert, create_test_flow
from authentik.lib.tests.utils import get_request
from authentik.lib.xml import lxml_from_string
from authentik.managed.manager import ObjectManager
from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider
from authentik.providers.saml.processors.assertion import AssertionProcessor
@ -44,7 +45,7 @@ class TestSchema(TestCase):
request_proc = RequestProcessor(self.source, http_request, "test_state")
request = request_proc.build_auth_n()
metadata = etree.fromstring(request) # nosec
metadata = lxml_from_string(request)
schema = etree.XMLSchema(etree.parse("xml/saml-schema-protocol-2.0.xsd")) # nosec
self.assertTrue(schema.validate(metadata))
@ -65,7 +66,7 @@ class TestSchema(TestCase):
response_proc = AssertionProcessor(self.provider, http_request, parsed_request)
response = response_proc.build_response()
metadata = etree.fromstring(response) # nosec
metadata = lxml_from_string(response)
schema = etree.XMLSchema(etree.parse("xml/saml-schema-protocol-2.0.xsd"))
self.assertTrue(schema.validate(metadata))

View file

@ -4,6 +4,7 @@ from django.test import RequestFactory, TestCase
from lxml import etree # nosec
from authentik.core.tests.utils import create_test_cert, create_test_flow
from authentik.lib.xml import lxml_from_string
from authentik.sources.saml.models import SAMLSource
from authentik.sources.saml.processors.metadata import MetadataProcessor
@ -24,7 +25,7 @@ class TestMetadataProcessor(TestCase):
)
request = self.factory.get("/")
xml = MetadataProcessor(source, request).build_entity_descriptor()
metadata = etree.fromstring(xml) # nosec
metadata = lxml_from_string(xml)
schema = etree.XMLSchema(etree.parse("xml/saml-schema-metadata-2.0.xsd")) # nosec
self.assertTrue(schema.validate(metadata))

View file

@ -55,13 +55,11 @@ show_missing = true
[tool.pylint.master]
disable = [
"arguments-differ",
"no-self-use",
"fixme",
"locally-disabled",
"too-many-ancestors",
"too-few-public-methods",
"import-outside-toplevel",
"bad-continuation",
"signature-differs",
"similarities",
"cyclic-import",