ソフトウェア開発において開発者はセキュリティ問題を自己解決できるのか?それとも自己解決できないのか?どちらが正しいのか考えてみます。
開発者はセキュリティ問題を自己解決できない
開発者はセキュリティ問題を自己解決できないことを前提とした場合
- 全ての開発者に安全な処理の基礎知識を教えるのは無理である
- 従って、開発者には「安全に処理する作法」を教えてそれを守らせる
といった方針になります。
”特定の処理”に関する安全性を向上させるにはこのアプローチは効果的です。開発者は何故ソフトウェアに脆弱性が発生するのか考える必要がないこともメリットです。
例えば、SQLクエリのパラメータによりSQLインジェクションを防ぐには、全てのパラメータをプリペアードクエリのパラメータとしてSQL文からデータを分離すると教えて守らせる、JavaScriptにパラメータを渡したい場合は安全なHTMLデータとして保存し安全なDOM操作を利用してJavaScriptコードとデータを分離すると教えて守らせる、などがあります。
このアプローチのデメリットは”特定の処理”に関する安全性しか向上できないこと、開発者が何故ソフトウェアに脆弱性が発生するのか”考えない”ことです。
ソフトウェア開発で実装しなければならない処理は多様です。新規開発もあれば、既存システムのメンテナンスもあります。異る言語やフレームワークでソフトウェア開発を行うことは当たり前にあります。特定のSQL操作やJavaScriptのデータ受け渡しは上記の作法で安全性を維持可能ですが、全ての処理に一般化することは困難です。
アプリケーション開発者ではなくフレームワークやライブラリ自体を改造/作成する開発者などの場合、この前提条件ではソフトウェア開発は行なえません。しかし、開発を始めたばかりの開発者に必要な知識全てを教えることも困難です。
開発者はソフトウェアのセキュリティ問題を自己解決できる
開発者はソフトウェアのセキュリティ問題を自己解決できることを前提とした場合
- 開発者に安全な処理の基礎知識を教えることは可能であり効果がある
- 従って、開発者には「安全に処理する基本」を教えて自分で考える
となります。
ソフトウェアは「入力→処理→出力」の基本構造を持っています。Webアプリケーションのセキュリティ問題のほとんどは”入力”と”出力”で発生しています。これはWebアプリケーションが利用するインターフェースが”命令とデータを持つテキストインターフェース”を持っていて、安全に出力しないと”不正な命令”を”挿入”(インジェクション)できる事が原因です。インジェクション問題の基礎知識を持っているだけで、実際に発生しているセキュリティ問題(JavaScriptインジェクション、SQLインジェクション、コマンドインジェクション、XPathインジェクション、LDAPインジェクション、その他)の8割から9割に対応できます。
現在では、フレームワークやセキュリティライブラリ、セキュアなAPIのお陰でインジェクションについてあまり考えなくても一定のセキュリティレベルを保てるようになっています。Webアプリケーションを作り始めたばかりの開発者が知っておくべき基礎知識を知らなくても、ある程度の品質のアプリケーションを作れるようになっています。
しかし、インジェクションの基礎知識はHTML5による脅威など、新しい脅威にも応用が効く知識です。技術的な進歩が速いWebでは基礎知識は欠かせません。フレームワークを本体やコンポーネントを作ったり、改造する場合、ライブラリを作る場合にも基礎知識は必須です。フレームワークやセキュリティライブラリを利用していても、前提条件や例外があることもしばしばあります。そしてその前提条件や例外が明確にドキュメント化されておらず、ソースコードで実装を確認できるスキルが必要であることも多くあります。
どちらのアプローチを採用すべきか?
「開発者はセキュリティ問題に対して自己対応できる、できない、どちらの前提を採用すべきでしょうか?」
この問いかけ自体が間違っています。どちらも適材適所で採用すべきです。
開発規約やフレームワーク/ライブラリを作っている場合、開発者はセキュリティ問題に自己対応できない(開発者は間違える)とする前提で作るべきです。開発者にセキュリティ教育を行う場合、開発者は自己対応できる(自分でセキュリティ対策を考えられる)を前提に教育すべきです。どちらも必要です。
フレームワークの使い方を教育する場合、その作法を教えるのは当たり前です。セキュリティの教育をする時、セキュリティ問題が発生する理由と対策を教えるのは当たり前です。どちらも必要です。
まとめ
セキュリティの議論をしていると、時々議論が噛み合っていない、と感じる事があります。多くの場合、方法論と教育論との区別ができていないことが原因です。アプリケーション開発には手法からのアプローチは必須です。セキュリティ教育には論理からのアプローチが必須です。どちらもセキュアな開発には必要ですが、議論のテーマが異る場合には咬み合いません。
議論が噛み合わない原因がセキュリティの定義にあることもよくあります。セキュリティの定義については解説済みなのでここでは省略します。
セキュリティの議論をする場合、
- セキュリティの定義を明確にする(ISO27000のrisk treatment)
- 方法論なのか教育論なのか明確にする
を行うとスムースな議論が行えます。方法論/教育論は「実践の話と基礎の話」とも言えると思います。セキュリティの定義が異なっていると議論にはなりません。何かおかしいな?と思ったらセキュリティの定義について確認すると良いでしょう。
論理自体に間違いが無い限り、方法論/教育論のどちらかの議論が間違っている、ということはありません。どちらも間違っていないのに、間違っている、とすると建設的な議論になりません。こうならないよう注意するとよいと思います。
最後に、私は開発者の皆さんはほとんどのセキュリティ問題を自己解決できる、と考えています。入出力のセキュリティは、暗号理論などとは異り、それほど難しい物ではありません。
参考
Leave a Comment