ja:rule:num:データ型を指定する場合はデータの表現可能範囲に注意する
Table of Contents
データ型を指定する場合はデータの表現可能範囲に注意する
PHPの関数/メソッドにはタイプヒントが利用できる。PHP 7.0からスカラー型(整数型、浮動小数点型、リソース型、論理型)と配列型のタイプヒントサポートが追加された。PHPのint型は環境によって大きさが異る。32ビットOSでは符号付き32ビット整数、64ビットOSでは符号付き64ビット整数1)となり、int型には注意が必要である。
float型(倍精度浮動小数点 - 符号付き53ビット整数まで正確)や符号付き64ビット整数、任意精度の整数が、符号付き32ビット整数に丸められる。2^31を超えるデータベースのレコードIDが処理できない、などの問題が発生しシステムが動作しなくなったり、演算結果が不正となる問題が発生する。
データベーステーブルのレコードIDは文字列型でも問題なく処理できる。テキスト形式で取り扱うデータ(データベースの値、XMLやJSONの値)は不用意に「整数形式だらint型」を指定すると問題が発生する。特にポータブルなコードを書く場合に重要である。
非適合コード例
<?php $db = pg_connect('host=localhost'); if (!$db) { throw new Exception('Cannot connect to database'); } // int type hint casts $id to int type without any errors function findRecord(int $id) { $sql = 'SELECT * FROM sample WHERE num = $1'; $ret = pg_query_params($sql, [$id]); if ($ret === FALSE) { throw new Exception('Query failed'); } return $ret; } $ret = findRecord($_GET['id']); ?>
適合コード例(String type)
<?php $db = pg_connect('host=localhost'); if (!$db) { throw new Exception('Cannot connect to database'); } // $id may not fit in int type range, use string instead function findRecord(string $id) { $sql = 'SELECT * FROM sample WHERE num = $1'; $ret = pg_query_params($sql, [$id]); if ($ret === FALSE) { throw new Exception('Query failed'); } return $ret; } // 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'); } $ret = findRecord($_GET['id']); ?>
タイプヒントを利用しないという選択肢も有りえるが、この場合$idは配列型なども許可してしまう。string型に限定することにより、他のデータ型が渡されるリスクは低減する。
例外
64ビット整数をサポートする環境でのみ動作すれば良い場合、64ビット整数をサポートしない場合に動作しないコードにする。
if (PHP_INT_SIZE !== 8) { throw new Exception('System does not support 64 bit integer'); }
リスク評価
システムが動作しなくなったり、演算結果が不正となる場合はテストでは判明しない可能性が高い。
| Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
| IDS05-J | high | likely | low | P4 | L3 |
関連ガイドライン
参考文献
1)
PHP 7.0未満のWindows環境では64ビットOSでも32ビット整数
ja/rule/num/データ型を指定する場合はデータの表現可能範囲に注意する.txt · Last modified: 2016/03/20 00:04 by yohgaki
