Security controls bypass or absence - Session Invalidation - Python

Security controls bypass or absence - Session Invalidation - Python

Need

Implementation of proper session invalidation mechanisms

Context

  • Usage of Python 3 for writing and executing Python code
  • Usage of Django for building web applications

Description

Non compliant code

        from django.contrib.sessions.models import Session
from django.contrib.auth import get_user_model
User = get_user_model()

def get_user_main(session_key):
    session = Session.objects.get(session_key=session_key)
    user_id = session.get_decoded().get('_auth_user_id')
    user = User.objects.get(id=user_id)
    if 'auto' in session_key:
        return user.main
    return 'Access Denied'
        
        

In the above Python code using Django framework, a function get_user_main(session_key) is defined which accepts a session key as a parameter. This function is supposed to return the main of a user from his session code.

The function first fetches the session object from the session key. Then it retrieves the user id from the decoded session object. Using this user id, it fetches the user object.

The vulnerability lies in the conditional statement where it checks if the word 'auto' is in the session key. If it is, it returns the user's main, effectively bypassing any other security checks. This means that if a session key containing the word 'auto' is used, access is allowed to the user's main.

This is a serious security flaw as it allows unauthorized access to user's main by simply including the word 'auto' in the session key. This vulnerability can be exploited by an attacker to gain unauthorized access to user data.

The code was probably left in from the debugging phase, but it should have been removed or commented out before pushing the code to production.

Steps

  • Remove the debug code that allows access when the session key contains the word 'auto'. This is a security risk as it allows unauthorized access.
  • Implement proper session invalidation. When a user logs out or after a certain period of inactivity, the session should be invalidated to prevent unauthorized access.
  • Use secure session management. Django provides middleware for session security that should be used to prevent session hijacking or fixation.
  • Ensure that the session data is encrypted. This prevents an attacker from being able to read or modify the session data.
  • Implement access controls to ensure that only authorized users can access certain resources. This could be done using Django's built-in authentication and authorization features.

Compliant code

        from django.contrib.sessions.models import Session
from django.contrib.auth import get_user_model
from django.contrib.sessions.middleware import SessionMiddleware
from django.contrib.auth.decorators import login_required

User = get_user_model()

@login_required
def get_user_main(request, session_key):
    session = Session.objects.get(session_key=session_key)
    user_id = session.get_decoded().get('_auth_user_id')
    user = User.objects.get(id=user_id)
    if request.user != user:
        return 'Access Denied'
    return user.main
        
        

The updated code now includes several security measures to prevent unauthorized access and ensure secure session management.

1. Removal of Debug Code: The debug code that allowed access when the session key contained the word 'auto' has been removed. This prevents unauthorized access.

2. Session Invalidation: The @login_required decorator is used to ensure that the user is logged in to access the get_user_main function. If the user is not logged in, Django will redirect them to the login page. This decorator also takes care of session invalidation when the user logs out.

3. Secure Session Management: The SessionMiddleware is used to handle the session security. This middleware manages session expiration and ensures that the session cookie is secure.

4. Access Control: The function now checks if the user associated with the current session is the same as the user associated with the session key. If they are not the same, access is denied. This ensures that only authorized users can access the get_user_main function.

5. Session Data Encryption: Django's session framework automatically encrypts session data, preventing attackers from being able to read or modify it.

By implementing these measures, the application is now more secure and less vulnerable to unauthorized access and session hijacking or fixation.

References