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 import xmlsec
from defusedxml import ElementTree from defusedxml import ElementTree
from lxml import etree # nosec
from structlog.stdlib import get_logger 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.exceptions import CannotHandleAssertion
from authentik.providers.saml.models import SAMLProvider from authentik.providers.saml.models import SAMLProvider
from authentik.providers.saml.utils.encoding import decode_base64_and_inflate from authentik.providers.saml.utils.encoding import decode_base64_and_inflate
@ -95,7 +95,7 @@ class AuthNRequestParser:
verifier = self.provider.verification_kp verifier = self.provider.verification_kp
root = etree.fromstring(decoded_xml) # nosec root = lxml_from_string(decoded_xml)
xmlsec.tree.add_ids(root, ["ID"]) xmlsec.tree.add_ids(root, ["ID"])
signature_nodes = root.xpath("/samlp:AuthnRequest/ds:Signature", namespaces=NS_MAP) signature_nodes = root.xpath("/samlp:AuthnRequest/ds:Signature", namespaces=NS_MAP)
# No signatures, no verifier configured -> decode xml directly # 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.core.tests.utils import create_test_cert, create_test_flow
from authentik.lib.tests.utils import get_request from authentik.lib.tests.utils import get_request
from authentik.lib.xml import lxml_from_string
from authentik.managed.manager import ObjectManager from authentik.managed.manager import ObjectManager
from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider
from authentik.providers.saml.processors.assertion import AssertionProcessor 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_proc = RequestProcessor(self.source, http_request, "test_state")
request = request_proc.build_auth_n() 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 schema = etree.XMLSchema(etree.parse("xml/saml-schema-protocol-2.0.xsd")) # nosec
self.assertTrue(schema.validate(metadata)) self.assertTrue(schema.validate(metadata))
@ -65,7 +66,7 @@ class TestSchema(TestCase):
response_proc = AssertionProcessor(self.provider, http_request, parsed_request) response_proc = AssertionProcessor(self.provider, http_request, parsed_request)
response = response_proc.build_response() 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")) schema = etree.XMLSchema(etree.parse("xml/saml-schema-protocol-2.0.xsd"))
self.assertTrue(schema.validate(metadata)) self.assertTrue(schema.validate(metadata))

View File

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

View File

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