セキュアプログラミング・コーディング”だけ”でセキュアなプログラムが作れない理由

(Last Updated On: 2018年8月8日)

記事を探すことができなかったのですが、少し前に元記事が英語で日本語訳された記事に「セキュアプログラミング・コーディングはハイプ(誇大な宣伝)である」とする記事がありました。これには全く賛同できません。

なぜセキュアプログラミング”だけ”でセキュアなプログラムが作らないのか?理由を考えてみたいと思います。

そもそもセキュアプログラミングが普及しているのか?

セキュアプログラミングが提唱されてから久しいです。ここではセキュアプログラミングの歴史を詳しく紹介しないのでセキュアプログラミング(防御的プログラミング)の歴史をざっと振り返るを参照してください。

セキュアプログラミングはもう四半世紀も提唱されています。それでも効果が出ていないのだから、セキュアプログラミングに効果がない!と結論づけるのは拙速です。どんな良い薬でも飲んでいなければ効果が出ないように、どんな良い方法論でも実践していなければ効果はありません。

私の印象では海外の開発者にはそこそこ浸透しているように感じますが、日本の開発者には全くと言ってよいほど浸透していないように思えます。

 

そもそもセキュアプログラミングとは?

セキュアプログラミング標準は色々なところで標準化されていると思います。開発プロジェクト毎に標準を定めている所もあるでしょう。最も有名なセキュアプログラミング標準はCERTセキュアコーディング標準だと思います。

セキュアプログラミング標準は「安全なコードを書くためのベストプラクティスとアンチパターン集」の体裁を持っています。これはCERTセキュアコーディングのCコーディング標準を見ると一目瞭然です。

 

セキュアプログラミングで脆弱性(セキュリティ問題)を防げない最大の原因

そもそもセキュアプログラミング自体が実践されていない、という現状は無視するとしてもセキュアプログラミング標準を実践する”だけ”ではセキュアなプログラムは作れません

セキュアプログラミング標準は「安全なコードを書くためのベストプラクティスとアンチパターン集」の体裁である、と紹介しました。CERTのCコーディング標準は網羅的かつ詳細にセキュアなコードを書くためのベストプラクティスとアンチパターンを紹介していますが、これだけでは十分ではありません。

これはCERT Top 10 Secure Coding Practicesを見れば一目瞭然です。

  1. 入力をバリデーションする
  2. コンパイラの警告に用心する
  3. セキュリティポリシーの為に構成/設計する
  4. 簡易にする
  5. デフォルトで拒否する
  6. 最小権限の原則を支持する
  7. 他のシステムに送信するデータを無害化する
  8. 縦深防御を実践する
  9. 効果的な品質保証テクニックを利用する
  10. セキュアコーディング標準を採用する

「セキュアコーディング標準を採用する」は最後に記載されています。つまり、セキュアプログラミングを行う為のセキュアコーディング標準より上位の施策の方が重要であるということです。

セキュアプログラミングを全く知らない方々だとは思いますが、個人的には1番目の「入力バリデーションをする」を真っ向否定する経験豊富な開発者は勿論、セキュリティ専門家の方々にまで出会っています。7番目の「他のシステムに送信するデータを無害化する」為に必須のエスケープを教えることが有害であるとする方々も居ました。こういう状況からすると、セキュアコーディング標準だけではなくセキュアコーディングの基本的な考え方され全く理解されていない可能性が高いことを意味していると考えるのが自然です。ITセキュリティに関わる方々でさえこうなのですから、一般の開発者に浸透しているとは到底思えません。(少なくとも日本は)

 

個別のテクニックだけでは安全なコードを書けなくて当たり前

セキュアプログラミング標準は「安全なコードを書くためのベストプラクティスとアンチパターン集」で網羅的に作られるべきですが、本質的に「パッチワーク」に成らざるを得ません。パッチワークになるとは、つまり全体の対策として機能しづらく、部分部分の局所最適化になることを意味します。

せキュティ対策には全体最適化が欠かせません。一つ一つが正しいことであっても部分最適化の積み重ねでは合成の誤謬が発生します。

全体最適化を行うにはコード全体の安全性を維持するための基本的な考え方が重要です。CERT Top 10 Secure Coding Practicesの1位から9位が全体最適化を行う為の基本的な考え方です。

CERTのTop 10でも十分抽象的/基本的な考え方で全体をカバーしているかも知れませんが、それより更にもう一段階基礎的な物を含めた方が良いのでは?と思い セキュアプログラミングの7つ習慣を考えてみました。この7つの習慣はISO27000/ISMSへの対応も考えてリストアップしています。

  1. ゼロトラストを実践する
  2. 信頼境界線を意識する
  3. 入力の正しさを検証する
  4. 出力の正しさを確実にする
  5. 想定外のエラーで停止する
  6. システムのイベントを記録する
  7. 秘密であるべき情報を秘密にする

CERT Top 10 Secure Coding Practicesでは「ゼロトラストを実践する」や「信頼境界線を意識する(境界防御)」は当たり前過ぎて項目として挙げていないのでは?と考えています。CERTの10のプラクティスとこの7つ習慣の基本的な考え方を理解した上で、セキュアコーディング標準を知り、利用すると全体最適化の効果ができると思います。

 

別の理由 – セキュリティ対策の定義

別の理由として「セキュリティ対策の定義」があります。CERT Top 10 Secure Coding Practicesで挙げているような対策が浸透しない理由、セキュリティ対策の根本的な勘違いが起きる理由は「セキュリティ対策の定義」にもあります。

ISO27001の定義ではセキュリティ対策は以下のように定義されています。

2.71
リスク対応
リスクを変化 (2.61)させる為のプロセス(2.54)

ノート 1
リスク対応には以下の項目を含める事ができる:

  •  リスクを発生させる活動を開始しない、または継続しないことを決断することによりリスクを回避する
  • 機会を獲得する為にリスクを選択または増加させる
  • リスクの原因を排除する
  • 発生の頻度を変える
  • 結果を変える
  • 他の組織(契約企業やリスクの資金的処理を含む 訳注:保険など)とリスクを共有し
  • 見聞のある選択によりリスクを抑える

ノート 2
否定的な結果をもたらす事象のリスク対応は、”リスク緩和策”、”リスク排除策”、”リスク防止策”、”リスク削減策”などと呼ばれる事がある
ノート 3
リスク対応は新しいリスクを生成したり、既存のリスクを変更することができる

セキュリティ対策とは緩和策、排除策、防止策、削減策と呼ばれる事がある、としています。ISOの定義では「否定的な結果をもたらす事象の対応」に留まらず、リスクを増やす対応もセキュリティ対策です。(例えば、パスワードのみによる認証は、他の優れた認証方法よりリスクを増加されるセキュリティ対策だがセキュリティ対策)

大雑把に言うとセキュリティ対策は緩和策、排除策、防止策、削減策ですが、排除策、防止策だけに限る、と定義されている方が少なからず居ます。

 

まとめ

セキュアコーディング標準”だけ”では部分対策です。全体対策が必要なプログラムの作成で、期待する効果が発揮できないは当然と言えます。

セキュアプログラミング/コーディングは”基礎的な考え方”を理解してから行いましょう!

「入力バリデーションはセキュリティ対策ではない」とか「エスケープをどうこう考えるのは古臭い」※ などと主張するのは「私はプログラミングのセキュリティを全く理解していません」と言うのと同じです。もしこのような主張をされてきたのなら「セキュリティ対策とは何か?」(参考)という基本的な概念から考え直した方が良いです。

※ 特にWebはテキストI/Fの塊なので 参考1参考2

投稿者: yohgaki