プロジェクトの1つでDjangoの組み込みユーザーモデルを使用しています。もちろん、ユーザーは編集可能である必要があります。これが最も便利なソリューションなので、Django独自のUserChangeFormを使用してユーザー編集用のフォームを提供し始めました。UserChangeFormは、基本的にUserModelのModelFormであるため、Userモデルのすべてのフィールドを変更できます。
ユーザーがすべてのフィールドを変更できるようにしたくありません。したがって、私の最初のアイデアは、UserChangeForm全体をテンプレートに渡し、必要なフィールド(たとえば、「username」と「email」)のみをレンダリングすることでした。また、スーパーユーザーのみがユーザー名を変更できるようにしたいので、このフィールドはスーパーユーザーの場合にのみ表示されます。
基本的なコードは次のようになります。
ビュー機能
def edit_user(request, pk):
... #code to ensure not everyone can edit every user
user = User.objects.get(pk=pk)
if request.method == 'POST':
form = UserChangeForm(request.POST, instance=user)
if form.is_valid:
form.save()
... #redirect
else:
form = UserChangeForm(instance=user)
... # render template
テンプレートのフォーム
<form action="{{ request.path }}" method="post">
{% csrf_token %}
{% if user.is_superuser %}
{{ form.username }}
{% endif %}
{{ form.email }}
<button type="submit">Save</button>
</form>
さて、私の質問は次のとおりです。このソリューションのセキュリティ面はどうですか?攻撃者がスーパーユーザーでなくても、たとえばユーザー名フィールドを追加するのを防ぐために私は何もしません。それによって、彼はPOSTデータに追加のデータを入力し、それがview関数に送信され、Userオブジェクトを更新するために使用されます。元のUserChangeFormにはフィールド'is_superuser'も含まれているため、これは非常に危険です。
私は自分の疑いをテストするために自分でフォームをハックしてみました。通常のユーザーとしてログインし、開発者ツールを使用してユーザー名の入力を追加し、フォームを送信しました。結果は例外でした:
Traceback:
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/Library/Python/2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
20. return view_func(request, *args, **kwargs)
File "/Users/joker/Development/wiki2099/wiki2099/apps/accounts/views.py" in edit_user
69. form.save()
File "/Library/Python/2.7/site-packages/django/forms/models.py" in save
364. fail_message, commit, construct=False)
File "/Library/Python/2.7/site-packages/django/forms/models.py" in save_instance
74. " validate." % (opts.object_name, fail_message))
Exception Type: ValueError at /accounts/edit/12/
Exception Value: The User could not be changed because the data didn't validate.
それがこの種の攻撃が不可能なのか、それとも私が正しくやらなかったのかはわかりません。CSRFトークンはそのような種類のハッキングを防ぐことができると思いますが、ドキュメントにはその問題について何も見つかりませんでした。誰かが私を教えてもらえますか?攻撃者がレンダリングされていないフォームフィールドを使用するのを防ぐメカニズムはありますか?それはどのように機能しますか?
前もって感謝します!