C言語の最も重要なセキュリティの基本ルールは「メモリをきっちり管理する」です。もちろん他にもプログラミングをする上で注意しなればならない事は山ほどありますが、C言語でプログラミングする上で最も基本的なセキュリティのルールは「正確なメモリ管理」です。
Webアプリを作る上でのセキュリティの基本ルールは何でしょうか?
今回はWebアプリセキュリティはもっとシンプルに考えよう!という話です。
Webセキュリティの基本ルールは正確なテキスト管理
C言語で最も重要なセキュリティの基本ルールは「正確なメモリ管理」です。セキュリティの基本である「正確なメモリ管理」がされていないと「不正なコードをインジェクションされ実行」されてしまいます。不正なコードを実行されることはシステムの乗っ取られる事を意味します。
1つの間違いでサーバーを乗っ取られる可能性があるC言語でWebアプリ開発は危険すぎます。今どきはC言語でWebアプリを作ることはまずありません。C言語の基本ルールである「正確なメモリ管理」ができていない場合、簡単にWebアプリサーバーを乗っ取られるからです。Webアプリ開発には「正確なメモリ管理」が必要ないLL系、Java系、.NET系の言語が利用されるので、「正確なメモリ管理」は基本ルールではなくなりました。
Webアプリセキュリティの基本ルールは「正確なテキスト管理」です。
Webアプリは基本的にテキスト型インターフェースを扱うアプリケーションです。
- HTML/CSS
- JavaScript/JSON
- HTTP
- SQL
- XML/XPath
- LDAP
- SMTP
- OSコマンド
- ファイル名
これらは全てテキストを扱う仕組みです。
「セキュリティは難しい」とよく耳にしますが、ロジックのバグ、設定・仕様のバグやDoSセキュリティ問題以外は「攻撃用のテキストをインジェクションする攻撃」です。上記のテキスト型インターフェースに対する攻撃はそれぞれ以下のようになります。
- HTMLインジェクション
- JavaScriptインジェクション(XSS)
- HTTPヘッダーインジェクション(HTTPヘッダースレスポンスプリッティング)
- SQLインジェクション
- XMLインジェクション
- XPathインジェクション
- LDAPインジェクション
- メールヘッダーインジェクション
- OSコマンドインジェクション
- ヌル文字インジェクション(他には “../” インジェクションなど)
Webアプリの脆弱性情報を見ると、これらの脆弱性が大多数を占めています。これら全ては「正確なテキスト管理」が出来ていなかった事が原因のセキュリティ問題です。
C言語で「正確なメモリ管理」が出来ていないと「不正なコードをインジェクションされ攻撃」される事と同じように、Webアプリでは「正確なテキスト管理」が出来ていないと「不正なテキストをインジェクションされ攻撃」されます。
難解なパズルを解くような攻撃手法、例えば、HTTPヘッダレスポンススプリッティングも単純に言えば「改行をインジェクションする事により、不正なテキストをブラウザ/プロキシーにインジェクションする攻撃」です。
基本ルールは変えられない
「Webアプリのセキュリティ対策にはAPIを使えば良い」としている方も居ますが、APIを使う事によって基本ルールが変わる事はありません。
C言語でメモリ管理を自動で行うライブラリだけ使っていれば「正確なメモリ管理」を知らなくてもOKとはならにように、Webアプリがテキスト管理を自動で行ってくれるライブラリ/フレームワークを使っていれば「正確なテキスト管理」を知らなくてもOKとはなりません。
基本ルールを変えるには、「正確なメモリ管理」が必要ない言語に乗り換えた時に「自由なメモリ操作」を禁止したように、「正確なテキスト管理」が必要なくなるよう、プロトコルやHTMLなどのテキストを直接操作できる仕組みを無くす(使えなくする)必要があります。
中途半端なセキュリティに頼るのは危険
不完全な物を完全であるかのように教える事は非常に危険です。「アンチウイルスソフトを入れているから安全」と教えて自由にパソコンを使用させて安全でしょうか?
現在では、多くのWebアプリ開発環境(フレームワーク)ではHTTP/SMTPプロトコルを直接操作しなくても良いレベルくらいまでにはなっています。しかし、それはあくまでフレームワークが「直接操作をしなくても良い仕組み」を提供しているだけです。どのWebアプリ開発環境でもプラットフォームとなる言語がテキストの直接操作をサポートしているので「テキストを直接操作」できます。一部の機能に「直接操作しなくても良い仕組み」があっても、その一部の機能の「直接操作しなくても良い仕組み」でさえほとんどの場合不完全です。(例:プリペアードクエリ、ORM、エスケープ関数でさえ不完全な場合もある)
「メモリを直接操作しないライブラリ」を使っているからといって、C言語プログラマに「APIだけ使えばOK」など教育する人は居ないでしょう。Webアプリ開発でも同じ事が言えます。
「自由なテキスト処理」が可能である以上、仮に「テキストの直接操作が一切不要」で優れたフレームワークを使っていたとしても「APIだけ使えばOK」と教育する事は間違っています。現実にはそのようなフレームワークは無いです。もし存在しても利用するのはプログラムが作れないエンドユーザーくらいで、Web開発者は利用しないでしょう。
それ以前の問題として現在存在するフレームワークで「テキストの直接操作が一切不要」なフレームワークを聞いたことがありません。「テキストを直接操作しないAPI ”も” あるから、そのAPIを使っていればOK」と教育し「正確なテキスト管理」を教えない事は教育上の明らかな瑕疵だと思います。四則演算を教えずに、電卓の使い方を教える学校や先生が居たらそれが間違っている事と同じです。
Webプログラマは自由にテキストを書き込めます。だからこそ進化の速いWebシステムでも必要に応じて新しい機能をどんどん取り込めます。自由にテキストを書き込める状況は少なくと当分の間変わる見込みはありません。Webプログラマに「正確なテキスト管理」が必要であると伝えることはセキュリティ関係者の責務と言って良いと思います。
正確なテキスト管理を行う設計・手法
正確なテキスト管理を行う設計は エンジニア必須の概念 – 契約による設計と信頼境界線、方法は入力と出力を確実に管理することにより実現できます。入力はバリデーションを行い、出力は出力先に合わせた適切なエスケープ、API利用、バリデーションを行います。基本的にはこれだでです。
このブログでは「正確なテキスト管理」に必要となる具体的な手法もPHP Securityカテゴリのエントリなどで解説しています。まだまだ十分ではないので今後も追加していきます。Facebook/Twitter/Google+にも投稿しているのでフォローして頂ければご覧いただけます。
まとめ
最後に私が確認したIPAのSQLインジェクション対策はプリペアードクエリ型、つまりAPI型でプログラマによる「正確なテキスト操作」が必要ない手法のみを紹介していました。基本ルールである「正確なテキスト操作」については一切触れていませんでした。これは根本的に間違っています。
- 基本ルールを変えるにはプラットフォーム自体の変更が必要(例:CからLL,Java,.NET)
- プラットフォームの変更なしのルール変更は無謀
- 細かい事は後でも構わないが「基本ルール」(正確なテキスト管理)は必ず教える
最後の項目はWebアプリプログラマに対するセキュリティ教育には必須だと思います。
C言語のメモリ管理の問題を攻撃する手法には色々複雑な手法、あっと驚くような手法があります。しかし、Cプログラマはそれらの攻撃手法に精通している必要なく「正確なメモリ管理」を行う方法さえ知っていて実践していればそれで構いません。
Webアプリの場合、「正確なテキスト管理」を行う方法さえ知っていれば◯◯インジェクション攻撃の手法に精通している必要はありません。
最初に「Webアプリセキュリティはもっとシンプルに考えよう!という話です」と書きました。
◯◯インジェクションと聞いて何だか難しそうな感じがするかも知れないですが、単純に「正確なテキスト管理」が出来ていなかった、というだけの話です。
SANS/CWE TOP 25で「怪物的なセキュリティ対策」の第一位に「確実な入力の処理」、第二位に「確実な出力の処理」を挙げているのは、言い換えると「正確なテキスト管理」をしてください、になります。
つまり、Webアプリセキュリティ問題のほとんどが「正確なテキスト管理」(入力・出力の確実な制御)で防げるのです!既にWeb開発を何年かやっている方なら、明確に意識していなくても解っていた事だと思います。これからWeb開発に関わる方、まだ始めたばかりの方には伝えて頂けるようお願いします。
C言語では「正確なメモリ管理」が必要なように、Webアプリでは「正確なテキスト管理」が必要だということです。実行は難しいかも知れませんが、考え方は簡単です。
楽しく、セキュアにコーディングしましょう!
お知らせ: FacebookにPHP Securityのページを作りました。興味がある方は是非「いいね!」をお願いします。このブログのPHP Securityカテゴリの投稿もまとめられています。