ja:rule:num:整数値のオーバーフローを検出_防止する
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| ja:rule:num:整数値のオーバーフローを検出_防止する [2016/03/18 21:35] – created yohgaki | ja:rule:num:整数値のオーバーフローを検出_防止する [2017/06/30 11:32] (current) – [参考文献] yohgaki | ||
|---|---|---|---|
| Line 8: | Line 8: | ||
| 浮動小数点型はIEEE754の倍精度浮動小数点型で符号付き53bit整数まで正確に表現できる。 | 浮動小数点型はIEEE754の倍精度浮動小数点型で符号付き53bit整数まで正確に表現できる。 | ||
| - | 厳密な整数型の利用が必要な場合は整数値のオーバーフローを検出、防止が必要となる。特に外部システムとデータをやり取りする場合に、データ型と範囲の違いに注意しなければならない。 | + | 厳密な整数型の利用が必要な場合は整数値のオーバーフローを検出、防止が必要となる。特に外部システムとデータをやり取りする場合に、データ型と範囲の違いに注意しなければならない。整数型には符号付きと符号無し整数の2種類がある。PHPは符号付き整数型のみサポートするので、符号無し整数を取り扱う場合にも注意が必要である。 |
| ここではRDBMSのPostgreSQLを例として利用する。しかし、データ型を持つシステム(PHPを含む)の場合はオーバーフローする場合の取り扱いに注意しなければならない。非適合コード、適合コードは以下のテーブル定義を持つデータベースとする。 | ここではRDBMSのPostgreSQLを例として利用する。しかし、データ型を持つシステム(PHPを含む)の場合はオーバーフローする場合の取り扱いに注意しなければならない。非適合コード、適合コードは以下のテーブル定義を持つデータベースとする。 | ||
| Line 14: | Line 14: | ||
| <code sql> | <code sql> | ||
| CREATE TABLE sample ( | CREATE TABLE sample ( | ||
| - | id SERIAL NOT NULL, | + | id SERIAL NOT NULL, -- SERIAL is signed 32 bit integer |
| - | | + | |
| - | + | int8 INT8 -- INT8 is signed 64 bit integer | |
| ); | ); | ||
| </ | </ | ||
| + | ※ PostgreSQLは16/ | ||
| ===== 非適合コード例 ===== | ===== 非適合コード例 ===== | ||
| + | <code php> | ||
| + | <?php | ||
| + | $db = pg_connect(' | ||
| + | if (!$db) { | ||
| + | throw new Exception(' | ||
| + | } | ||
| + | $myint = 1234567890*12345; | ||
| + | $sql = ' | ||
| + | $ret = pg_query_params($sql, | ||
| + | if ($ret === FALSE) { | ||
| + | throw new Exception(' | ||
| + | } | ||
| + | ?> | ||
| + | </ | ||
| + | |||
| + | このコードは32bit/ | ||
| + | |||
| + | エラー例 | ||
| + | < | ||
| + | Warning: pg_query_params(): | ||
| + | |||
| + | Fatal error: Uncaught Exception: Query failed in -:12 | ||
| + | Stack trace: | ||
| + | #0 {main} | ||
| + | thrown in - on line 12 | ||
| + | </ | ||
| ===== 適合コード例 ===== | ===== 適合コード例 ===== | ||
| - | [ルール/推奨事項に適合するコードおよびその解説。複数あって構わない。その場合、セクション名の後に" | + | PHPで整数オーバーフローを検出するのは比較的簡単である。PHPは整数オーバーフローを起こす場合は自動的に浮動小数点型に変換される。64bit環境では符号付き32bit整数の範囲外であるか、のチェックも必要である。 |
| + | |||
| + | <code php> | ||
| + | <?php | ||
| + | $db = pg_connect(' | ||
| + | if (!$db) { | ||
| + | throw new Exception(' | ||
| + | } | ||
| + | |||
| + | $myint = 1234567890*12345; | ||
| + | |||
| + | // Check signed 64 bit integer overflow | ||
| + | // PHP_INT_SIZE is available since PHP 5.0.5 | ||
| + | if (PHP_INT_SIZE === 8 && is_float($myint)) { | ||
| + | throw new Exception(' | ||
| + | } | ||
| + | |||
| + | // Check signed 32 bit integer overflow | ||
| + | // Under 32 bit OS, $myint became float. Under 64 bit OS, check 32 bit integer range | ||
| + | if (is_float($myint) || $myint < 0x80000000 || $myint > 0xEFFFFFFF) { | ||
| + | throw new Exception(' | ||
| + | } | ||
| + | |||
| + | $sql = ' | ||
| + | $ret = pg_query_params($sql, | ||
| + | if ($ret === FALSE) { | ||
| + | throw new Exception(' | ||
| + | } | ||
| + | ?> | ||
| + | </ | ||
| ===== 例外 ===== | ===== 例外 ===== | ||
| - | [ルール/推奨事項の例外] | + | DBMSなど、外部システムの整数オーバーフローエラーに頼れる場合は外部システムのエラーに頼っても構わない。だたし、他の出力先への出力する場合は先に外部システムに出力してエラーを確認しなければならない点に注意する。 |
| ===== リスク評価 ===== | ===== リスク評価 ===== | ||
| - | [ルール/推奨事項のリスク評価] | + | 入力を受け付けた時点または計算を行った時点でチェックしないとシステムで常にエラーが発生し、サービス提供が不能になる場合も考えられる。 |
| - | + | ||
| - | [評価例 - 英語表記に統一] | + | |
| ^ Rule ^ Severity ^ Likelihood ^ Remediation Cost ^ Priority ^ Level ^ | ^ Rule ^ Severity ^ Likelihood ^ Remediation Cost ^ Priority ^ Level ^ | ||
| - | | IDS05-J | medium | unlikely | medium | + | | IDS05-J | medium | unlikely | high | P4 | L3 | |
| ===== 関連ガイドライン ===== | ===== 関連ガイドライン ===== | ||
| ===== 参考文献 ===== | ===== 参考文献 ===== | ||
| + | |||
| + | * https:// | ||
| + | * https:// | ||
| + | * https:// | ||
ja/rule/num/整数値のオーバーフローを検出_防止する.1458336924.txt.gz · Last modified: 2016/03/18 21:35 by yohgaki
