Django/Auth:request.user是否存在被利用指向其他用户的漏洞?

6

假设我有一个表单,它在数据库中执行某些操作,并需要通过POST发送用户身份验证,那么在request内部是否可能被某个恶意人士更改user以便利用系统?

下面的示例在数据库中创建一个项目,但需要已登录的用户。是否可以在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)

谢谢!

2个回答

7

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 对象被篡改,此验证将失败,因为会话数据验证会失败。

用户对象不是也通过响应对象传递,以便可以通过模板访问吗?有没有一种方法可以由于安全问题而不传递用户对象? - user1050619
在中间件中,您可以这样做:del response['user']。还要确保删除相应的上下文处理器。更多信息请参见此处:https://docs.djangoproject.com/en/1.9/ref/request-response/ - karthikr

5
request中的user属性,即request.user是由AuthenticationMiddleware设置的。该中间件的process_request内部使用了Django认证系统提供的get_user(),该函数在django.contrib.auth.__init__.py中定义。
get_user()使用Django会话,而Django会话内部使用cookies。 Django会话使用一个名为sessionid的cookie作为key
因此,假设恶意用户获得了合法用户的cookie并将该cookie发送到服务器,则服务器将认为该请求来自合法用户并将登录为合法用户。但是由于请求是由恶意用户发送的,他现在可以访问合法用户的资源。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接