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