首页 > 解决方案 > 您如何保护 django 隐藏输入表单免受恶意攻击?

问题描述

假设我在模板中呈现了以下表单:

# Form
class CandidatTourForm(models.ModelForm):
    class Meta:
        model = Candidat
        fields = [
            "email", #charField
            "first_name", #charField
            "last_name", #charField
            "dossier", #foreignKey
        ]

# parent Model
class Candidat(models.Model):
    email = models.EmailField()
    first_name = models.CharField(max_length=64, blank=True, null=True)
    last_name = models.CharField(max_length=64, blank=True, null=True)
    dossier = models.ForeignKey(Dossier, on_delete=models.CASCADE)

这是一种古典形式,没有什么花哨的。该dossier字段是隐藏的输入。

def candidat_form_tour(request, dossier_uuid, candidat_id):
    dossier = get_object_or_404(Dossier, uuid=dossier_uuid)
    candidat = get_object_or_404(Candidat, id=candidat_id, dossier__uuid=dossier_uuid)
    if request.method == "GET":
        form = CandidatTourForm(instance=candidat,)
    elif request.method == "POST":
        form = CandidatTourForm(request.POST)
        if form.is_valid() and assertDataIsLegit(form._meta.model): # see below
            candidat = form.save()
            return redirect(
                "main:document_tour", dossier_uuid=dossier_uuid, candidat_id=candidat_id
            )
    return render(
        request,
        "candidature/candidat_form_tour.html",
        {
            "form": form,
            "candidat": candidat,
            "dossier_uuid": dossier_uuid,
        },
    )

当我使用 POSTMAN 测试此视图并将与在 GET 请求中收到的表单无关的 dossier_id 时,候选人被保存到错误的档案中。

我想像这样创建一个辅助函数

def assertDataIsLegit(_object, _id, _id2):
    _type = type(_object)
    instance = _type.objects.get(id=_id)
    return instance.id == _id2

并调用它来验证 post 请求发回的 dossier id 是否与原始 dossier 匹配:

if form.is_valid() and assertDataIsLegit(form._meta.model, dossier.id, form.cleaned_data['dossier']):
   #do stuff save and all

但我很确定存在更好的方法。我已经查看了表单的clean方法,但是由于我需要验证相关数据,我不确定这是不是好方法。

你将如何防止这种情况?我知道您不应该信任发送的数据并对其进行验证。你会在视图函数中验证它吗?在表单方法中?欢迎任何线索!

标签: pythondjangodjango-forms

解决方案


推荐阅读