User Tools

Site Tools


ja:rule:num:整数値のオーバーフローを検出_防止する

Differences

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

Link to this comparison view

Next revision
Previous revision
ja:rule:num:整数値のオーバーフローを検出_防止する [2016/03/18 21:35] – created yohgakija: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 
-  expires INT, +  int4 INT, -- INT is signed 32 bit integer 
-    +  int8 INT8 -- INT8 is signed 64 bit integer  
 ); );
 </code> </code>
 +※ PostgreSQLは16/32/64bit符号付き整数型のみサポートする。MySQLは明示的に指定し符号無し整数型を利用できる。
  
 ===== 非適合コード例 ===== ===== 非適合コード例 =====
  
 +<code php>
 +<?php
 +$db = pg_connect('host=localhost');
 +if (!$db) {
 +  throw new Exception('Cannot connect to database');
 +}
  
 +$myint = 1234567890*12345; // Exceeds signed 32 bit integer range, but within signed 64 bit integer range.
  
 +$sql = 'INSERT INTO sample (int4, int8) VALUES ($1, $2)';
 +$ret = pg_query_params($sql, [$myint, $myint]);
 +if ($ret === FALSE) {
 +  throw new Exception('Query failed');
 +}
 +?>
 +</code>
 +
 +このコードは32bit/64bit OS両方のPHPでクエリに失敗する。
 +
 +エラー例
 +<code>
 +Warning: pg_query_params(): Query failed: ERROR:  value "9223372036854775" is out of range for type integer in - on line 10
 +
 +Fatal error: Uncaught Exception: Query failed in -:12
 +Stack trace:
 +#0 {main}
 +  thrown in - on line 12
 +</code>
  
  
 ===== 適合コード例 ===== ===== 適合コード例 =====
  
-[ルル/推奨事項に適合するコードおよびそ解説。複数って構わないその場合、セクション名後に"(適合パターン名)"を記述する。]+PHPで整数オバーフローを検出するのは比較的簡単でPHPは整数オーバーフローを起こす場合は自動的に浮動小数点型に変換される。64bit環境では符号付き32bit整数の範囲外であるか、のチェックも必要である。 
 + 
 +<code php> 
 +<?php 
 +$db = pg_connect('host=localhost'); 
 +if (!$db) { 
 +  throw new Exception('Cannot connect to database'); 
 +
 + 
 +$myint = 1234567890*12345; // Exceeds signed 32 bit integer range, but within signed 64 bit integer range. 
 + 
 +// 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('64 bit integer overflow'); 
 +
 + 
 +// 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('32 bit integer overflow'); 
 +
 + 
 +$sql = 'INSERT INTO sample (int4, int8) VALUES ($1, $2)'; 
 +$ret = pg_query_params($sql, [$myint, $myint]); 
 +if ($ret === FALSE) { 
 +  throw new Exception('Query failed'); 
 +
 +?> 
 +</code> 
  
  
 ===== 例外 ===== ===== 例外 =====
  
-[ルル/推奨事項]+DBMSなど、外部システムの整数オバーフローエラーに頼れる場合は外部システムエラーに頼っても構わない。だたし、他の出力先への出力する場合は先に部システムに出力してエラーを確認しなければならない点に注意する。
  
 ===== リスク評価 ===== ===== リスク評価 =====
  
-[ルル/推奨事項のリク評価] +入力を受け付けた時点または計算を行った時点でチェックしないとシステムで常にエラが発生し、サービ提供が不能なる場合も考えられる。
- +
-[評価例 - 英語表記統一]+
  
 ^ Rule ^ Severity ^ Likelihood ^ Remediation Cost ^ Priority ^ Level ^ ^ Rule ^ Severity ^ Likelihood ^ Remediation Cost ^ Priority ^ Level ^
-| IDS05-J | medium | unlikely | medium | P4 | L3 |+| IDS05-J | medium | unlikely | high | P4 | L3 |
  
 ===== 関連ガイドライン ===== ===== 関連ガイドライン =====
  
 ===== 参考文献 ===== ===== 参考文献 =====
 +
 +  * https://blog.ohgaki.net/checking-php-int-type-overflow-underflow
 +  * https://blog.ohgaki.net/computers-cannot-handle-numeric-value-correctly
 +  * https://blog.ohgaki.net/php7-type-hint-problem-with-int-and-float
ja/rule/num/整数値のオーバーフローを検出_防止する.1458336924.txt.gz · Last modified: 2016/03/18 21:35 by yohgaki

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki