User Tools

Site Tools


ja:rule:inp:正規表現に用いられる入力データにメタ文字がないことを確認する

Differences

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

Link to this comparison view

Next revision
Previous revision
ja:rule:inp:正規表現に用いられる入力データにメタ文字がないことを確認する [2016/03/06 06:23] – created yohgakija:rule:inp:正規表現に用いられる入力データにメタ文字がないことを確認する [2017/07/04 01:28] (current) – [例外] yohgaki
Line 39: Line 39:
 ===== 非適合コード例 ===== ===== 非適合コード例 =====
  
-[ルール/推奨事項に適合コードおよびその解説。複数あってよい。]+適合なコードは信頼できなユーザーに対して正規表現となる文字列を許可し正規表現検索を実行する 
 + 
 +<color #ed1c24>**非適合コード**</color> 
 +<code php> 
 +function search_log($user, $pattern) { 
 +  if (!strlen($pattern)) { 
 +    return FALSE; 
 +  } 
 +  $regex = '(.*? +'. $user .'\[\d+\+.*'. $pattern .'.*'; 
 +  $log = file_get_contents('/path/to/logfile'); 
 +  preg_match_all($regex, $log, $matches); 
 +  return $matches; 
 +
 + 
 +$log = search_log($_SESSION['username'], $_POST['pattern']); 
 +var_dump($log); 
 +</code> 
 + 
 +このコードは攻撃者に正規表現インジェクションを許す。
  
 ===== 適合コード例(Whitelisting) ===== ===== 適合コード例(Whitelisting) =====
  
-[ルル/推奨事項適合するコードおよびその解説複数あって構わない。その場合、セクション名の後に"(適合パタン名)"を記述する。]+検索パタアルファベットのみを許可する。 
 + 
 +<color #00a2e8>**適合ド**</color> 
 +<code php> 
 +function search_log($user, $pattern
 +  if (!strlen($pattern)) { 
 +    return FALSE; 
 +  } 
 +  $regex = '#(.*? +'. $user .'\[\d+\+.*'. $pattern .'.*#i'; 
 +  $log = file_get_contents('/path/to/logfile'); 
 +  preg_match_all($regex, $log, $matches); 
 +  return $matches; 
 +
 + 
 +// Length check 
 +if (mb_strlen($_POST['pattern'], 'UTF-8') < 1) { 
 +  throw new Exception('Validation error: Too short UTF-8 string'); 
 +
 +if (mb_strlen($_POST['pattern'], 'UTF-8') > 30) { 
 +  throw new Exception('Validation error: Too long UTF-8 string'); 
 +
 +// $_POST['pattern'] is validated by JavaScript at client side and 
 +// must not contain other than alphabet chars. 
 +if (strlen($_POST['pattern']) !== strspn($_POST['pattern'], 'abcdefghijklmnopqrstuvwxyz')) { 
 +  throw new Exception('Validation error: pattern may contain alphabet chars only.'); 
 +
 +$log = search_log($_SESSION['username'], $_POST['pattern']); 
 +var_dump($log); 
 +</code>
  
 ===== 適合コード例(Detect Meta Character) ===== ===== 適合コード例(Detect Meta Character) =====
  
 +preg_quote()はPCRE正規表現のメタ文字をエスケープする。エスケープされた場合、元の文字列より長くなることを利用してバリデーションを行う。
 +
 +<color #00a2e8>**適合コード**</color>
 +<code php>
 +function search_log($user, $pattern) {
 +  if (!strlen($pattern)) {
 +    return FALSE;
 +  }
 +  $regex = '#(.*? +'. $user .'\[\d+\] +.*'. $pattern .'.*#i';
 +  $log = file_get_contents('/path/to/logfile');
 +  preg_match_all($regex, $log, $matches);
 +  return $matches;
 +}
 +
 +// Length check
 +if (mb_strlen($_POST['pattern'], 'UTF-8') < 1) {
 +  throw new Exception('Validation error: Too short UTF-8 string');
 +}
 +if (mb_strlen($_POST['pattern'], 'UTF-8') > 30) {
 +  throw new Exception('Validation error: Too long UTF-8 string');
 +}
 +// Char encoding check
 +if (mb_check_encoding($_POST['pattern'], 'UTF-8')) {
 +  throw new Exception('Validation error: Invalid UTF-8 encoding');
 +}
 +// Allow only following char patterns
 +if (!mb_ereg('\A[\x20-\x7e\x80-\xFF]+\z', $_POST['pattern'])) {
 +  throw new Exception('Invalid char', $_POST['pattern']);
 +}
 +// $_POST['pattern'] is validated by JavaScript at client side and
 +// must not contain meta chars.
 +if (strlen($_POST['pattern']) !== strlen(preg_quote($_POST['pattern'], '#')) {
 +  throw new Exception('Validation error: pattern may contain regex meta chars.');
 +}
 +$log = search_log($_SESSION['username'], $_POST['pattern']);
 +var_dump($log);
 +</code>
 +
 +===== 適合コード例の解説 =====
 +
 +例示した適合コードは非常に単純であるため、出力時(preg_match_all()の呼び出し)のバリデーションを省略している。コードが複雑で入力となる箇所が多い場合、入力バリデーション漏れが発生する可能性が高くなる。ある程度複雑なプログラムの場合は入力と出力の両方でバリデーションを行う。
 +
 +ログフォーマットが変更された場合に意図せず秘密にすべきログが取得できてしまう可能性がある点にも注意が必要である。
 +
 +ユーザー定義正規表現を許可する場合、ReDoSに対してかなり脆弱になる。
  
 ===== 例外 ===== ===== 例外 =====
  
-  * 正規表現を利用するユーザーが権限を持つシステム管理者のみ限定されている場合。+  * 正規表現を利用するユーザーが権限を持つシステム管理者のみ限定されている場合、などそもそも検索対象全てにアクセス権限を持っている時。 
 +  * 検索対象のデータが機密情報でない場合。
  
 ===== リスク評価 ===== ===== リスク評価 =====
ja/rule/inp/正規表現に用いられる入力データにメタ文字がないことを確認する.1457245425.txt.gz · Last modified: 2016/03/06 06:23 by yohgaki

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki