Djangoの脆弱性CVE-2019–6975について解説

Ryuji Tsutsui
CreditEngine Tech
Published in
4 min readFeb 14, 2019

こんにちは。筒井です。今日は、2019年2月11日のリリースで修正されたDjangoの脆弱性CVE-2019–6975について解説します。

今回の脆弱性はDoS攻撃に悪用される可能性があります

Django公式サイトのリリース記事については以下を参照してください。
https://www.djangoproject.com/weblog/2019/feb/11/security-releases/

影響を受けるバージョン

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

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

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

  • Django 1.11.19
  • Django 2.0.11
  • Django 2.1.6

脆弱性の内容

django.utils.numberformat.format()関数は、Decimal型の巨大な値を受け取るとメモリ使用量が通常より増大します。悪用すればDoS攻撃が可能です。
django.utils.numberformat.format()関数は以下で使われています。

  • django.contrib.admin に属するコード
  • floatformat フィルター
  • filesizeformat フィルター
  • intcomma フィルター

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

では、Django 1.11.18でサンプルプロジェクトを作成し、 python manage.py shell で以下コードを実行してみましょう。

>>> from django.utils.numberformat import format
>>> from decimal import Decimal
>>> number = Decimal('9e9999')
>>> format(number, ".", grouping=3, thousand_sep=",", force_grouping=True) # 出力結果は長いので間を「...」で省略
'9,000,000,000,000,000,000,000,.........................,000'

かなり長い文字列が出力されました。
次に、Django 1.11.20にアップデートして同じコードを実行してみましょう。
(2019年2月14日現在、1.11.19はPyPIに公開されてなかったので、1.11.20を使いました)

>>> from django.utils.numberformat import format
>>> from decimal import Decimal
>>> number = Decimal('9e9999')
>>> format(number, ".", grouping=3, thousand_sep=",", force_grouping=True)
'9e+9999'

今度は数字が指数表記 9e+9999に変換されるようになりました。

どのように修正されたか

django.utils.numberformat.format()関数に渡される入力値が以下の条件すべてに一致するときに、指数表記に変換されるようになりました。

  • 型がDecimal
  • 整数部分と小数部分の桁数の合計が200超

具体的な変更内容は以下のGitHubコードを参照してください。

--

--

Ryuji Tsutsui
CreditEngine Tech

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