【问题标题】:Django/Auth: Can request.user be exploited and point to other user?Django/Auth:request.user 可以被利用并指向其他用户吗?
【发布时间】:2013-03-27 01:01:27
【问题描述】:

假设我有一个表单在数据库中执行某些操作并需要通过 POST 发送的用户身份验证,是否有可能在 request 内部某个邪恶的人更改 用户为了利用系统?

以下示例在数据库中创建一个项目,但需要登录用户。有人可以在 request.user 中发送其他用户的数据吗?

from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from items_core.models import Item
from items.forms import CreateItemForm
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
@login_required
def create(request):
    errors = None
    if request.method == 'POST':
        form = CreateItemForm(request.POST)
        if form.is_valid():
            try:
                Item.objects.get(
                    name = form.cleaned_data['name'],
                    user = request.user
                    )
                errors = 'Item already exist. Please provide other name.'
            except Item.DoesNotExist:
                Item.objects.create(
                    name = form.cleaned_data['name'],
                    user = request.user
                    )

                return redirect('items:list')

        form = CreateItemForm()
    else:
        form = CreateItemForm()

    template = {
        'form':form, 
        'items':Item.objects.filter(user=request.user),
        'request':request,
        'errors':errors
        }

    return render(request, 'items/item_create.html', template)

谢谢!

【问题讨论】:

    标签: django security django-authentication authentication http-post


    【解决方案1】:

    request.user 对象属于 SimpleLazyObject 类型,由 auth middleware 添加到请求对象中。

    SimpleLazyObject(LazyObject):用于延迟包装类的实例化 在请求实际登录用户时,get_user 方法被调用。

    def get_user(request):
        if not hasattr(request, '_cached_user'):
            request._cached_user = auth.get_user(request)
        return request._cached_user
    

    这里,auth.get_user() 会反过来验证这种方式:

    backend_path = request.session[BACKEND_SESSION_KEY]
    backend = load_backend(backend_path)
    user = backend.get_user(user_id) or AnonymousUser()
    

    因此,如果request.user 对象被篡改,则此验证将失败,因为会话数据验证将失败

    【讨论】:

    • 响应对象中不也是传入user对象,这样模板就可以访问了吗?由于安全问题,有没有办法让我不传递用户对象?
    • @user1050619 在中间件中,您可以执行以下操作:del response['user']。还要确保删除相应的上下文处理器。更多信息在这里:docs.djangoproject.com/en/1.9/ref/request-response
    【解决方案2】:

    request 上的user 属性,即request.userAuthenticationMiddleware 设置。 process_request 这个中间件内部使用了get_user() 由 django auth 系统提供,在django.contrib.auth.__init__.py 中定义。

    这个get_user() 使用django session 并且django session 内部使用cookies。 Django 会话使用key 作为sessionid 的cookie。

    因此,假设恶意用户获取了合法用户的 cookie 并将此 cookie 发送到服务器,服务器将认为请求来自合法用户,并以合法用户身份登录。但由于请求是由恶意用户发送的,他现在可以访问合法用户的资源。

    【讨论】:

      猜你喜欢
      • 2020-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-24
      • 2020-04-29
      • 1970-01-01
      • 2021-06-16
      相关资源
      最近更新 更多