MITREがCWEを大幅更新 〜 セキュアコーディング対応を強化 〜
CWEはセキュアなソフトウェア開発を行う開発者にとっては欠かせない情報源です。2019年1月3日にCWE (Common Weakness Enumeration – 共通脆弱性タイプ) 3.2が公開されました。大幅更新と言える内容になっています。
この更新を一言で言うと「セキュアコーディング対応の強化」でしょう。
もっと読むCWEはセキュアなソフトウェア開発を行う開発者にとっては欠かせない情報源です。2019年1月3日にCWE (Common Weakness Enumeration – 共通脆弱性タイプ) 3.2が公開されました。大幅更新と言える内容になっています。
この更新を一言で言うと「セキュアコーディング対応の強化」でしょう。
もっと読む全ての入力データはバリデーション済み(またはバリデーション済みと信頼可能)であるため出力時にバリデーションを行うことに抵抗を感じる(≒ 省略したくなる)方も多いと思います。「同じ、ほぼ同じような処理を繰り返したくない」と感じるのは普通の開発者の感覚でしょう。
そこで「ファイルパスを安全に出力する方法」を考えてみます。
※ ここではUNIX系OSのファイルシステムを前提とします。安全なファイルパス出力からセキュアコーディングの考え方を紹介しています。
もっと読むセキュアコーディング原則において、インジェクション対策の為に重要な原則は
の2つです。これらに、一般的なプログラミング原則であるフェイルファースト原則とフェイルセーフ原則、ゼロトラストを適用するとセキュアコーディングになります。
簡単なSQLインジェクション対策コードを使ってセキュアコーディングの概念を紹介します。
セキュアコーディング/セキュアプログラミングの原則と技術は国際情報セキュリティ標準(ISO 27000)でも要求される技術です。しかし、根本から誤ったセキュリティ対策の概念が長年啓蒙されています。GDPR対策にもISO 27000は重要です。日本に於てもISO 27000が要求する基礎的対策ができていない場合、法的リスクが非常に高いと言わざるを得ません。
もっと読む世の中のソフトウェアには危険なコードが埋もれています。これがセキュリティ問題の原因になっています。なぜ危険なアプリケーションが書かれるのか?その仕組みを理解すると、対策が可能です。
もっと読む基本的にWebアプリへの入力データは全てバリデーションする必要があります。具体的には以下のような構造でバリデーションが必要です。
Webアプリへの入力データの種類は大抵の場合、数百程度です。Validate for PHPはこれらの入力仕様を定義すれば、アプリケーション内で繰り返し同じ入力仕様をバリデーションできるように作られています。
Validate for PHPのスクリプト版をPre Alphaとしてリリースします。このブログのGitHubリポジトリのリンクは0.7.0ブランチに向いています。開発版はmasterブランチを参照してください。
もっと読むAttack Surface (攻撃可能面=攻撃可能な箇所)の管理はセキュリティ対策の基本中の基本です。あまりに基本すぎてあまり語られていないように思います。
攻撃可能面を管理するには先ず攻撃可能な箇所がどこにあるのか分析(=リスク分析)します。その上でできる限り攻撃可能な箇所を削減(=リスク削減)します。攻撃可能面の分析と管理とはリスク分析と管理です。セキュリティ対策そのものと言える、基本的な管理です。
Attack Surface (攻撃可能面)
The attack surface of a software environment is the sum of the different points (the “attack vectors“) where an unauthorized user (the “attacker”) can try to enter data to or extract data from an environment.[1][2] Keeping the attack surface as small as possible is a basic security measure.
出典:Wikipedia
日本語訳すると以下のようになります。
もっと読むソフトウェア環境における攻撃可能面は不正なユーザー(攻撃者)がデータを攻撃対象に入力または取り出し可能な様々箇所(アタックベクター)の集合である。攻撃可能面を可能な限り小さくするのは基本的なセキュリティ対策である。
コンテクストを知る、はデータを安全に扱う為に必須の基礎知識です。
よくある致命的な脆弱性を作る考え方は
です。セキュリティ対策ではコンテクストが何であるのか?を正しく理解することが重要です。ここではコンテクストについて紹介します。
もっと読むPostgreSQLには
の文字列型があります。他にバイナリも保存できる
もあります。
text/byteaの最大サイズは1GiBだ、と私も思っていたのですが違いました。
serialize()でシリアライズしたデータを外部に送信/保存1し、それをunserialize()すると危険です。
アンシリアライズは複雑なメモリ操作が必要で、PHPに限らず、何度もメモリ破壊攻撃の脆弱性が見つかっています。このため、外部入力データのアンシリアライズは行うべきではありません。現在のPHPプロジェクトでは、RubyやPythonと同じく、アンシリアライズのメモリ問題を”脆弱性として取り扱わない”ことになっています。
しかし、外部データでもunserialize()を安全に利用する方法はあります。
PHPのセッションID用クッキーと他のクッキー関数にSameSiteサポートが追加されます。
https://wiki.php.net/rfc/same-site-cookie
これによりクロスサイト・リクエスト・フォージェリ攻撃(CSRFやXSS)などを緩和できます。
入力バリデーションでほぼ全てのインジェクションリスクを回避/防止できるケースは以前書いたブログで紹介しています。
今回は趣向を変えて、入力バリデーションで許可してしまった文字で発生するリスクをざっと紹介します。
※ ここで紹介する考え方は脆弱なブラックリスト型です。より安全な方法はホワイトリスト型の考え方です。参考: ほぼ全てのインジェクション攻撃を無効化/防止する入力バリデーション
RDBMSはデータセキュリティを学ぶには良い題材です。RDBMSはできる限り正しいデータを保存する仕組みがあるからです。RDBMSからどのようにデータのセキュリティを保証するのか紹介します。
プログラムが正しく動作する為には
が絶対条件です。どちらが欠けてもプログラムは正しく動作しません。
SQLiteは手軽で良いのですが、組み込み型であるためデータセキュリティを学ぶには機能的に問題があります。SQLiteにはデータ型を保証する機能もデータの内容を検証する機能もありません。1
利用するRDBMSはPostgreSQLを用い、データセキュリティに関連性の強い機能のみを対象とします。
プログラムを作っているとOSコマンドを実行したくなる時があります。OSコマンドの実行に問題があり、不正なコマンドをインジェクションされると大変な事になります。
どのようなセキュリティガイドラインでも「OSコマンドの実行に注意する」と大抵書かれています。
多くの場合、「コマンド実行時、コマンドと引数を分離すれば安全に実行できるAPIを利用すれば安全に実行できる」としています。
この記述は間違ってはいないです。しかし、正しくは
です。
コマンドと引数を分離するAPI利用だけでは完璧とは言えないセキュリティ対策です。
CORS問題でAJAXリクエストが失敗する場合の対策として、CORSを設定を紹介しているところまでは良いのですが、他のオプションとしてJSONPを挙げているページを見つけました。記事作成が2018年4月になっていたのでつい最近のことです。あまり知られていないようです。
誤解の無いよう正確に書いておきます。誰かに見られて困るデータが含まれる場合、JSONPは禁止です。
一応、PHPの危い関数リスト、は存在します。例えば、以下のような物があります。
後者は主にホスティング環境(?)でリスクがある関数の一覧を作るプログラムのようです。
ファイルを操作する関数、コマンドやスクリプトを実行する関数などのリスクは自明だと思います。少し趣向を変え、間違えて使うと危い関数の一覧を独断と偏見で作ってみました。
【重要】こういった「危険な物」を定義するのはブラックリストです。ブラックリストは仕組的に危険です。ブラックリストに頼るのは脆弱性を作るような物です。ブラックリスト”だけ”で安心しないでください。最後にどうすれば良いのか?を書きます。