User Tools

Site Tools


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

Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
ja:rule:out:エスケープの必要がないapiの制限を熟知する [2016/03/21 02:54] yohgakija:rule:out:エスケープの必要がないapiの制限を熟知する [2016/06/28 06:56] (current) – [適合コード例(Validation)] yohgaki
Line 14: Line 14:
  
 <code php> <code php>
 +<?php
 +$db = pg_connect('host=localhost');
 +$result = pg_query_params($db, 'SELECT * FROM user_table_prefix_'.$_GET['tblname'].' WHERE id = $1', [$_GET['id']]);
 </code> </code>
  
Line 21: Line 24:
  
 <code php> <code php>
 +<?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']]);
 </code> </code>
  
 +pg_escape_literal()関数は引数として渡された文字列をSQL識別子としてエスケープ(”は”でエスケープ)し、”で括った文字列を返します。
  
-===== 非適合コード例(ExecvExecve) =====+識別子のエスケープ方法はSQLデータベースによって異なる場合があります。例えば、MySQLの場合は動作モードによってエスケープ方法が異なったりします。正しいエスケープ方法でエスケープします。 
 + 
 +識別子を安全に処理するにはエスケープする方法以外に識別子として利用可能な文字でのみ構成されているかバリデーションする方法も利用できます。 
 + 
 +SQL識別子のエスケープ/バリデーションで注意しなけれならないのは多くのデータベースで” ”(半角スペース)も識別子に利用可能な文字であることです。この為、文字列がSQL識別子として利用可能な文字だけで構成されているのみでなく識別子の文字列を区切る”(ダブルクオート、SQL標準の場合)で括られていなければなりません。 
 + 
 + 
 +===== 非適合コード例(execvexecve) =====
  
 OSのシステムコールとしてexecv/execveなどを利用するAPIを用いれば、OSコマンドの引数をエスケープせずに安全に利用できる。execv/execveはコマンドと引数を分離するが、コマンド自体が変数の場合は任意コマンドを実行できる。 OSのシステムコールとしてexecv/execveなどを利用するAPIを用いれば、OSコマンドの引数をエスケープせずに安全に利用できる。execv/execveはコマンドと引数を分離するが、コマンド自体が変数の場合は任意コマンドを実行できる。
  
-PHPの場合、pcntl_exec関数はexecv/execveを内部的に利用している。+PHPの場合、[[http://php.net/pcntl_exec|pcntl_exec関数]]はexecv/execveを内部的に利用している。
  
 <code php> <code php>
 +<?php
 +pcntl_exec('/path/to/user/cmd/'.$_GET['cmd'], $_GET['params']); 
 </code> </code>
 +
 +上記のコードには2つの問題がある。
 +
 +  * execv, execveシステムコールはコマンドとその引数を分離するが、コマンド部分がインジェクションに脆弱である場合、安全性を維持できない。(SQLのプリペアードクエリにおけるプリペア文とパラメーターの関係と同じ)
 +  * execv, execveシステムコールはコマンドとその引数を分離するが、コマンドに脆弱性がある場合、安全性を維持できない。(コマンドの引数を更に別のコマンドの引数に利用する場合などにこの問題が発生しうる。シェルスクリプトなどではこのような状況は容易に起こり得る)
 +
  
  
 ===== 適合コード例(Validation) ===== ===== 適合コード例(Validation) =====
 +
 +通常のホワイトリストによるバリデーションを行う。
  
 <code php> <code php>
 +<?php
 +if (!isset($_GET['cmd']) || strspn($_GET['cmd'], 'abcdefghijklmnopqrstuvwxyz') !== strlen($_GET['cmd'])) {
 +  throw Exception('cmd validation error');
 +}
 +foreach($_GET['params'] as $param) {
 +  if (strspn($param, 'abcdefghijklmnopqrstuvwxyz1234567890') !== strlen($param)) {
 +    throw Exception('param validation error');
 +  }
 +}
 +
 +pcntl_exec('/path/to/user/cmd/'.$_GET['cmd'], $_GET['params']); 
 </code> </code>
 +
 +バリデーションの注意点
 +
 +  * コマンド引数でパストラバーサルが可能な場合、任意コマンドに実行許してしまう。コマンドとして"."(ピリオド)、"/","\"(スラッシュ、バックスラッシュ)の許可には十分な注意を払う。
 +  * パラメーター引数は指定したコマンドにより、更に別のコマンド実行に利用される可能性もある。この為、シェルの特殊文字を一文字でも許可するとリスクが発生する。文字種によるバリデーションより、特定の文字列のみをホワイトリスト形式でバリデーションする方がより安全性が高い。
  
  
ja/rule/out/エスケープの必要がないapiの制限を熟知する.1458528869.txt.gz · Last modified: 2016/03/21 02:54 by yohgaki

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki