From 919b433847da11058840a51e93b29955e2ea5978 Mon Sep 17 00:00:00 2001 From: Brian Wilson Date: Fri, 30 May 2014 18:34:49 -0400 Subject: [PATCH] Encrypt the session id before writing to tracking logs. --- common/djangoapps/track/middleware.py | 20 +++++++++++++++++-- .../djangoapps/track/tests/test_middleware.py | 4 ++-- common/djangoapps/track/views.py | 11 +++------- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/common/djangoapps/track/middleware.py b/common/djangoapps/track/middleware.py index e32ee9d4ac..2f7e9eb80b 100644 --- a/common/djangoapps/track/middleware.py +++ b/common/djangoapps/track/middleware.py @@ -1,3 +1,5 @@ +import hmac +import hashlib import json import re import logging @@ -111,12 +113,26 @@ class TrackMiddleware(object): ) def get_session_key(self, request): - """Gets the Django session key from the request or an empty string if it isn't found""" + """ Gets and encrypts the Django session key from the request or an empty string if it isn't found.""" try: - return request.session.session_key + return self.encrypt_session_key(request.session.session_key) except AttributeError: return '' + def encrypt_session_key(self, session_key): + """Encrypts a Django session key to another 32-character hex value.""" + if not session_key: + return '' + + # Follow the model of django.utils.crypto.salted_hmac() and + # django.contrib.sessions.backends.base._hash(), but use MD5 + # so that the result has the same length (32) as the original + # session_key. + key_salt = "common.djangoapps.track" + self.__class__.__name__ + key = hashlib.sha1(key_salt + settings.SECRET_KEY).digest() + encrypted_session_key = hmac.new(key, msg=session_key).hexdigest() + return encrypted_session_key + def get_user_primary_key(self, request): """Gets the primary key of the logged in Django user""" try: diff --git a/common/djangoapps/track/tests/test_middleware.py b/common/djangoapps/track/tests/test_middleware.py index 1f4dd3b499..3c9a43b181 100644 --- a/common/djangoapps/track/tests/test_middleware.py +++ b/common/djangoapps/track/tests/test_middleware.py @@ -117,10 +117,10 @@ class TrackMiddlewareTestCase(TestCase): SessionMiddleware().process_request(request) request.session.save() session_key = request.session.session_key - + expected_session_key = self.track_middleware.encrypt_session_key(session_key) context = self.get_context_for_request(request) self.assert_dict_subset(context, { - 'session': session_key, + 'session': expected_session_key, }) def test_request_headers(self): diff --git a/common/djangoapps/track/views.py b/common/djangoapps/track/views.py index b3b8cb3998..69be4a37cc 100644 --- a/common/djangoapps/track/views.py +++ b/common/djangoapps/track/views.py @@ -41,18 +41,13 @@ def user_track(request): except: username = "anonymous" - try: - scookie = request.META['HTTP_COOKIE'] # Get cookies - scookie = ";".join([c.split('=')[1] for c in scookie.split(";") if "sessionid" in c]).strip() # Extract session ID - except: - scookie = "" - page = request.REQUEST['page'] with eventtracker.get_tracker().context('edx.course.browser', contexts.course_context_from_url(page)): + context = eventtracker.get_tracker().resolve_context() event = { "username": username, - "session": scookie, + "session": context.get('session', ''), "ip": _get_request_header(request, 'REMOTE_ADDR'), "event_source": "browser", "event_type": request.REQUEST['event_type'], @@ -61,7 +56,7 @@ def user_track(request): "page": page, "time": datetime.datetime.utcnow(), "host": _get_request_header(request, 'SERVER_NAME'), - "context": eventtracker.get_tracker().resolve_context(), + "context": context, } log_event(event)