Djangoの脆弱性CVE-2019–12308・CVE-2019–11358について解説

Ryuji Tsutsui
CreditEngine Tech
Published in
7 min readJun 7, 2019

こんにちは。筒井です。今日は、2019年6月3日のリリースで修正されたDjangoの脆弱性CVE-2019–12308(AdminURLFieldWidget XSS)・CVE-2019–11358(Prototype pollution)について解説します。

今回の脆弱性は2点あります

Django公式サイトのリリース記事については以下を参照してください。

影響を受けるバージョン

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

【CVE-2019–12308: AdminURLFieldWidget XSS】

  • Django master development branch
  • Django 2.2 before version 2.2.2
  • Django 2.1 before version 2.1.9
  • Django 1.11 before version 1.11.21

【CVE-2019–11358: Prototype pollution】

  • Django master development branch
  • Django 2.2 before version 2.2.2
  • Django 2.1 before version 2.1.9

脆弱性の内容

【CVE-2019–12308: AdminURLFieldWidget XSS】

AdminURLFieldWidget から生成されるリンクにXSS脆弱性があります。AdminURLFieldWidgetURLField を使ったモデルをadminで扱う際に使われるウィジェットです。

【CVE-2019–11358: Prototype pollution】

admin用にバンドルされているjQuery(3.4.0未満)に脆弱性があります。
jQuery.extend(true, {}, …)にユーザーからの入力値を渡すことで Object.prototypeを汚染し、任意のプロパティの挙動を書き換えたり、新しいプロパティを追加することができます。
以下jQuery公式ブログの解説も併せて参照してください。

この脆弱性はadmin用にバンドルされているJavaScriptライブラリ select2を使っている場合にも影響があります。

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

以下で紹介するサンプルコードはDjango 2.2.1を使っています。

【CVE-2019–12308: AdminURLFieldWidget XSS】

まず、posts アプリケーションに以下のコードを書きます。

postsアプリケーションのソースコード

次に、予め shellコマンドで以下のデータを作っておきます。
( URLValidator を使っていない入力フォームを作ってブラウザから登録してもいいです)

>>> from posts.models import Post
>>> Post.objects.create(title='テスト', content='テストテストテスト', url='javascript:alert(\'XSS\');')
<Post: テスト>

postsに対してchangeの権限を持った管理者ユーザーでadminにログインし、上記で作ったデータの編集画面を開いてください。URLの欄に現在の値が表示されているはずです。

赤枠の部分にXSS脆弱性があります

赤枠の部分は本来はURLをブラウザで開くためのリンクですが、JavaScriptコードが埋め込まれているので、アラートが実行されます。

リンクをクリックした結果

また、新規登録画面でURLを javascript:alert('XSS'); にすると、入力エラーにはなりますが、 先述の例と同様にクリック時にアラートが表示されるリンクが表示されます。
(もっとも、この画面は入力者本人にしか表示されないので、これを攻撃に利用するには、かなり条件が限られてくるでしょう)

赤枠の部分にXSS脆弱性があります

【CVE-2019–11358: Prototype pollution】

ModelAdmin.autocomplete_fieldsselect2 を使っているので、内部で使っているjQuery.extend(true, {}, …) にユーザーからの入力値を渡せば攻撃できるはずですが、具体的な例を見つけられませんでした。
JavaScriptのカスタマイズを行っている、かつ select2jQuery を利用している場合は攻撃が成立する可能性はあります。

攻撃例の代わりに、adminで脆弱なjQueryが使われているか確認する方法を載せます。
ChromeのJavaScriptコンソールやFirefoxの開発ツールを使って、http://127.0.0.1:8000/admin/auth/user/の画面上で以下のコードを実行してください。脆弱なjQueryを使っているなら true が表示されます。
(つまり、 {} に本来存在しないはずのプロパティ test が追加されている)

django.jQuery.extend(true, {},
JSON.parse('{"__proto__": {"test": true}}')
);
console.log( "test" in {} );

どのように修正されたか

【CVE-2019–12308: AdminURLFieldWidget XSS】

AdminURLFieldWidget にコンテキスト変数 url_valid が追加され、以下のルールで値が設定されるようになりました。

  • 入力値がURLValidatorでエラーにならない→ True を設定
  • 入力値がURLValidatorでエラーになる→ False を設定

また、AdminURLFieldWidget のレンダリング用に使われているテンプレートファイルでは、 url_validTrue の場合のみリンクが表示されるようになりました。
実際の変更内容は以下を参照してください。

【CVE-2019–11358: Prototype pollution】

keyが __proto__の値はマージ対象から外すように変更されました。
jQuery自体のバージョンを上げたわけではなく、該当部分にパッチを当てただけのようです。

実際の変更内容は以下を参照してください。

--

--

Ryuji Tsutsui
CreditEngine Tech

私がmediumに記事を書くことはおそらく当分ないので、 https://ryu22e.org/ の方を読んでください。