ネタもと:「サニタイズ言うなキャンペーン」とは何か 要約版:「サニタイズ言うなキャンペーン」とは
基本的に賛成なのですが、「「じゃあなんと言えばいいのか」って?」のほうかな?
「やるべきことをやろうよ」この一言で終わるのでは?
例えば、C 言語のプログラマは、文字列で "¥" 円マークを使うとき、必ずチェックするでしょう。例えば Windows 系でパスを記述するときです。これを“サニタイズ”という人はいないでしょう。
同じように、入力が「何に対して使われるのか」を把握して、使われる先で「どの様に解釈されるのか」を考えれば、サニタイズといわれている処理の多くは、「やるべきことをやっていない」から必要なのではないでしょうか。または、そこに「どんな入力が許されるべきなのか」を考え、まずは「許されない入力を弾く」ことで、危険性の多くは除去できるのではないでしょうか。
例えば、SQL Injection の例として、次のようなコードをよく見かけます(高木さんのサイトに書かれているのではなく、記事へのリンク/トラックバックを参照していて見かけた)。
string sql = "SELECT COUNT(*) FROM USERTABLE WHERE NAME = '" + name + "' AND PASSWORD = '" + pass + "'";
// SQL 文を実行する処理があって
...
if (count > 0) {
// ログイン成功の処理
...
} else {
// ログイン失敗の処理
...
}
これ、とっても不思議なのです。ここで行わなければならない処理は、「ユーザ名とパスワードが一致したデータベースエントリ数を数える」ことですか?「入力されたユーザ名とパスワードが一致する、データベースエントリを取り出す」ことじゃないですか?せめて「count == 1」となっていれば、少なくとも NAME が一致しなければログインできません。例としてあわてて作ったものであって、いつもこのように作っているわけではないと、信じたいです。
[追記]
なお、SQL Injection の危険性は、任意のログイン名でログイン可能である、ということだけではありません。任意の SQL 文を実行可能であるという危険性があります。これは、テーブルの一覧を表示したり、内容を書き換えたり、テーブルを削除してシステムを破壊することが出来る、ということです。
また、ログイン時に「ログイン名」と「パスワード」を入力させ、ログイン名が間違っているときに「ログイン名が違います」「登録されているログイン名ではありません」というメッセージを表示するシステムがあります。なるほど、「ログイン名」と「パスワード」のどちらを間違っているのかわからせ、親切かもしれません。しかし、これによって「正当なログイン名を知ることができる」という脆弱性を作り込んでいます。
ログイン名が「メールアドレス」と等しく、かつ「ログイン名が違います」というメッセージを表示するシステムの場合、総当たり攻撃により、システムに登録されているメールアドレスの一覧が取得可能になります。
また、「ログイン名」ではなく「メールアドレス」と表示しているシステムもあります。このシステムでは、「ログイン名」と「パスワード」という、本来なら2つの不定長文字列を推測しなければならないのに、一方をメールアドレスという(おそらく)公開されている文字列であると公開しています。このため、1つの不定長文字列を推測するだけでよいので、やはり脆弱性であるといえます。
この脆弱性は、ログイン部分だけに存在するわけではありません。パスワードを忘れてしまったユーザに新しいパスワードを発行する機能がある場合、「秘密の質問」に対する答えを入力させて本人確認をするシステムと、メールアドレスを入力させてパスワードを通知するシステムがあります。後者の場合、「入力されたメールアドレスは登録されていません」などのメッセージを表示しているなら、同じ脆弱性を含んでいることになります。
[/追記]
例えば、「年齢」を入力する箇所に、"[^0-9]"(十進で数字以外) が入力されると、それは入力値としておかしいはずです。数字でも、3桁…200とかが入力されるのはおかしいでしょう。また、場合によっては1桁もおかしいでしょう。「名前」を入力する欄に、ピリオドやローマ数字など一部の記号以外の記号、特に ">" などが入力されるのは、入力値としておかしいはずです。そういった「入力としておかしな値」を、ユーザに確認する前にチェックするのは、「ユーザの入力ミスを防ぐ」為に必要なことではないでしょうか。「備考」であるなら、あるいは ">" などの記号を入力できるようにするでしょう。しかし、ここで入力できるのは、「表示するもの」であって、「動作させるもの」ではないはずです。そうであれば、C 言語における文字列中の "¥" のように、通常の文字として扱われるように変換しておかなければなりません。
これらは「セキュリティ対策」でも、まして「サニタイズ」でもなく、「やるべきことをやる」ただそれだけのことではないでしょうか。
投稿日時 : 2006年1月5日 21:27