如何保护Django隐藏输入表单免受恶意攻击?

2024-05-15 09:23:39 发布

您现在位置:Python中文网/ 问答频道 /正文

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

# 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请求中放置一个与表单中收到的文档id无关的文档id时,候选对象被保存到错误的文档中

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

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

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

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

但我很肯定有更好的方法。 我已经研究了表单的clean方法,但是因为我需要验证相关数据,所以我不确定这是一种好方法

你将如何防止这种情况?我知道你不应该信任发送的数据并验证它。 您能在查看功能中验证它吗?以一种形式方法? 欢迎任何线索


Tags: 方法nameformidtrue表单modelobject