diff --git a/data/class/helper/SC_Helper_Session.php b/data/class/helper/SC_Helper_Session.php index 2c75a69d9c..9fb7a59506 100644 --- a/data/class/helper/SC_Helper_Session.php +++ b/data/class/helper/SC_Helper_Session.php @@ -64,6 +64,13 @@ function sfSessClose() { * @return string セッションデータの値 */ function sfSessRead($id) { + // SameSite=None を未サポート UA 向け対応 + if (empty($_COOKIE['ECSESSID']) && isset($_COOKIE['legacy-ECSESSID']) && $id !== $_COOKIE['legacy-ECSESSID']) { + // session_id と $_COOKIE['legacy-ECSESSID'] が異なる場合は ECSESSID の cookie が拒否されたと見なす + GC_Utils_Ex::gfPrintLog('replace session id: ECSESSID=>legacy-ECSESSID'); + $id = $_COOKIE['legacy-ECSESSID']; // 互換用 cookie からセッションデータを読み込む + unset($_COOKIE['legacy-ECSESSID']); + } $objQuery = new SC_Query_Ex(); $arrRet = $objQuery->select("sess_data", "dtb_session", "sess_id = ?", array($id)); if (empty($arrRet)) { diff --git a/data/class/session/sessionfactory/SC_SessionFactory_UseCookie.php b/data/class/session/sessionfactory/SC_SessionFactory_UseCookie.php index aea4b7837f..0835b2ad3c 100644 --- a/data/class/session/sessionfactory/SC_SessionFactory_UseCookie.php +++ b/data/class/session/sessionfactory/SC_SessionFactory_UseCookie.php @@ -36,25 +36,45 @@ * @version $Id$ */ class SC_SessionFactory_UseCookie extends SC_SessionFactory { - - // }}} - // {{{ functions - /** * セッションパラメーターの指定 * ・ブラウザを閉じるまで有効 - * ・すべてのパスで有効 - * FIXME 多分、同一ホスト名に複数の EC-CUBE をインストールした場合に望ましくない状態である。特段の事由がなければ、アプリケーションルートを指定すべきだし、あればコメントに残すべき。 + * ・EC-CUBE ルート配下で有効 * ・同じドメイン間で共有 + * FIXME セッションキーのキーが PHP デフォルトのため、上位ディレクトリーで定義があると、その値で動作すると考えられる。 **/ - function initSession() { + public function initSession() + { ini_set('session.cache_limiter', 'none'); - if (session_id() === "") { - session_set_cookie_params(0, "/", DOMAIN_NAME); - if (!ini_get("session.auto_start")) { - // セッション開始 - session_start(); + // (session.auto_start などで)セッションが開始されていた場合に備えて閉じる。(FIXME: 保存する必要はない。破棄で良い。) + session_write_close(); + $params = array( + 'lifetime' => 0, + 'path' => ROOT_URLPATH, + 'domain' => DOMAIN_NAME, + 'secure' => $this->getSecureOption(), + 'httponly' => true, + 'samesite' => '' + ); + if ($this->getSecureOption()) { + $params['samesite'] = 'None'; // require secure option + } + if (PHP_VERSION_ID >= 70300) { + session_set_cookie_params($params); + } else { + $samesite = ''; + if (!empty($params['samesite'])) { + $samesite = '; SameSite='.$params['samesite']; } + session_set_cookie_params($params['lifetime'], $params['path'].$samesite, $params['domain'], $params['secure'], $params['httponly']); + } + // セッション開始 + // FIXME EC-CUBE をネストしてインストールした場合を考慮して、一意とすべき + session_name('ECSESSID'); + session_start(); + if (session_id() !== '') { + // SameSite=None を未サポートの UA 向けに 互換用 cookie を発行する. secure option 必須 + setcookie('legacy-'.session_name(), session_id(), $params['lifetime'], $params['path'], $params['domain'], true, true); } } @@ -63,9 +83,21 @@ function initSession() { * * @return boolean 常に true を返す */ - function useCookie() { + public function useCookie() + { return true; } + + /** + * secure オプションの値を返す. + * + * この値をもとに secure オプションを設定する. + * @return bool HTTP_URL 及び HTTPS_URL が https の場合は true + */ + protected function getSecureOption() + { + return (strpos(HTTP_URL, 'https') !== false && strpos(HTTPS_URL, 'https') !== false); + } } /* * Local variables: