Home > Archives >

2038年問題にぶちのめされる前にXSSにぶちのめされるところだった

http://www.masayashi.com/2008/01/05/536
王様は2038年にぶちのめされる前にXSSの対処をされることをお勧めいたします.

via: 王様に提言 - よくきたはてダ

うおー!ありがとうございます!
ご指摘を受け、以下のようにコードを一部改変しました。『受け取ったデータはhtmlspecialcharsかけようね』という指摘だと解釈しました。

$month 	= $_POST{'month'};	//月を受け取る
$day 	= $_POST{'day'};	//日を受け取る
  ↓ XSS対策
$month 	= htmlspecialchars($_POST{'month'});	//月を受け取る
$day 	= htmlspecialchars($_POST{'day'});	//日を受け取る

重ねて、今回のご提言に深く感謝します。
今後も至らない点が見受けられましたら、ご指摘いただければ幸いです。
2008/01/07 12:43 masayashi

PHPで誕生日の曜日を千年分調べたら2038年問題の壁にぶちのめされた

概要

この恋がいつの日か 表彰台にのぼる時
君がメダルを受けとってくれないか
たとえば千年 千年じゃ足りないか
できるだけ長生きするから
 (千年メダル/ザ・ハイロウズ)

  • というようなわけで、各年の誕生日の曜日を表示するPHPプログラムを演習として組んでみた。
  • そしたら2038年問題の壁にぶちのめされた。
  • ここに公開しておきます。
  • (2008/01/07 12:34 追記)elfさまの指摘を受け、コードを一部改変しました。ありがとうございます。
    $month 	= $_POST{'month'};	//月を受け取る
    $day 	= $_POST{'day'};	//日を受け取る
      ↓ XSS対策
    $month 	= htmlspecialchars($_POST{'month'});	//月を受け取る
    $day 	= htmlspecialchars($_POST{'day'});	//日を受け取る
    
ソースコード

送信側(calendar.html)のコードは特別なことをしていないので省略します。

<html>
	<head>
		<title>PHPで誕生日の曜日を千年分調べたら2038年問題の壁にぶちのめされた</title>
	</head>
	<body>
	<h2>PHPで誕生日の曜日を千年分調べたら2038年問題の壁にぶちのめされた</h2>

	<?php
		//変数定義とか
		define("YEAR_START",1900);	//とりあえずこのへんからスタート
		define("YEAR_NUM",1000);	//表示する年数
		$year 	= YEAR_START;
		$month 	= htmlspecialchars($_POST{'month'});	//月を受け取る
		$day 	= htmlspecialchars($_POST{'day'});	//日を受け取る
		$weeks	= array('日','月','火','水','木','金','土');

		//ちょっと失礼して先にテーブルとか組ませてもらいますよっと
		print("<h3>".$month."月".$day."日の曜日を千年分表示しています</h3>");
		print("<table border='1px'><tr><td></td>");
		for ($i=0; $i<10; $i++) {
			print("<td>0".$i."年</td>");
		}
		print("</tr>");

		//ここから処理系
		$counter = 0;	//表示時折り返し用のカウンタ
		print("<tr><td><strong>".$year."年代:</strong></td>");	//妥協の塊
		for (; $year < YEAR_START+YEAR_NUM; $year++, $counter++) {
			//10個表示するごとに改行入れるんば
			if ($counter>=10) {
				print("</tr><tr><td><strong>".$year."年代:</strong></td>");
				$counter=0;
			}
			$week = date("w", mktime(0,0,0,$month,$day,$year));
			print("<td>$weeks[$week]</td>");
		}
		print("</tr></table>");
	?>
	</body>
</html>
出力結果

2008-01-05.JPG

  • ずっと木曜日のターン!なんぞこれー
  • 2038年問題っていうらしいよ。参照:【PHP TIPS】 8. 2038年問題:ITpro
  • 時間の変数を32ビットで表しているらしいのですが、この限界(2の32乗-1)が2038-01-19 12:14:07であり、これより未来に関する処理はオーバーフローしちゃって扱えないよーごめんねー。という問題。
  • PHPに関しては、PEARのCalcクラスを使用することによって対応できる。

うっわー!なんだこの小さな不幸は!困ったさんだなー。
実際に2038年になってこの問題に世間が脅かされるなんてことは、まあないはず。30年後にはコンピュータって単語が持つ意味そのものが変容しているだろー、というのが個人的な持論。

いい未来になっていてほしいもんです。などと考えたり考えなかったりしながら、次回の解決編へつづく。

PHP独習中 - ヒアドキュメントが終了しなくてつまづいた

テストコード
<?php
	$hoge = "ほげ";
	print <<< EOD
		ヒアドキュメント開始!<br />
		ずっと俺のターン!<br />
		$hoge 変数も表示される<br />
		"'<>;/ この辺の記号も大丈夫<br />
		そろそろ終了なんだぜ<br />
	EOD;
?>

上のコード、全然よゆうで動きそうなものなのに、なんかエラーとかいうの。
ソースコードの最終行でエラー出てるから、EOD認識してないんじゃね? と思ったらやっぱりそうだった。

終了のIDの文字列の存在する行にはID以外は何も記述してはいけません。
IDの左側にスペースやタブ等を記述してもエラーとなります。

だってさー。テストコードにはEODの前にタブが入ってる。
正直タブぐらい入れさせていただきたいのだが。インデントさせてくれー。

PHP独習中 - 可変可変可変可変変数

memo
  • 『可変変数とは、変数名を変数でつけられる変数のこと』 うん、日本語でおk
  • サンプルコード追いかけたら簡単。要するにポインタのポインタっていうか参照の参照みたいなことかー、違うかもしれないけど。スクリプト言語特有かな?RubyとかLispにもあるのー?
  • 動的に変数名が付けられて鼻血が出るほど便利らしい。その便利さは今のぼくには 理 解 で き な い 。
  • ちょっとまて参照関係ループにできるんじゃね?
  • やってみたらできた
テストコード
<?php
	$foo = "bar";
	$bar = "foo";

	print ("<strong>変数</strong><br />");
	print ('$foo: '.$foo."<br />");
	print ('$bar: '.$bar."<p />");

	print ("<strong>可変関数</strong><br />");
	print ('$$foo: '.$$foo."<p />");

	print ("<strong>可変可変関数</strong><br />");
	print ('$$$foo: '.$$$foo."<p />");

	print ("<strong>可変可変可変関数</strong><br />");
	print ('$$$$foo: '.$$$$foo."<p />");

	print ("<strong>可変可変可変可変関数</strong><br />");
	print ('$$$$$foo: '.$$$$$foo."<p />");
?>
可変変数の補足メモ
  • $foo => bar
  • $$foo => $ $foo => $ bar => $bar => foo

変態だー!

実行結果

変数
$foo: bar
$bar: foo

可変関数
$$foo: foo

可変可変関数
$$$foo: bar

可変可変関数
$$$$foo: foo

可変可変関数
$$$$$foo: bar

すごく・・・ループです・・・
無限って気持ちいいよねー

PHP独習中 - return未定義の関数の戻り値はNULL

  • 地獄のようにどうでもいいのだけれど、本に載ってなかったのでテストしてみたらNULLだった
  • ふつうだー
テストコード
<?php
	function test() {
		print ("exec test()<p />");
	}
	$ret = test();
	print(gettype($ret));
?>
結果

exec test()
NULL

じゃーん。NULLでしたー。

PHP独習中 - フォーム入出力

実行テスト用 -> http://www.masayashi.com/php/test/formpost.html

memo
  • htmlのフォームからPOSTで投げたデータをphpで受け取って表示するハローワールド
  • 受け取ったデータなどを出力するときは、四の五の言わずにhtmlspecialchars($hoge);かけとけって感じらしい。
  • <script>alert("こんにちはこんにちは!!")</script>

    みたいな入力を与えたら、出力側でスクリプトが実行される。一時流行ったXSS(クロスサイトスクリプティング)ってやつ。

  • このサンプルでもそういう挙動をするはずなんだけど、どうしてかぼくの環境では実行ならず。あるぇー?ブラウザレベルで対策されてるとか?だれかおしえてー
    • コメント欄にて解決しました。Thanks takadekoさん!
formpost.html
<html>
	<head>
		<title>フォーム入力</title>
	</head>
	<body>
	フォームからの入力
	<form action="formput.php" method="post">
		<input type="text" name="name" value="(´・ω・`)" />	<!-- ここの"name"をデータ取り出すときにつかうよー -->
		<input type="submit" value="submit" />	<!-- いってらっしゃい -->
	</form>
	</body>
</html>
formput.php
<html>
	<head>
		<title>フォーム出力</title>
	</head>

	<body>
	<strong>フォームからの入力を受けての出力</strong><p /><p />
	<?php
		$name = $_POST{'name'};	//POSTでもらったデータ

		print ("受け取ったデータをそのまま => $name <p />");
		//	上は$nameに<script>タグを入れて、変なコード実行させられるので危険!
		//	XSS(クロスサイトスクリプティング)っていうらしいよ!

		print ("受け取ったデータにhtmlspecialchars() => ".htmlspecialchars($name)."<p />");
		//	htmlspecialchars()で"<>"とかを実際参照の"&lt;&gt;"に変換しとこうぜー
		//	これで絶対完璧ってわけではないけれど、最低限のマナー
	?>
	</body>
</html>

Home > Archives >

アカウント所有サービス
検索
クリック募金

クリックするだけでスポンサー企業を通して無料で募金が行えます。
あわせて読みたい

あわせて読みたい
ここ一週間の起床時刻

早起き生活
こまごまとしたもの

track feed