黄昏流星群 (23)
  • 黄昏流星群 (23)
  • 小学館(2005-03-30)
  • (著)弘兼 憲史
  • 定価:¥ 530
  • 新品価格:¥ 530
  • ASIN:4091873138

TGRGの23巻。
ドラマのプロットをそのまま読んでる感じ。
難しいビジネスや政界の話と違ってこういう話に物事を凄まじく解り易く説明する能力を適用するとこうなるのか!
そんな違和感がいちいち引っかかりになって楽しい。

複数Webサーバ、単一セッション管理でセッションかぶっちゃう問題ですが、調べたら5人日ぐらいかかりそう・・・とか思ってましたが、この間の勉強会で聞いたら、

「session_id()でセッションID設定できる。」

一瞬で解決しました。

解決策をまとめると、

「セッション維持してくれるロードバランサーを使う」 OR 「セッションIDにアドレスをくっ付ける」

となりました。
実装はこんな感じか!?

session_id(str_replace(".", "a", $_SERVER["SERVER_ADDR"]).session_id());

Mojavi2で使うためにIPでユニークなセッションIDを使うコンテナ、IpUniqueSessionContainerを作ってみました。

<?php
require_once (USER_DIR."SessionContainer.class.php");

class IpUniqueSessionContainer extends SessionContainer {
    function load(& $authenticated, & $attributes, & $secure) {
        if (ini_get("session.auto_start") != 1) session_start();
        session_id(str_replace(".", "a", $_SERVER["SERVER_ADDR"]).session_id());
        if (!isset($_SESSION["attributes"])) {
            $authenticated = false;
            $attributes = array();
            $secure = array();
        } else {
            $authenticated = $_SESSION["authenticated"];
            $attributes = $_SESSION["attributes"];
            $secure = $_SESSION["secure"];
        }
        $_SESSION["authenticated"] =& $authenticated;
        $_SESSION["attributes"] =& $attributes;
        $_SESSION["secure"] =& $secure;
    }
}
?>

IpUniqueSessionContainer-0.1.zip

index.phpのUSER CONTAINER SETTINGSのところでこんな感じで使う。

require_once(BASE_DIR."opt/user/IpUniqueSessionContainer.class.php");
$user =& $controller->getUser();
$user->setContainer(new IpUniqueSessionContainer());

ref: PHPのセッションID2

この間のおざきさんの話がすごい気になってたんですが、対策できました!

Mojaviのすべての基本となるSCRIPT_PATH定数をこんな感じで設定してやれば、この間つくったURIUtil::redirect()もSmartyプラグインのmojavi_uriも絶対URIを吐いてくれます。

/**
* An absolute web path to the index.php script.
*/
define('SCRIPT_PATH', strtolower(trim(array_shift(split("/", $_SERVER["SERVER_PROTOCOL"]))))."://".$_SERVER["HTTP_HOST"].dirname($_SERVER["PHP_SELF"])."/index.php");

きもちー。

ref: リダイレクト面倒

2005/07/08追記:

こっちの方がよい(via MugeSo)

/**
* An absolute web path to the index.php script.
*/
define('SCRIPT_PATH', strtolower(trim(array_shift(split("/", $_SERVER["SERVER_PROTOCOL"]))))."://".$_SERVER["HTTP_HOST"].$_SERVER["PHP_SELF"]);

CSRF(クロスサイトリクエストフォージェリ)の対策を自分の中で決めてみましたが、根本的に間違った理解をしてることがわかりました

CSRFはそのユーザ自身(のクライアント)がアクセスする(させる)ことを利用する攻撃なんですな!

高木浩光さんの記事(via ファイさん)を元にPHPでのサンプルを作ってみました。

ログインページ(index.php):

<?php
session_start();
?>
<?="<?xml version=\"1.0\" encoding=\"utf-8\"?>"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<title>ログイン</title>
</head>
<body>
<h1>ログイン</h1>
<p>ログインしました。</p>
<p><a href="confirm.php">退会</a></p>
</body>
</html>

確認ページ(confirm.php):

<php
session_start();
?>
<?="<?xml version=\"1.0\" encoding=\"utf-8\"?>"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<title>退会処理 確認画面</title>
</head>
<body>
<h1>退会処理 確認画面</h1>
<p>本当に退会しますか?</p>
<form method="post" action="resign.php">
<strong>&lt;input type="hidden" name="sessionid" value="&lt;?=session_id()?&gt;" /&gt;</strong>
&lt;input type="submit" value="退会する" /&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;

処理ページ(resign.php):

&lt;?php
session_start();
if (<strong>session_id() == $_POST["sessionid"]</strong>) {
    $message = "退会しました。";
} else {
    $message = "退会・・・するかよ!";    
}
?&gt;
&lt;?="&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;"?&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;
&lt;meta http-equiv="Content-Style-Type" content="text/css" /&gt;
&lt;meta http-equiv="Content-Script-Type" content="text/javascript" /&gt;
&lt;title&gt;退会処理 完了画面&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;退会処理 完了画面&lt;/h1&gt;
&lt;p&gt;&lt;?=$message?&gt;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;

動いてるサンプル:http://p0t.jp/anti-csrf/

ソース:anti-csrf-0.2.zip

外部サイトでは(本人がアクセスしたとしても)対象サイトのクッキーを取ることができないっていうのがミソ・・・だと思う。
あってるのかどうか気になります!

それほど面倒ではないのでコンシューマサイトは全部これで行くことにします!

ref: CSRF対策俺ルール

2005/07/08追記:

$_COOKIE[””PHPSESSID”“] から session_id() に変更しました。(via ishinao

PEAR :: PEPr :: Details :: Linux_Debian_Apt

This package works as a wrapper of the famous apt utilities under Debian. It lets user search for packages or files, it uses packages.debian.org to fetch the content and return it in nice array structs.

PEPrにaptのラッパ。
素敵だけどProposal通らなそう!

Warning!!! 下記は全部間違ってました!
罵声を浴びせてからこちらへ → CSRF対策俺ルール2

CSRF クロスサイトリクエストフォージェリ – SpecIII – てけとうなWeb開発者の雑記

CSRFはサイトに対する正規のユーザーの権限を利用した攻撃です。
あるサイトのある処理を行うページに正規のユーザーを誘導し、強制的に望まない処理を発生させます。

CSRF(クロスサイトリクエストフォージェリ)
この間の勉強会でgorouさんとかが言っていてわかんなかったので調べました。

forgeryは偽造の意味なので「サイト横断的リクエスト偽造」でしょうか。
内容的には↓こうだそうです。

CSRFはサイトに対する正規のユーザーの権限を利用した攻撃です。
あるサイトのある処理を行うページに正規のユーザーを誘導し、強制的に望まない処理を発生させます。

具体的には記事の編集や削除といった機能を持つページのURLをダミーのリンクに埋め込んで踏ませたり、imgタグのsrcとして指定して知らず知らずのうちにアクセスさせます。特に後者の例ではユーザーが全く気がつかぬうちに攻撃が完了します。

JavaScriptでGETやPOSTができる以上、根本的な対策が難しそうです。
どう対応するか自分ルールを決めておくことにします。

CSRF対策俺ルール:

  • 本気で防ぎたい場合:CAPTCHA
  • ユーザビリティ優先の場合:全部POST&セッション&リファラーチェック(7/7追加)

Byecycle – Aesthetic Programming for Eclipse

logobyecycle.gif

Byecycle is an auto-arranging dependency analysis plug-in for Eclipse.

クラスの依存関係を表示するEclipseプラグイン。
可視化してくれると依存関係を減らすのが楽しくなっていいかも!こんな風に小ネタをすぐにEclipseプラグイン化できるようになりたい。

PECL :: Package :: ssh2

Provides bindings to the functions of libssh2 which implements the SSH2 protocol. libssh2 is available from http://www.sourceforge.net/projects/libssh2

libssh2のPHPバインディング。これ知っておくと仕事で要件を意外な方法で片付けたりできる場面がある・・・気がする!

Trackbackサーバを書いたんですがXMLがちょっと面倒くさい。
そこでRESTより簡単なRPCを考えてみました。

サーバ:

&lt;?php
echo var_export(array("foo", "bar", "buz"));
?&gt;

クライアント:

&lt;?php
function var_export_rpc($uri) { return eval('return '.file_get_contents($uri).';'); }
var_dump(var_export_rpc("http://localhost/workspace/samples/var_export_rpc_server.php"));
?&gt;

VAR_EXPORT_RPC

XMLじゃなくてPHPコードを返す。
クライアントがPHPじゃないと死ぬほど面倒なことになる方式です。(Webサービスの利点台無し)
あぁ、しかもオブジェクト渡せない・・・。

この間やった内部勉強会の資料をアップしました。

基礎Mojavi(2) ~ValidationとLogging~

基礎Mojavi(2)サンプルアプリ