Skip to content

Fix issue that occurs when using bytes as secret key. #890

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 7, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions debug_toolbar/panels/sql/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from django.core.exceptions import ValidationError
from django.db import connections
from django.utils.crypto import constant_time_compare
from django.utils.encoding import force_text
from django.utils.encoding import force_bytes
from django.utils.functional import cached_property

from debug_toolbar.panels.sql.utils import reformat_sql
Expand Down Expand Up @@ -79,12 +79,10 @@ def reformat_sql(self):
return reformat_sql(self.cleaned_data['sql'])

def make_hash(self, data):
items = [data['sql'], data['params']]
# Replace lines endings with spaces to preserve the hash value
# even when the browser normalizes \r\n to \n in inputs.
items = [' '.join(force_text(item).splitlines()) for item in items]
return hmac.new(settings.SECRET_KEY.encode('utf-8'),
''.join(items).encode('utf-8'), hashlib.sha1).hexdigest()
m = hmac.new(key=force_bytes(settings.SECRET_KEY), digestmod=hashlib.sha1)
for item in [data['sql'], data['params']]:
m.update(force_bytes(item))
return m.hexdigest()

@property
def connection(self):
Expand Down
2 changes: 1 addition & 1 deletion tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

# Quick-start development settings - unsuitable for production

SECRET_KEY = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
SECRET_KEY = bytes(bytearray([i for i in range(256)]))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check the ticket you linked again (https://code.djangoproject.com/ticket/24994). They've closed the ticket without making any changes, referencing a comment I left to them (see django/django#7510).

Also note, the Django docs already recommended the use of external files for storing the SECRET_KEY, in which case it's reasonable to expect the SECRET_KEY be bytes, given the multiple ways files can be opened in Python (as bytes). See https://docs.djangoproject.com/en/stable/howto/deployment/checklist/#secret-key .

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

open defaults to reading in text mode, which means that the snippet from the documentation returns text, not binary, which negates your point.

I can see the case for putting bytes in SECRET_KEY, especially now that the system check PR in Django has been closed. OTOH as Aymeric said it's not established practice, so please try submitting a documentation patch to Django saying bytes as SECRET_KEY is supported, and maybe even recommended. I don't see why DDT has to move first (especially since, with the rest of your changes, your use case will work perfectly).

Thanks!


INTERNAL_IPS = ['127.0.0.1']

Expand Down