🎃
レガシーコードをあるがままに保護しつつセッションを盗み見するための工夫
PHPレガシーコード、保全したいんですよね、僕はしたくないですが。
たとえばこういうコードがあったとする。
<?php
## Old-skool style PHP will never die.
session_start();
## Confidential must be stored within the session, you know?
if(!isset($_SESSION['my-secret'])){
$secret = rand(1,1000);
$_SESSION['my-secret'] = $name . $secret;
}
echo "<h2>my-secret:".$_SESSION['my-secret']."</h2>";
?>
ちょっとした依頼で「これ、どうなってるのか調べて」といわれる。色々ページを行き来すると、SESSIONに保持されたCSRF_TOKENが予期せぬタイミングで書き換わってる「らしい」とか、なんとか。
「ただし、調査のためにはコードは一切いじらないでね、そして本番しか環境ないから」といわれることが有ります。なるほど。
で、この間Symfonyのコードをみながらそうかーとなって、昔ながらのトリックをつかった様子がこちらです。
<?php // steal-session.php
# capture SESSION
session_start();
$pre_session = $_SESSION;
session_write_close();
ob_start();
@include($_SERVER['SCRIPT_FILENAME']);
echo $____output = ob_get_clean();
# check modified SESSION.
$after_session = $_SESSION;
# save.
@file_put_contents(
'my-bag.ndjson',
@json_encode(
[
'pre' => $pre_session,
'after' => $after_session,
],
JSON_UNESCAPED_UNICODE
),
FILE_APPEND
);
exit();
$ php -d auto_prepend_file=steal-session.php -S 127.0.0.1:3000
$ cat my-bag.ndjson |jq .
{
"pre": [],
"after": {
"my-secret": "asdf432"
}
}
{
"pre": {
"my-secret": "asdf432"
},
"after": {
"my-secret": "asdf432"
}
}
@
つかいまくってるので、実にレガシーですね。もちろん上のjsonにはREQUEST_URI
とかタイムスタンプとかをいれることもできますし、実際いれます。$_SERVER['REMOTE_ADDR']
とかで絞ることもするでしょう。
本番にこういうコードをいれるの正気かって?そうですね、しかしまあ、言われた通りに「既存の」コードはさわってないですし、Apacheの.htaccessに一行入れるくらいならゆるされる世界というのもあります。
応用は色々あるんですけど、省略します。
ではまた。
Discussion