Skip to content

Commit

Permalink
Add support for using utf8 compatible keys (#109)
Browse files Browse the repository at this point in the history
* Add support for using utf8 compatible keys

- Change: cache key arguments accept utf8 strings

* Improve testcase readability

---------

Co-authored-by: Bruno Souza <[email protected]>
  • Loading branch information
brnosouza and Bruno Souza authored Jul 25, 2024
1 parent 1eefb84 commit bc5429b
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
12 changes: 10 additions & 2 deletions security/auth_throttling/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import hashlib
import logging
import time
import urllib.parse
from math import ceil

from django.contrib.auth import REDIRECT_FIELD_NAME
Expand Down Expand Up @@ -43,15 +44,22 @@ def delay_message(remainder):
return _("%d seconds") % ceil(remainder)


def _to_ascii_compatible(value: str):
if not value.isascii():
value = urllib.parse.quote(value)

return value


def _key(counter_type, counter_name):
"""
We store a hashed version of the key because what we generate can be
too long, and it's possible the POST data we get could contain characters
that memcache doesn't like.
"""
key = "security.authentication_throttling.%s:%s" % (
counter_type,
counter_name,
_to_ascii_compatible(counter_type),
_to_ascii_compatible(counter_name),
)
return hashlib.sha256(key.encode("ascii")).hexdigest()

Expand Down
19 changes: 18 additions & 1 deletion tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from security.auth_throttling import Middleware as AuthThrottlingMiddleware
from security.auth_throttling import (attempt_count, default_delay_function,
delay_message, increment_counters,
reset_counters)
reset_counters, throttling_delay)
from security.middleware import (BaseMiddleware,
ContentSecurityPolicyMiddleware,
DoNotTrackMiddleware,
Expand Down Expand Up @@ -1071,3 +1071,20 @@ def test_improper_configuration_raises(self):
"REFERRER_POLICY",
"invalid",
)


class UnicodeDataTests(TestCase):
USERNAME = "ñoñó1234"
IP_ADDRESS = "127.0.0.1"

def test_unicode_data_in_cache_key(self):
self._execute_with_unicode_data(self.USERNAME, self.IP_ADDRESS)

def _execute_with_unicode_data(self, username, ip):
try:
increment_counters(username=username, ip=ip)
reset_counters(username=username, ip=ip)
throttling_delay(username=username, ip=ip)
attempt_count(attempt_type="auth", id=username)
except Exception:
self.fail("Unicode data not allowed")

0 comments on commit bc5429b

Please sign in to comment.