Djangoで開発する際にセキュリティについて気をつけること
Webアプリケーションを製作するときに、セキュリティについて気をつけなきゃいけないことはいろいろありますが、使用するフレームワークによって何を気にしなければいけないか、何を気にしなくてもいいのかは変わってきます。そこでDjangoでは何を考えなければいけないかを様々なセキュリティリスクについて見てみます。なお、Djangoのバージョンは1.0alpha2とします。
SQLインジェクション
SQLインジェクションは、DjangoのO/Rマッパーを使っている限り、SQL文中の変数は自動的にエスケープされるので気にする必要はありません。DjangoのO/Rマッパーはよくできているので、生のSQLクエリを発行することはあまりないかと思われますが、生のSQLを使う際もプレースホルダを利用すれば問題なく処理されます。
余談ですが、SQLのLIKE演算子を使うときも、O/Rマッパーを使ってフィールドを照合する際に__contains,__startswith,__endswithを使えばワイルドカードである'%'と'_'を自動的にエスケープされるので、パーセント記号とアンダースコアが含まれていることを気にしなくても大丈夫です。
クロスサイトスクリプティング(XSS)
Djangoのテンプレートシステムには、デフォルトで自動エスケープが組み込まれており、"<"(小なり), ">"(大なり), "'"(シングルクオート),'"'(ダブルクオート),"&"(アンパサンド)は、それぞれ"<", ">", "'", """, "&"に変換されます。言ってしまえば力技ですが、おかげでほとんど気にせずにテンプレートを書くことができます。
逆に安全なHTMLをエスケープせずに出力したいときは
{{ html|safe }}
とsafeフィルタを使うか、
{% autoescape off %} {{ some_html }} {{ other_html }} {% endautoescape %}
のようにautoescapeタグで囲えばそのまま出力されます。
URLにユーザーが入力する文字列が含まれるURLを逆引きを使わずに作るときは、django.utils.http.urlquoteを使って
from django.utils.http import urlquote url = '/person/%s/' % urlquote(username)
というようにしなければいけません。
クロスサイトリクエストフォージェリ(CSRF)
CsrfMiddlewareクラスを使うと、レスポンスに含まれるすべてのフォームに、セッションIDとシークレット文字列から作られたハッシュをhiddenフィールドとして追加します。そして、すべてのPOSTリクエストに対して、ハッシュが一致するかどうかをチェックし、そのリクエストが正規のフォームから作られたものであるかを確認することで、不正なリクエストを排除することができます。
セッションハイジャック
DjangoのSessionMiddlewareを使えば、問題ないでしょうきっと。なおDjangoのセッション管理では、セッションIDのやりとりにクッキーのみを使います。
やる気がなくなって来た感が否めません。
フォームのパラメータ改ざん
適当なforms.〜Fieldを使っていれば、フィールドごとにバリデートされるのできっと大丈夫。
ディレクトリトラバーサル
ユーザーにファイルをアップロードさせるときは気をつけたほうがいいかもね。
バッファオーバーラン
この対策は大変そうだね。わかんない。