読者です 読者をやめる 読者になる 読者になる

フォームのセキュリティ

PHP

授業でやった簡単なセキュリティ
(時間なかったので名前のところのみ1から作りました。)
簡単な説明もコメントアウトのところに書いてみました。


フォーム画面(index.php)

<?php
function h($str){
	return htmlspecialchars($str, ENT_QUOTES, 'utf-8');
}
/*
session_start関数によって、check.phpの$_SESSION['name']を取得し$nameへ代入する
inputのvalueへ送ることによって前回送信した値が残る
カラ文字を入れるのはvalueに値がないとエラーが出るため
@はエラー表示を無視する(あんまり使用すべきでない)
*/
session_start();
$name = '';
$name_error = '';

$name = @$_SESSION['name'];
$name_error = @$_SESSION['name_error'];
?>
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="utf-8">
		<title>フォーム画面</title>
	</head>
	<body>
		<h1>入力画面</h1>
		<form action="check.php" method="POST">
			<p><label for="name">名前(10文字以内):</label><input type="text" name="name" id="name" value="<?php echo h($name); ?>"></p>
			<input type="submit" value="送信">
		</form>
	</body>
</html>

入力項目の確認画面(check.php)

<?php
//htmlspecialcharsが長いのでh()で呼び出せるようにする
function h($str){
	return htmlspecialchars($str, ENT_QUOTES, 'utf-8');
}

//$_POST['name']の値が無かったらindex.phpへ移動する
if(!isset($_POST['name'])){
	header('Location:index.php');
}

//POSTで送られた値を変数へ代入する
$name = $_POST['name'];

//$successがtrueだったら送信を表示、falseだったら非表示(どっかでエラーが出るとfalseになる)
$success = true;

//$name_errorにカラ文字を代入
$name_error = '';

//$nameの値がカラだったらエラーを表示する
if(empty($name)){
	$name_error = '値がからです';
	$success = false;
}

//$nameが10文字以上だったらエラー
if(mb_strlen($name,'utf-8') > 10){
	$name_error = '名前が長すぎます';
	$success = false;
}

//各データをサーバーに保存する(他のページでもそのデータを使用できる)
session_start();
$_SESSION['name'] = $_POST['name'];
$_SESSION['success'] = $success;
$_SESSION['name_error'] = $name_error;
?>
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="utf-8">
		<title>フォーム画面</title>
	</head>
	<body>
		<h1>確認画面</h1>
		<p>名前:<?php echo h($name); echo h($name_error); ?></p>
		<?php
			if($success){
			echo '<p><a href="send.php">送信</a></p>';
			}
		?>
		<p><a href="index.php">戻る</a></p>
	</body>
</html>

メール送信画面(send.php)

<?php
session_start();

/*
$_SESSION['success']がtrueじゃなかったら(falseだったら)index.phpへ移動する
どっかのページでURL直打ちやcheck.phpでfalseになった後にURL直打ちをするとfalseになってindex.phpに移動する(check.phpでtrueの時にURL直打ちでもOK)
*/
if(!$_SESSION['success']){
	header('Location:index.php');
	exit;
}
//check.phpの$_SESSION['name']を取得し代入する
$name = $_SESSION['name'];

//メールを送る(送信先、subject,本文)
mb_send_mail('xxx@example.com','フォーム',$name);
?>
<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="utf-8">
		<title>無題ドキュメント</title>
	</head>
	<body>
	</body>