Ryuji Tsutsui
Jan 7 · 4 min read

明けましておめでとうございます。筒井@ryu22eです。今年もよろしくお願いします。
さて、年明け早々に何ですが、今回の記事はDjangoの脆弱性の話です。2019年1月4日のリリースで修正されたCVE-2019–3498について解説します。

Django公式サイトのリリース記事については以下を参照してください。
Django security releases issued: 2.1.5, 2.0.10, and 1.11.18 | Weblog | Django

影響を受けるバージョン

以下のバージョンが影響を受けます。

  • Django master branch
  • Django 1.11
  • Django 2.0
  • Django 2.1

以下のバージョンで修正されています。

  • Django 1.11.18
  • Django 2.0.10
  • Django 2.1.5

脆弱性の内容

handler404 がデフォルト値のdjango.views.defaults.page_not_found()の場合、404ページに攻撃者が偽装したコンテンツを挿入することができます。
自分で書いたビューを指定している場合は、「 request.pathをURLエンコードせずにテンプレート上で表示させる」というコードになっていないか注意してください。
判断が難しければ、後述の「脆弱性を利用した攻撃の例」を参考に検証してください。
該当する場合は、後述の「どのように修正されたか」を参考に自分でコードを修正してください。

脆弱性を利用した攻撃の例

実際にサンプルコードを作って試してみましょう。この記事では Django==1.11.17 を使っています。

まず、django-admin startproject でプロジェクトを作成します。
ローカル環境でもデフォルトの404ページを表示させるために、 DEBUG には FalseALLOWED_HOSTS には ['*'] を設定してください。あとは ./manage.py migrate && ./manage.py runserver で開発サーバーを立ち上げます。

404ページは以下のように表示されるはずです。

URLの部分をちょっと工夫すると、以下のように表示させることができます。あまりいい例文が思いつかなかったのですが、 %20 をスペースとして表示できるので、工夫次第で自然な文章が作れそうです。

どのように修正されたか

デフォルトの404ページに「URLの一部が画面上に表示される」という仕様が廃止されました。先述のサンプルコードをDjango 1.11.18で動かしてみると、以下のように表示されます。

また、表示に使われていたコンテキスト変数 request_pathrequest.pathの内容が入っている)はURLエンコードされるようになり、 %20はそのまま %20として表示されるようになりました。
もし、テンプレートファイルだけ入れ替えて request_pathを使うようにしても、偽装コンテンツを挿入されることはありません。
実際のコードは以下のリンクを参照してください。

CreditEngine Tech

Credit Engine Tech Blog

Ryuji Tsutsui

Written by

はい

CreditEngine Tech

Credit Engine Tech Blog

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade