User Tools

Site Tools


ja:rule:out:外部へ出力するデータはデフォルトで全て無害化する

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
ja:rule:out:外部へ出力するデータはデフォルトで全て無害化する [2016/03/20 03:02] – created yohgakija:rule:out:外部へ出力するデータはデフォルトで全て無害化する [2017/10/25 00:20] (current) – コンテクストの解説追加 yohgaki
Line 18: Line 18:
 文字エンコーディングのバリデーションは出力時にも行えますが、入力を受け付けた時点でバリデーションしないと問題を生む場合も少なくありません。入力バリデーションと出力時に出力を無害化する処理は独立したセキュリティ対策です。セキュアなコードを書く場合には、入力と出力の両方でセキュリティを意識したコードが必要です。 文字エンコーディングのバリデーションは出力時にも行えますが、入力を受け付けた時点でバリデーションしないと問題を生む場合も少なくありません。入力バリデーションと出力時に出力を無害化する処理は独立したセキュリティ対策です。セキュアなコードを書く場合には、入力と出力の両方でセキュリティを意識したコードが必要です。
  
-固定長/可変長のデータ(文字やデータ位置に意味があるデータ)、文字エンコーディングを持つデータは全て出力する前に無害化(エスケープするかエスケープが必要ないAPIを利用、またはバリデーション)しなければなりません。+固定長/可変長のデータ(文字やデータ位置に意味があるデータ)、文字エンコーディングを持つデータは全て出力する前に無害化しなければなりません。
  
-データ形式がスカラーであるかどうか、で振るまいが変る出力先もあります。このようなAPIを持つ出力先にはデータ型のバリデーションも欠かせません。+無害化の手段 
 + 
 +   * エスケープするか 
 +   * エスケープが必要ないAPIを利用 
 +   * バリデーション 
 + 
 +これらの何れかの手段を出力するデータ**全て**に適用する。 
 + 
 +出力先の無害化は”コンテクスト”によって異る。必ず適切な無害化方法を使用する。 
 + 
 +例:SQLの出力先コンテクスト 
 + 
 +  * パラメーター (パラメーター用エスケープまたはパラメーター用プレイスホルダ) 
 +  * 識別子 (テーブル名、カラム名など。識別子用エスケープ) 
 +  * SQL語句 (DESC、ASCなど。バリデーション) 
 +パラメーターには更にコンテクストがある。全てのコンテクストに対して適切な無害化が必要 
 +  * LIKEクエリ (LIKE用エスケープ) 
 +  * 正規表現 (正規表現用エスケープ) 
 +  * バイナリ型 (バイナリ型用エスケープ) 
 +  * 配列型 (パラメーター用またはバイナリ型用のエスケープ) 
 +  * JSON型 (JSON用エスケープ) 
 +  * その他、全てのコンテクストに対して適切な無害化処理 
 + 
 +エスケープはコンテクストに合わせて行わなければならない。例えば、SQLインジェクション対策としてエスケープ/エスケープが必要ないAPIを利用しても、LIKEクエリや正規表現をサポートするDBMSの場合、LIKEクエリのエスケープ、正規表現のエスケープが必要となる。 
 + 
 + 
 +データ形式がスカラーであるかどうか、で振るまいが変る出力先もあります。このようなAPIを持つ出力先にはデータ型のバリデーションも欠かせません。例:MongoDBインジェクション
  
 データ形式をバリデーションしたり、出力データをエスケープするだけでは不十分な場合も少くありません。例えば、データベースクエリで取得するレコード数は最大値を制限(LIMIT句で取得可能なレコード数の値を制限)していないと、システムが応答不能になる問題が発生する場合があります。 データ形式をバリデーションしたり、出力データをエスケープするだけでは不十分な場合も少くありません。例えば、データベースクエリで取得するレコード数は最大値を制限(LIMIT句で取得可能なレコード数の値を制限)していないと、システムが応答不能になる問題が発生する場合があります。
Line 31: Line 57:
  
 ===== 非適合コード例(Output depends on input validation) ===== ===== 非適合コード例(Output depends on input validation) =====
 +
 +入力対策と出力対策は独立した対策である。出力時に無害化できるものは全て無害化する。
  
 <code php> <code php>
Line 54: Line 82:
  
 // $id is used without escape/validation at output // $id is used without escape/validation at output
-$sql = 'SELECT * FROM  sample WHERE num = '.$id;+$sql = 'SELECT * FROM  sample WHERE id = '.$id;
 $ret = pg_query($sql); $ret = pg_query($sql);
 if ($ret === FALSE) { if ($ret === FALSE) {
Line 61: Line 89:
 ?> ?>
 </code> </code>
 +
 +この非適合コードの場合、$idが整数値としてバリデーションされていることに依存したコードになっている。出力対策は入力対策とは独立して行う。
 +
  
 ===== 適合コード例 ===== ===== 適合コード例 =====
  
-[ルル/推奨事項合するドおよびそ解説。複数あっ構わないの場合、ション名の後に"(ターン名)"記述する。]+一部のデタベースは整数など文字リテラルをサポートしていない場もあるが、ほとんどのデータベースはサポートしている。全てのパラメータに文字リテラルをサポートするタベース場合、すべ文字列としてエスケープする 
 + 
 +<code php> 
 +<?php 
 +$db = pg_connect('host=localhost'); 
 +if (!$db) { 
 +  throw new Exception('Cannot connect to database'); 
 +
 +  
 +// There should be arbitrary length limit validation 
 +if (strspn(strlen($_GET['id']) > 100) { 
 +  throw new Exception('Invalid integer format'); 
 +
 +// Validate $_GET['id'] contains only 0 to 9 chars 
 +if (strspn($_GET['id'], '0123456789') !== strlen($_GET['id'])) { 
 +  throw new Exception('Invalid integer format'); 
 +
 +  
 +$id = $_GET['id']; 
 +  
 +// Usually there are many lines of codes and/or input/output 
 +// codes are stored in different files. 
 +  
 +// $id should be escaped/validated at output or use pg_query_params()/etc. 
 +$sql = 'SELECT * FROM  sample WHERE id = '.pg_escape_literal($id); 
 +$ret = pg_query($sql); 
 +if ($ret === FALSE) { 
 +  throw new Exception('Query failed'); 
 +
 +?> 
 +</code> 
 + 
 +PostgreSQLの場合、pg_query_params()などのプリペアードエリを利用しても良い。 
 + 
 +識別子(テーブルやカラム名)がパラメータ場合、PostgreSQLではpg_escape_identifier()が利用できる。識別子のエスケープ関数がないAPIを利用している場、デースの識別子エスケープ仕様に合わせて関数作成し適用しなければななあい。LIKEクエリや正規表現を利用したクエリは、SQLコンテクストとは異る。必要な場合はLIKEクエリ、正規表現用のエスケープ関数を使ってエスケープしなければならない。
  
  
Line 72: Line 137:
  
 <code php> <code php>
 +<?php
 +$db = new PDO('sqlite:/tmp/mydb');
 +// Test table
 +$db->query('CREATE TABLE test (str varchar(8));');
 +// Test data
 +$str = 'aaaaaaaaaaaaaaaaaaaaa';
 +
 +$db->query("INSERT INTO test (str) VALUES (".$db->quote($str).");");
 +?>
 </code> </code>
  
 +sqlite3コマンドでmydbの内容を確認すると以下のような出力となる。
  
-===== 適合コード例 =====+<code> 
 +sqlite> select * from test;
  
-[ルール/推奨事項に適合するコードおよびその解説。複数あって構わない。その場合、セクション名の後に"(適合パターン名)"を記述する。]+aaaaaaaaaaaaaaaaaaaaa 
 +</code>
  
 +SQLite3のカラムは整数型のプライマリーキーを除き、全て可変長テキスト型である。このため、この非適合コードはカラムデータ型定義の制限を越えた文字列を保存する。
 +
 +
 +===== 適合コード例(Validation) =====
 +
 +<code php>
 +<?php
 +$db = new PDO('sqlite:/tmp/mydb');
 +// Test table
 +$db->query('CREATE TABLE test (str varchar(8));');
 +// Test data
 +$str = 'aaaaaaaaaaaaaaaaaaaaa';
 +
 +// PHP 5.5 or less requires encoding setting.
 +if (!is_scalar($str) || !mb_check_encoding($str) || strlen($str) > 8) {
 +  throw new Exception('Invalid str');
 +}
 +$db->query("INSERT INTO test (str) VALUES (".$db->quote($str).");");
 +?>
 +</code>
 +
 +この適合コードは適切なバリデーションを行う。CHECK制約やデータ型が利用できるデータベースの場合、データベース側のバリデーション機能を利用し、クエリエラーを検出する方法も選択できる。
 +
 +
 +===== 非適合コード例(HTML) =====
 +
 +<code php>
 +<?php
 +$id = $_GET['id'];
 +if (!is_scalar($id) || strlen($id) > 8 || strspn($id, '1234567890') != strlen($id)) {
 +  throw new Exception('Invalid ID');
 +}
 +
 +
 +echo 'ID: '. $id . '<br />';
 +?>
 +</code>
 +
 +HTMLコンテクストへの出力に対しHTML用のエスケープを行っていない。
 +
 +===== 適合コード例(HTML) =====
 +
 +<code php>
 +<?php
 +$id = $_GET['id'];
 +if (!is_scalar($id) || strlen($id) > 8 || strspn($id, '1234567890') != strlen($id)) {
 +  throw new Exception('Invalid ID');
 +}
 +
 +// PHP 5.6以降のデフォルトの場合
 +echo 'ID: '. htmlspecialchars($id) . '<br />';
 +?>
 +</code>
 +
 +適合コードはコンテクストに対してエスケープ可能な全ての変数をコンテクスト用のエスケープを行う。エスケープしない変数は「エスケープできない変数」のみとする。HTMLコンテクストの場合、関数などで既に作られたHTML部品がエスケープできない変数である。
 +
 +エスケープできない変数はプログラムによって自動処理できるようにするか、変数名によってエスケープができない変数であることが判るようにする。
 +
 +エスケープできない変数を作成する場合、確実に安全な変数となるようにする。
  
 ===== 例外 ===== ===== 例外 =====
  
-[ルル/推奨事項例外]+文字エンコディングチェックは入力受付時に行う方が効率的である。全ての入力がバリデーションされている場合、出力時の文字エンコーディングバリデーションは省略しても構わない。 
 + 
 +出力パラメータには無害化ができない物(HTML構文交じりのパラメータなど)もある。この場合、無害化できないパラメータを生成する場合に、全てのパラメータを無害化する。
  
 ===== リスク評価 ===== ===== リスク評価 =====
  
-[ルル/推奨事項のリスク評価] +出力対策と入力対策は独立した対策だが、入力対策だけで十分とするコドは間違いを起こしやすい。複雑なソフトウェアでは全てパラメータが十分に安全なバデーションを適用されているかを保証することも困難である。非常に単純なコード以外では出力時全て無害化する。
- +
-[評価例 - 英語表記統一]+
  
 ^ Rule ^ Severity ^ Likelihood ^ Remediation Cost ^ Priority ^ Level ^ ^ Rule ^ Severity ^ Likelihood ^ Remediation Cost ^ Priority ^ Level ^
-| IDS05-J | medium unlikely | medium | P4 | L3 |+| IDS05-J | critical likely | medium | P4 | L3 |
  
 ===== 関連ガイドライン ===== ===== 関連ガイドライン =====
  
 ===== 参考文献 ===== ===== 参考文献 =====
 +
 +
ja/rule/out/外部へ出力するデータはデフォルトで全て無害化する.1458442965.txt.gz · Last modified: 2016/03/20 03:02 by yohgaki

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki