feat: use hmac, sha256, and a better secret for published nomcom hashes. (#4475)
* feat: use hmac, sha256, and a better secret for published nomcom hashes. * fix: avoid using django secret key for a different secret context * fix: Only strip the newline * fix: improve readability by using rstrip
This commit is contained in:
parent
5d6f1e7509
commit
5c8545eecb
|
@ -1,9 +1,11 @@
|
|||
# Copyright The IETF Trust 2012-2020, All Rights Reserved
|
||||
# Copyright The IETF Trust 2012-2022, All Rights Reserved
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
import base64
|
||||
import datetime
|
||||
import hashlib
|
||||
import hmac
|
||||
import os
|
||||
import re
|
||||
import tempfile
|
||||
|
@ -101,8 +103,7 @@ def get_user_email(user):
|
|||
return user._email_cache
|
||||
|
||||
def get_hash_nominee_position(date, nominee_position_id):
|
||||
return hashlib.md5(('%s%s%s' % (settings.SECRET_KEY, date, nominee_position_id)).encode('utf-8')).hexdigest()
|
||||
|
||||
return hmac.new(settings.NOMCOM_APP_SECRET, f"{date}{nominee_position_id}".encode('utf-8'), hashlib.sha256).hexdigest()
|
||||
|
||||
def initialize_templates_for_group(group):
|
||||
for template_name in DEFAULT_NOMCOM_TEMPLATES:
|
||||
|
@ -165,6 +166,8 @@ def delete_nomcom_templates(nomcom):
|
|||
nomcom_template_path = '/nomcom/' + nomcom.group.acronym
|
||||
DBTemplate.objects.filter(path__contains=nomcom_template_path).delete()
|
||||
|
||||
def command_line_safe_secret(secret):
|
||||
return base64.encodebytes(secret).decode('utf-8').rstrip()
|
||||
|
||||
def retrieve_nomcom_private_key(request, year):
|
||||
private_key = request.session.get('NOMCOM_PRIVATE_KEY_%s' % year, None)
|
||||
|
@ -173,8 +176,13 @@ def retrieve_nomcom_private_key(request, year):
|
|||
return private_key
|
||||
|
||||
command = "%s bf -d -in /dev/stdin -k \"%s\" -a"
|
||||
code, out, error = pipe(command % (settings.OPENSSL_COMMAND,
|
||||
settings.SECRET_KEY), private_key)
|
||||
code, out, error = pipe(
|
||||
command % (
|
||||
settings.OPENSSL_COMMAND,
|
||||
command_line_safe_secret(settings.NOMCOM_APP_SECRET)
|
||||
),
|
||||
private_key
|
||||
)
|
||||
if code != 0:
|
||||
log("openssl error: %s:\n Error %s: %s" %(command, code, error))
|
||||
return out
|
||||
|
@ -185,8 +193,13 @@ def store_nomcom_private_key(request, year, private_key):
|
|||
request.session['NOMCOM_PRIVATE_KEY_%s' % year] = ''
|
||||
else:
|
||||
command = "%s bf -e -in /dev/stdin -k \"%s\" -a"
|
||||
code, out, error = pipe(command % (settings.OPENSSL_COMMAND,
|
||||
settings.SECRET_KEY), private_key)
|
||||
code, out, error = pipe(
|
||||
command % (
|
||||
settings.OPENSSL_COMMAND,
|
||||
command_line_safe_secret(settings.NOMCOM_APP_SECRET)
|
||||
),
|
||||
private_key
|
||||
)
|
||||
if code != 0:
|
||||
log("openssl error: %s:\n Error %s: %s" %(command, code, error))
|
||||
if error:
|
||||
|
|
|
@ -6,6 +6,7 @@ import datetime
|
|||
import re
|
||||
from collections import OrderedDict, Counter
|
||||
import csv
|
||||
import hmac
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
|
@ -695,7 +696,7 @@ def private_questionnaire(request, year):
|
|||
|
||||
|
||||
def process_nomination_status(request, year, nominee_position_id, state, date, hash):
|
||||
valid = get_hash_nominee_position(date, nominee_position_id) == hash
|
||||
valid = hmac.compare_digest(get_hash_nominee_position(date, nominee_position_id), hash)
|
||||
if not valid:
|
||||
permission_denied(request, "Bad hash!")
|
||||
expiration_days = getattr(settings, 'DAYS_TO_EXPIRE_NOMINATION_LINK', None)
|
||||
|
|
|
@ -1272,6 +1272,8 @@ if SERVER_MODE != 'production':
|
|||
|
||||
if 'SECRET_KEY' not in locals():
|
||||
SECRET_KEY = 'PDwXboUq!=hPjnrtG2=ge#N$Dwy+wn@uivrugwpic8mxyPfHka'
|
||||
if 'NOMCOM_APP_SECRET' not in locals():
|
||||
NOMCOM_APP_SECRET = b'\x9b\xdas1\xec\xd5\xa0SI~\xcb\xd4\xf5t\x99\xc4i\xd7\x9f\x0b\xa9\xe8\xfeY\x80$\x1e\x12tN:\x84'
|
||||
|
||||
ALLOWED_HOSTS = ['*',]
|
||||
|
||||
|
|
Loading…
Reference in a new issue