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ビット整数