Python 2.7.14が2017/9/16にリリースされました。Pythonの開発はバージョン3系に移行しており、2系はセキュリティ修正のみのリリースになっています。とは言ってもモジュールの変更を見るとバグフィックスやドキュメント修正も含まれているようです。
Python 2.7.14のリリースはソフトウェアセキュリティの基本を学ぶには良い題材になります。
Python 2.7.14リリースノート
モジュールまで含めると多くなりすぎるので、コアと組み込み機能の更新のみ取り上げます。バグフィックスの説明だけでは修正の中身が判らない物には注釈を入れています。
Core and Builtins
—————–– bpo-30657: Fixed possible integer overflow in PyString_DecodeEscape.
Patch by Jay Bosamiya.– bpo-27945: Fixed various segfaults with dict when input collections are
mutated during searching, inserting or comparing. Based on patches by
Duane Griffin and Tim Mitchell.– bpo-25794: Fixed type.__setattr__() and type.__delattr__() for
non-interned or unicode attribute names. Based on patch by Eryk Sun.
(注:コードの変更を見ると、メモリ不足の際の処理が不十分。工夫すると攻撃が可能かも?)– bpo-29935: Fixed error messages in the index() method of tuple and list
when pass indices of wrong type.
(注:タイプコンフュージョンと言われる脆弱性)– bpo-28598: Support __rmod__ for subclasses of str being called before
str.__mod__. Patch by Martijn Pieters.
(注:入力チェック漏れにより、呼ぶべき関数が呼ばれていない問題に見えます。タイプコンフュージョン?)– bpo-29602: Fix incorrect handling of signed zeros in complex constructor for
complex subclasses and for inputs having a __complex__ method. Patch
by Serhiy Storchaka.
(注:これは純粋にバグフィックスの様ですが、基本的演算に影響するので修正されたようです)– bpo-29347: Fixed possibly dereferencing undefined pointers
when creating weakref objects.– Issue #14376: Allow sys.exit to accept longs as well as ints. Patch
by Gareth Rees.
(注:コードが意図しない型を終了コードに渡すと、正常終了のように見えてしまう。一種のタイプコンフュージョンと言える)– Issue #29028: Fixed possible use-after-free bugs in the subscription of the
buffer object with custom index object.– Issue #29145: Fix overflow checks in string, bytearray and unicode.
Patch by jan matejek and Xiang Zhang.– Issue #28932: Do not include <sys/random.h> if it does not exist.
(注:ビルドバグ修正)
バッファーオーバーフロー、整数オーバーフロー、タイプコンフュージョン、解放後のメモリアクセス、未定義ポインターの利用、どれもPHPのバグでもお馴染のバグです。そして、これらの問題を利用して、任意コード実行などの不正な処理を行わせることが可能であることもお馴染です。
コアのわかった部分だけでもコレだけの脆弱性が隠れていた事実は受け入れざるを得ません。つまり同様の問題は言語コアの部分のみでなく、3系を含め、モジュールやライブラリのコードにも隠れていることを前提とした対応が必要ということです。1
これらの脆弱性への攻撃をどうやって防止するのか?
一言でいうと、セキュアコーディングの第一の習慣 ー 入力バリデーションしておく、です。
参考:
バッファーオーバーフロー、整数オーバーフロー、タイプコンフュージョン、解放後のメモリアクセス、未定義ポインターの利用、これらの脆弱性に対する攻撃を入力バリデーションで完全に防止できない場合もあります。しかし、多くの場合は効果的に機能します。
広く、長く使われているから、といって無条件でソフトウェアを信頼すべきではありません。
入力バリデーションは自分が書いたソフトウェアが”正しく動作”する為に必要な処理ですが、自分が書いていないソフトウェアの”未知の脆弱性の緩和策”として効果があります。
このため、CERT、OWASP、SANS、MITRE、ISOといったセキュリティ標準やガイドラインでは必ず「入力は全てバリデーションするように」と要求/推奨しています。
最近ではこれらのセキュリティ機関の1つにIPAも加わりました。(解説におかしな部分がありますが、まだ指摘していません。指摘したらブログにします)
簡単かつ基礎的な事なのですが、入力バリデーションが要求/推奨通り出来ているソフトウェア/プログラムが圧倒的少数派です。セキュリティ専門家の中にも「入力バリデーションはセキュリティ対策ではない!」と主張していた方も少なからず居た(まだ居る?)ので仕方ない事なのかも知れませんが・・・
Pythonだけの問題!?
Pythonだけがこういった問題を持っているのではないです。結構バッファーオーバーフローは修正されています。例えば、Rubyの2016/09/13 のこの修正です。
差分だけ見ると整数オーバーフローに対する対策が無かった問題を修正したように見えます。しかし、Rubyの脆弱性一覧
には2016年頃にはこの修正が紹介されていません。Trunkだけの問題?リファクタリング?詳しく見ていないので状況が理解できていないのですが、掲載漏れでしょうか?
- } - if (!rb_enc_asciicompat(enc)) { - len += strlen(nonascii_suffix) - rb_strlen_lit("%s"); - len += strlen(enc->name); + + if (clen > LONG_MAX - len) { + rb_raise(rb_eRuntimeError, "string size too big"); + } + len += clen; }
こういうコードがあるのでリファクタリングではないように見えます。これはたまたま購読しているRubyのコミットログMLで気になったのでブックマークしておいた物です。
Gitで見てみると、Ruby 2.3のブランチには
commit 840a4573af4477f699714030d7f5191796d591d7
Author: nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Fri Jul 1 19:09:29 2016 +0000merge revision(s) 55427: [Backport #12503]
* string.c (tr_trans): consider terminator length and fix heap
overflow. reported by Guido Vranken <guido AT guidovranken.nl>.commit e117afcb70719022a362b0ae3433dddc1944def5
Author: nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Wed Jun 15 16:05:04 2016 +0000merge revision(s) 55054: [Backport #12390]
* string.c (rb_str_modify_expand): check integer overflow.
[ruby-core:75592] [Bug #12390]
といった感じで別(?)のオーバーフローで出てきます。Rubyのコードは時々一部を読むのですが、全体を解っている訳ではないので、コミットログだけ見ているだけだとよく解らないです。
取り敢えず、ゼロトラストは重要です。
参考:
- 状況は言語や環境を問わず同じである、と考える必要があります。どれも大きくは変わりません。 ↩