events: improve sanitising for tuples and sets

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens Langhammer 2023-01-31 19:19:22 +01:00
parent 55782d3929
commit e5ba5d51fe
No known key found for this signature in database
2 changed files with 31 additions and 2 deletions

View file

@ -30,7 +30,7 @@ def cleanse_item(key: str, value: Any) -> Any:
"""Cleanse a single item""" """Cleanse a single item"""
if isinstance(value, dict): if isinstance(value, dict):
return cleanse_dict(value) return cleanse_dict(value)
if isinstance(value, list): if isinstance(value, (list, tuple, set)):
for idx, item in enumerate(value): for idx, item in enumerate(value):
value[idx] = cleanse_item(key, item) value[idx] = cleanse_item(key, item)
return value return value
@ -103,7 +103,7 @@ def sanitize_item(value: Any) -> Any:
return sanitize_dict(value) return sanitize_dict(value)
if isinstance(value, GeneratorType): if isinstance(value, GeneratorType):
return sanitize_item(list(value)) return sanitize_item(list(value))
if isinstance(value, list): if isinstance(value, (list, tuple, set)):
new_values = [] new_values = []
for item in value: for item in value:
new_value = sanitize_item(item) new_value = sanitize_item(item)

View file

@ -3,10 +3,12 @@ from django.contrib.auth.models import AnonymousUser
from django.core.cache import cache from django.core.cache import cache
from django.test import RequestFactory, TestCase from django.test import RequestFactory, TestCase
from django.urls import resolve, reverse from django.urls import resolve, reverse
from django.views.debug import SafeExceptionReporterFilter
from guardian.shortcuts import get_anonymous_user from guardian.shortcuts import get_anonymous_user
from authentik.core.models import Application, Group, User from authentik.core.models import Application, Group, User
from authentik.events.models import Event, EventAction from authentik.events.models import Event, EventAction
from authentik.lib.generators import generate_id
from authentik.policies.dummy.models import DummyPolicy from authentik.policies.dummy.models import DummyPolicy
from authentik.policies.expression.models import ExpressionPolicy from authentik.policies.expression.models import ExpressionPolicy
from authentik.policies.models import Policy, PolicyBinding from authentik.policies.models import Policy, PolicyBinding
@ -136,6 +138,15 @@ class TestPolicyProcess(TestCase):
request = PolicyRequest(self.user) request = PolicyRequest(self.user)
request.set_http_request(http_request) request.set_http_request(http_request)
request.context = {
"complex": {
"dict": {"foo": "bar"},
"list": ["foo", "bar"],
"tuple": ("foo", "bar"),
"set": {"foo", "bar"},
"password": generate_id(),
}
}
response = PolicyProcess(binding, request, None).execute() response = PolicyProcess(binding, request, None).execute()
self.assertEqual(response.passing, False) self.assertEqual(response.passing, False)
self.assertEqual(response.messages, ("dummy",)) self.assertEqual(response.messages, ("dummy",))
@ -151,6 +162,24 @@ class TestPolicyProcess(TestCase):
self.assertEqual(event.context["result"]["passing"], False) self.assertEqual(event.context["result"]["passing"], False)
self.assertEqual(event.context["result"]["messages"], ["dummy"]) self.assertEqual(event.context["result"]["messages"], ["dummy"])
self.assertEqual(event.client_ip, "127.0.0.1") self.assertEqual(event.client_ip, "127.0.0.1")
# Python sets don't preserve order when converted to list,
# so ensure we sort the converted set
event.context["request"]["context"]["complex"]["set"].sort()
self.assertEqual(
event.context["request"]["context"],
{
"complex": {
"set": [
"bar",
"foo",
],
"dict": {"foo": "bar"},
"list": ["foo", "bar"],
"tuple": ["foo", "bar"],
"password": SafeExceptionReporterFilter.cleansed_substitute,
}
},
)
def test_execution_logging_anonymous(self): def test_execution_logging_anonymous(self):
"""Test policy execution creates event with anonymous user""" """Test policy execution creates event with anonymous user"""