23 June 2008

PHPで入力数値・日時の汚染除去

PHPプログラムでテキスト文字列を受け取る時に、SQLインジェクション等を起こす可能性のある汚染文字列を除去する必要性がある。

数値のチェックと、文字列の数値化


<html>
<body>

<p>
<form action = "checknum.php" method = "post" >
<input type="text" name="user_text">
<input type="submit" name="POST_SEND" value="チェック">
</form>
</p>

<?php

mb_language('Japanese');
mb_internal_encoding('Shift_JIS');
mb_http_output('Shift_JIS');

if(!$_POST['user_text'])
{
echo '<p>入力されていません</p>';
}
else
{
echo '<p> 入力値 : ' . $_POST['user_text'] . '</p>';

if(!validate_num($_POST['user_text']))
{
echo '<p>preg_matchによる10進数チェック:NG</p>';
}
else
{
echo '<p>preg_matchによる10進数チェック:OK</p>';

$sTmp = sprintf('%f', floatval($_POST['user_text']));
echo '<p> 数値化後 :' . $sTmp . '<p>';
}

if(!validate_num2($_POST['user_text']))
{
echo '<p>eregによる10進数チェック:NG</p>';
}
else
{
echo '<p>eregによる10進数チェック:OK</p>';
}
}

// Perl互換の正規表現でスキャン(preg_match)するバージョン
function validate_num($sStr)
{
if(preg_match('/[^0-9\-\.]/', $sStr))
{
// 数値以外の文字が発見された場合
return false;
}
if(is_numeric($sStr))
{
// 数値として正しい場合
return true;
}
return false;
}

// Posix拡張の正規表現でスキャン(ereg)するバージョン
function validate_num2($sStr)
{
if(ereg('/[^0-9\-\.]/', $sStr))
{
// 数値以外の文字が発見された場合
return false;
}
if(is_numeric($sStr))
{
// 数値として正しい場合
return true;
}
return false;
}

?>

</body>
</html>


日時のチェックと、文字列の数値化


<html>
<body>

<p>
<form action = "checkdatetime.php" method = "post" >
<input type="text" name="user_text">
<input type="text" name="user_text2">
<input type="submit" name="POST_SEND" value="チェック">
</form>
</p>

<?php

mb_language('Japanese');
mb_internal_encoding('Shift_JIS');
mb_http_output('Shift_JIS');

if(!$_POST['user_text'])
{
echo '<p>入力されていません</p>';
}
else
{
echo '<p> 入力値 : ' . $_POST['user_text'] . ' ' . $_POST['user_text2'] . '</p>';

if(!validate_date($_POST['user_text']))
{
echo '<p>年月日形式の検査 : NG</p>';
}
else
{
echo '<p>年月日形式の検査 : OK</p>';

$tmDate = strtotime($_POST['user_text']);
$sDate = date('Y-m-d H:i:s', $tmDate);
echo '<p>UNIX時刻化後の年月日:' . $sDate . '</p>';
}

if(!validate_time($_POST['user_text2']))
{
echo '<p>時分秒形式の検査 : NG</p>';
}
else
{
echo '<p>時分秒形式の検査 : OK</p>';

$tmTime = strtotime($_POST['user_text2']);
$sTime = date('Y-m-d H:i:s', $tmTime);
echo '<p>UNIX時刻化後の時分秒:' . $sTime . '</p>';
}
}


function validate_date($sStr)
{
if(preg_match('/[^0-9\/\-]/', $sStr))
{
// 数値以外の文字が発見された場合
return false;
}
return true;
}

function validate_time($sStr)
{
if(preg_match('/[^0-9\:]/', $sStr))
{
// 数値以外の文字が発見された場合
return false;
}
return true;
}

?>

</body>
</html>

※ 年月日文字列を strtotime で変数に入れる場合、時分秒は '00:00:00' が代入される。 また、字分秒文字列を strtotime で変数に入れる場合、年月日は現在の年月日が代入される。

※ 解釈できない日時が strtotime に渡された場合は、ゼロを返す(1970-01-01 09:00:00 JST)。