User Tools

Site Tools


ja:rule:out:エスケープの必要がないapiの制限を熟知する

This is an old revision of the document!


エスケープの必要がないAPIの制限を熟知する

出力を無害化する方法には

  • エスケープする
  • エスケープする必要がないAPIを利用する
  • バリデーションする

の3つの方法がある。「エスケープする必要がないAPI」は盲目的に利用して安全とは言えない。

非適合コード例(Prepared query)

プリペアードクエリ/プレイスホルダーはSQLパラメータとSQL文を分離し、SQLインジェクションを防止できる。しかし、SQL識別子、SQL語句の分離は行えない。またLIKEクエリや正規表現によるクエリを利用する場合、それぞれLIKE構文、正規表現構文に合ったエスケープを行わないと安全性を確保できない場合がある。

<?php
$db = pg_connect('host=localhost');
$result = pg_query_params($db, 'SELECT * FROM user_table_prefix_'.$_GET['tblname'].' WHERE id = $1', [$_GET['id']]);

適合コード例(Escape)

プリペアードクエリ/プレイスホルダはSQLパラメーターしか分離しない。他のパラメーターやSQLパラメーターが他のコンテクストで解釈される場合は別の対策が必要となる。

<?php
$db = pg_connect('host=localhost');
// SQL識別子(テーブル名、フィールド名など)は”(ダブルクオート)で括ってエスケープが必要
$result = pg_query_params($db, 'SELECT * FROM '. pg_escape_literal('user_table_prefix_'.$_GET['tblname']).' WHERE id = $1', [$_GET['id']]);

pg_escape_literal()関数は引数として渡された文字列をSQL識別子としてエスケープ(”は”でエスケープ)し、”で括った文字列を返します。

識別子のエスケープ方法はSQLデータベースによって異なる場合があります。例えば、MySQLの場合は動作モードによってエスケープ方法が異なったりします。正しいエスケープ方法でエスケープします。

識別子を安全に処理するにはエスケープする方法以外に識別子として利用可能な文字でのみ構成されているかバリデーションする方法も利用できます。

SQL識別子のエスケープ/バリデーションで注意しなけれならないのは多くのデータベースで” ”(半角スペース)も識別子に利用可能な文字であることです。この為、文字列がSQL識別子として利用可能な文字だけで構成されているのみでなく識別子の文字列を区切る”(ダブルクオート、SQL標準の場合)で括られていなければなりません。

非適合コード例(Execv, Execve)

OSのシステムコールとしてexecv/execveなどを利用するAPIを用いれば、OSコマンドの引数をエスケープせずに安全に利用できる。execv/execveはコマンドと引数を分離するが、コマンド自体が変数の場合は任意コマンドを実行できる。

PHPの場合、pcntl_exec関数はexecv/execveを内部的に利用している。

<?php
pcntl_exec('/path/to/user/cmd/'.$_GET['cmd'],$_GET['params']); 

適合コード例(Validation)

 

例外

例外はない。

リスク評価

[ルール/推奨事項のリスク評価]

[評価例 - 英語表記に統一]

Rule Severity Likelihood Remediation Cost Priority Level
IDS05-J medium unlikely medium P4 L3

関連ガイドライン

参考文献

ja/rule/out/エスケープの必要がないapiの制限を熟知する.1467095950.txt.gz · Last modified: 2016/06/28 06:39 by yohgaki

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki