PHPのcurlでCookieを使う時はどうしたらよいか実験


やりたいこと

PHPのcurlでform認証を突破する時に必要なテクニックの検証

動作確認環境、使用ライブラリ等

  • Fedora 24 Server Edition
  • PHP 5.6.28

サンプルコード

事前準備

事前準備として、以下のような2つのPHPファイルを用意し、テスト用Webサーバに配置した。
適当なセッション情報を設定し、それを取得するだけの簡単なプログラムだ。

setsession.php
<?php
session_start();
$_SESSION["hoge"] = "fuga";
print "setsession.php\n";
getsession.php
<?php
session_start();
print "getsession.php\n";
var_dump($_SESSION);

PHPのセッションが開始されると、セッションIDを含んだCookieを保存しようとする。
ブラウザ側でこのCookieが受け継がれていれば、保存したセッション値を読めるよね、というわけだ。
(回りくどいか。。。)

検証用コード1:特に何も指定しない

test1.php
<?php
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, "http://localhost/test/setsession.php");
$page1 = curl_exec($curl);
print $page1;
curl_close($curl);

$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, "http://localhost/test/getsession.php");
$page2 = curl_exec($curl);
print $page2;
curl_close($curl);

実行結果

output
setsession.php
getsession.php
array(0) {
}

$_SESSIONは空っぽ。

検証用コード2:明示的にCOOKIEJARを指定

test2.php
<?php
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_COOKIEJAR, "/tmp/test.cookie");
curl_setopt($curl, CURLOPT_URL, "http://localhost/test/setsession.php");
$page1 = curl_exec($curl);
print $page1;
curl_close($curl);

$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, "http://localhost/test/getsession.php");
curl_setopt($curl, CURLOPT_COOKIEJAR, "/tmp/test.cookie");
$page2 = curl_exec($curl);
print $page2;
curl_close($curl);

実行結果

output
setsession.php
getsession.php
array(0) {
}

$_SESSIONは空っぽだが、/tmp/test.cookie が作られている。

/tmp/test.cookie
# Netscape HTTP Cookie File
# https://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

localhost   FALSE   /   FALSE   0   PHPSESSID   3sn18vlmp1bd75qphm61j0v4a2

検証用コード3:明示的にCOOKIEFILEを指定

test3.php
<?php
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_COOKIEFILE, "/tmp/test.cookie");
curl_setopt($curl, CURLOPT_URL, "http://localhost/test/setsession.php");
$page1 = curl_exec($curl);
print $page1;
curl_close($curl);

$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, "http://localhost/test/getsession.php");
curl_setopt($curl, CURLOPT_COOKIEFILE, "/tmp/test.cookie");
$page2 = curl_exec($curl);
print $page2;
curl_close($curl);

実行結果

output
setsession.php
getsession.php
array(0) {
}

$_SESSIONは空っぽで、/tmp/test.cookie も作られない。

検証用コード4:COOKIEJARとCOOKIEFILEを同時に指定

test.php
<?php
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_COOKIEJAR, "/tmp/test.cookie");
curl_setopt($curl, CURLOPT_COOKIEFILE, "/tmp/test.cookie");
curl_setopt($curl, CURLOPT_URL, "http://localhost/test/setsession.php");
$page1 = curl_exec($curl);
print $page1;
curl_close($curl);

$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_COOKIEJAR, "/tmp/test.cookie");
curl_setopt($curl, CURLOPT_COOKIEFILE, "/tmp/test.cookie");
curl_setopt($curl, CURLOPT_URL, "http://localhost/test/getsession.php");
$page2 = curl_exec($curl);
print $page2;
curl_close($curl);

実行結果

output
setsession.php
getsession.php
array(1) {
  ["hoge"]=>
  string(4) "fuga"
}

$_SESSIONが引き継がれ、/tmp/test.cookie が作られている。

検証用コード5:COOKIEJARとCOOKIEFILEを別々に指定

test.php
<?php
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_COOKIEJAR, "/tmp/test.cookie"); //セットするときはJARだけ
curl_setopt($curl, CURLOPT_URL, "http://localhost/test/setsession.php");
$page1 = curl_exec($curl);
print $page1;
curl_close($curl);

$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_COOKIEFILE, "/tmp/test.cookie"); // ゲットするときはFILEだけ
curl_setopt($curl, CURLOPT_URL, "http://localhost/test/getsession.php");
$page2 = curl_exec($curl);
print $page2;
curl_close($curl);

実行結果

output
setsession.php
getsession.php
array(1) {
  ["hoge"]=>
  string(4) "fuga"
}

$_SESSIONが引き継がれ、/tmp/test.cookie が作られている。

検証結果

PHPのcurlからCookieを扱うには、「COOKIEJAR」「COOKIEFILE」を設定する必要がある。
「COOKIEJAR」は保存専用、「COOKIEFILE」は読込専用のような挙動をする。
実際に使用する際は、両方とも設定しておけばうまくいくかもしれない。