logo

Hidden fields manipulation - Python


Need

Prevention of unauthorized manipulation of hidden fields


Context

  1. Usage of Python 3 for developing applications and scripts
  2. Usage of Django for building web applications

Description

Insecure Code Example

from django import forms

class UserProfileForm(forms.Form):
    username = forms.CharField()
    secret_key = forms.CharField(widget=forms.HiddenInput())

def user_profile(request):
    if request.method == 'POST':
        form = UserProfileForm(request.POST)
        if form.is_valid():
            user = User.objects.get(username=form.cleaned_data['username'])
            user.secret_key = form.cleaned_data['secret_key']
            user.save()
    else:
        form = UserProfileForm()
    return render(request, 'edit_profile.html', {'form': form})

The above code is a Django form that is used to edit a user profile. The form contains a hidden field `secret_key` which is not visible to the regular user on the front end. However, this hidden field can be manipulated by a malicious user to change the value of `secret_key` for a particular user. When the form is submitted, the `user_profile` view function gets the `POST` data, validates the form and if it's valid, it gets the user object and updates the `secret_key` with the value from the form. This means that if a malicious user manipulates the `secret_key` in the form data, it will be saved in the database, potentially causing undesired behaviors in the application, such as unauthorized access or data corruption. This vulnerability, known as Hidden Field Manipulation, is a serious security risk as it allows an attacker to modify hidden form data before it's sent to the server, potentially leading to unauthorized access or modification of sensitive data.

Steps

  1. Remove the secret_key field from the form. It should not be editable from the client side.
  2. If the secret_key needs to be updated, create a separate function or method that handles this process securely on the server side.
  3. Ensure that only authorized users can update sensitive information. Implement proper authentication and authorization checks.
  4. Consider using Django's built-in User model for handling user data, which includes many security features.
  5. Always validate and sanitize user input to prevent other types of attacks.

Secure Code Example

from django import forms
from django.contrib.auth.decorators import login_required

class UserProfileForm(forms.Form):
    username = forms.CharField()

@login_required
def user_profile(request):
    if request.method == 'POST':
        form = UserProfileForm(request.POST)
        if form.is_valid():
            user = User.objects.get(username=form.cleaned_data['username'])
            if user == request.user:
                user.save()
            else:
                return HttpResponseForbidden("You are not allowed to edit this user.")
    else:
        form = UserProfileForm()
    return render(request, 'edit_profile.html', {'form': form})

def update_secret_key(user):
    # This is a server-side function to update the secret_key
    # Add your own logic here
    pass

The updated code removes the `secret_key` field from the `UserProfileForm`. This field should not be editable from the client side as it can lead to security vulnerabilities. The `user_profile` view now includes the `@login_required` decorator, which ensures that only authenticated users can access this view. Inside the `user_profile` view, we check if the user trying to update the profile is the same as the logged-in user. If not, a `HttpResponseForbidden` is returned, preventing unauthorized users from updating other users' profiles. A new function `update_secret_key` is added. This function should contain the logic to update the `secret_key` securely on the server side. This function should only be called from trusted server-side code, not from client-side code. Remember to always validate and sanitize user input to prevent other types of attacks. Django's form system provides a lot of built-in validation, but you should always add your own specific checks as needed.


References

  • 093 - Hidden fields manipulation

  • Last updated

    2023/09/18