Сессия потеряна при переключении с HTTP на HTTPS в PHP

При отправке пользователя на страницу проверки они переключаются с http://sitename.com на https://sitename.com.

В результате теряются переменные $_SESSION.

У сайта есть действительный сертификат SSL, который может или не может быть использован.

Ответ 1

Когда вы переключаетесь между службами HTTP и HTTPS на одном сервере, ваш идентификатор сеанса HTTP не передается на сеанс HTTPS. Вы можете установить его, передав идентификатор сеанса с HTTP-страницы на страницу HTTPS одним из трех возможных способов:

От PHP: session_start:

session_start() создает сеанс или возобновляет текущий на текущий идентификатор сеанса, который передается через запрос, например GET, POST или cookie

Когда вы используете сеансы, вы обычно начинаете свой script с session_start(). Если в браузере установлен файл cookie идентификатора сеанса, session_start() будет использовать этот идентификатор сеанса. Если в браузере нет набора cookie идентификатора сеанса, session_start() создаст новый.

Если идентификатор сеанса не установлен (в вашем примере браузер создает новый cookie идентификатора сеанса для сеанса HTTPS), вы можете установить его с помощью функции session_id(). session_id() также удобно возвращает идентификатор сеанса в виде строки. Так

...

$currentSessionID = session_id();

...

устанавливает переменную $currentSessionID, равную текущему идентификатору сеанса, и

...

session_id($aSessionID);

...

устанавливает cookie sessionID в браузере $aSessionID. из PHP: session_id

Вот пример с двумя скриптами. Доступ к нему осуществляется через HTTP, а другой - через HTTPS. Они должны находиться на одном сервере для хранения данных сеанса.

Script 1 (HTTP):

<?php

// This script will create a session and display a link to your secure server address
// to transfer your session ID. In this example, the secure page to receive the session
// ID is located at http://www.yoursite.com/safePages/securePage.php

// Start a session using the current session ID stored in a cookie, or create
// a new session if none is set.
session_start();

$currentSessionID = session_id();

// Set a variable that will be retrieved with the HTTPS script.
$_SESSION['testvariable'] = 'It worked';

// $secureServerDomain is the domain of your secure server
$secureServerDomain = 'www.yoursite.com';

// $securePagePath is the path to the page that will receive and set the session ID.
$securePagePath = '/safePages/securePage.php'

echo '<a href="https://' . $secureServerDomain . $securePagePath . '?session="' . $currentSessionID . '">Click here to transfer your session to the secure server</a>';

?>

Script 2 (HTTPS):

<?php

// Retrieve the session ID as passed via the GET method.
$currentSessionID = $_GET['session'];

// Set a cookie for the session ID.
session_id($currentSessionID);

// Start a session.
session_start();

// Test retrieval of variable set when using HTTP.
if (!empty($_SESSION['testvariable'])) {
      echo $_SESSION['testvariable'];
} else {
      echo 'It did not work.';
}

?>

Для этого серверы HTTP и HTTPS должны использовать одну и ту же субстанцию ​​хранения данных сеанса (т.е. для обработчика файлов по умолчанию, работать на одной физической машине с тем же php.ini). Здесь есть некоторые недостатки безопасности, поэтому я не буду использовать этот код для передачи конфиденциальной информации. Это просто предназначенный для примера.

Когда я столкнулся с этой проблемой раньше, я придумал это как быстрое исправление, но я только что вспомнил исходную причину проблемы. Я перешел из http://www.example.com/page.php в https://example.com/page.php ( обратите внимание на отсутствие "www" ). Убедитесь, что http://www.example.com/page.php будет ссылаться на https://www.example.com/page.php и http://example.com будет ссылаться на https://example.com/page.php.

PS, я фактически не запускал эти сценарии, поэтому может быть опечатка или две, которые мешают им работать должным образом, как есть.

Ответ 2

Похоже, что cookie сеанса настроен на безопасность. Cookies имеют флаг "secure" , который, если установлен в true, означает, что cookie не будет отправлен на сайты, отличные от https. PHP, вероятно, использует это для своих сессионных файлов cookie. Вы можете изменить это с помощью функции session_set_cookie_params или с помощью сеанса

Ответ 3

У нас тоже была эта проблема. Это оказалось потому, что мы использовали патч suhosin на нашей установке PHP. Мы зафиксируем его, установив suhosin.session.cryptdocroot = Off в /etc/php.d/suhosin.ini.

Для руководства suhosin о suhosin.session.cryptdocroot см. http://www.hardened-php.net/suhosin/configuration.html#suhosin.session.cryptdocroot.

Мы изначально нашли исправление из этого сообщения в блоге: http://www.yireo.com/blog/general-news/315-switch-between-http-and-https-looses-php-session.

Ответ 4

Следующее решение предполагает, что безопасные и незащищенные серверы имеют доступ к тем же бэкэнд-службам (кэш, хранилище баз данных и т.д.).

Нам приходилось иметь дело с этой же проблемой при отправке пользователя в поток проверки, когда они делали покупки. Чтобы решить эту проблему, мы создали слой кэширования и кэшировали все соответствующие данные. Например, мы собираем идентификаторы продуктов и идентификатор пользователя из значений сеанса, сериализуем их, создаем хэш и, наконец, сохраняем данные сеанса в кеше, используя хеш в качестве ключа. Затем мы перенаправили пользователя на безопасный сайт с хешем в URL-адресе.

Когда пользователь оказался на защищенном сайте, мы попытались вытащить данные из кеша на основе хэша. Затем с идентификаторами пользователя и идентификаторами продуктов мы могли бы загрузить все данные о ценах и описании из базы данных и представить пользователю окончательный контроль.

Наследуется риск того, что данные кэша нестабильны, но у нас никогда не было никаких проблем с ним, так как перенаправление происходит быстро.

Ответ 5

Похоже, ваш cookie сеанса создается с помощью безопасного флага, но есть что-то с URL-адресом вашей страницы проверки, из-за которой cookie сеанса не передается.

Или, возможно, ваш cookie сеанса не защищен - просто, чтобы URL-адрес страницы проверки был достаточно разным (http://mysite.com vs http://www.mysite.com), что браузер не отправляет файл cookie.

Если вы хотите больше узнать о переходе с http на https и наоборот - посмотрите на при моей записи на выборочном ssl: -)

Ответ 6

Вы не можете передавать значения сеанса между разными доменами. Вы должны использовать http post-get или базу данных для передачи своих значений. Для обеспечения безопасности вы можете выполнить все ваши значения в строке и использовать

sha1($string)

и разместите его рядом с вашими значениями и вычислите sha1 для значений, которые получает другая страница, затем сравните хэши.

Метод отправки в разных доменах позволяет браузерам отображать сообщение безопасности, поэтому не используйте это.

Использование url для метода get небезопасно, вам нужно будет запросить пароль на перенаправленной странице для разрешения параметров get в вашей системе.

Не используйте файлы cookie, если вам нужна безопасность.

То, что я предлагаю, - сохранить значения в базе данных и сгенерировать ключ, а затем сделать ссылку перенаправления с помощью вашего ключа, переслать страницу пользователей с параметром get, который имеет ключ, затем пользователь страницы перенаправляется на получает этот ключ, извлекает данные и удаляет ключ. вы можете сгенерировать ключ с помощью sha1

PAGE 1---
$key=sha1($allvalsconcat);
//insert your session values to a database also the key in a column
header("Location: page2.php?key=".$key);

PAGE 2---
// select from database where key=$_GET["key"];
// delete from table where key=$key

это довольно безопасно.

вещи, которые могут произойти: a script вводят случайные значения для параметра "ключ", чтобы ваш сайт загружал данные в вашу память?

Это не произойдет, потому что вы удалите запись после ее использования. Некоторое распространенное заблуждение состоит в том, что получение значений является небезопасным и его всегда следует избегать.

вы можете установить тип движка таблицы в "память" в mysql, если хотите улучшить производительность.

Ответ 7

Я бы рекомендовал в дополнение к тому, что большинство из них заявили о передаче зашифрованной информации, глядя на нее так же, как если бы вы передавали конфиденциальную информацию через сторонний API. Как вы знаете, что кто-то не подделывает запрос? Существует множество протоколов для подлинного подтверждения подлинности запроса, в зависимости от того, насколько чувствительна ваша настройка. Вы открываете себя, чтобы скомпрометировать аккаунты, если не будете осторожны.

Даже если он на том же сервере, рассмотрите это:

Когда кто-то идет по ссылке, формирует действие и т.д., которая проходит через зашифрованный ключ, что мешает кому-то обнюхивать его до того, как они попадут в защищенную версию вашего сайта? Если бы я был на публичном месте WIFI, это не было бы слишком надуманным. Я мог бы притворяться вашим сайтом, перенаправлять запросы на свой собственный ноутбук, захватить токен и перенаправить посетителя туда, где они пришли. Они предполагали, что это был глюк, и понятия не имел. Теперь я могу войти в систему как они, и, возможно, пойду купить вещи стоимостью 10 000 долларов со своей кредитной карточкой и отправить ее в другое место. Степень осторожности, которую вы принимаете здесь, должна соответствовать степени чувствительности.

Кроме того, убедитесь, что вы истекли токены (один используется только после X числа секунд и т.д.), но я также хотел бы использовать шаблон Post-Redirect-Get с обоих концов, то есть:

Не показывать прямую ссылку на странице или в виде незащищенного сайта, а показывать ссылку, которая затем перенаправляется на бэкэнд (и обрабатывать все данные маркера/шифрования). Когда вы придете к защищенной версии, сделайте то же самое (не оставляйте параметр "? Токен = asdfjalksfjla", просто сидите там в URL-адресе, перенаправляйте его).

Итак, формальные системы на основе токенов были разработаны для решения этой самой проблемы, но реализация OAuth только для этого может быть чрезмерной. Проведите некоторое время, планируя потенциальные уязвимости перед выполнением. Просто потому, что было бы тяжело угадать, что токен не означает, что это невозможно (или не могло быть столкновений и т.д.), Поэтому планируйте соответственно.

Вам также может потребоваться более сложная система управления сеансом, чем встроенные обработчики PHP. Я не знаю, можете ли вы заставить PHP продолжать сеанс через несколько посещений (так называемые протоколы переключения).

Ответ 8

Подумайте о том, как использовать HTTPS для всех страниц, это самый простой способ избежать этой проблемы, и это улучшит безопасность вашего сайта.

Если SSL для всех страниц не является для вас вариантом, вы можете использовать этот подход: Переключение между страницами HTTP и HTTPS с помощью безопасного сеансового файла cookie. Идея заключается в том, что вы оставляете cookie сессии незащищенным (и, следовательно, доступным для страниц HTTP и HTTPS), но имеете второй защищенный cookie для обработки аутентификации. Это хороший способ отделить две проблемы "поддержание сеанса" и "аутентификация".

Ответ 9

Вы можете управлять сеансом между HTTP и HTTPS или HTTPS по протоколу HTTP:

  • Передавать идентификатор сеанса между страницами с помощью GET

  • Идентификатор сеанса POST по POST

  • Использовать файлы для сохранения сеансов

  • Использование файлов cookie для сеансов

  • Использовать базу данных для сохранения сеанса

Ниже пример может использоваться для передачи с использованием GET....

Файл: http.php ...............

<?php

session_start();

$sessionID = session_id();

$_SESSION['demo'] = ‘Demo session between HTTP HTTPS’;

echo ‘<a href="https://www.svnlabs.com/https.php?session=’.$sessionID.’">Demo session from HTTP to HTTPS</a>’;

?>

Файл: https.php ...............

<?php

$sessionID = $_GET['session'];

session_id($sessionID);

session_start();

if (!empty($_SESSION['demo'])) {
echo $_SESSION['svnlabs'];
} else {
echo ‘Demo session failed’;
}

?>

IE7: эта страница содержит как безопасные, так и небезопасные элементы

Вы должны использовать относительный путь для всех статических ресурсов на странице, например, css, js, images, flash и т.д., чтобы избежать защищенных и небезопасных сообщений IE...

IE Message Сообщение IE

Ответ 10

Это может быть невозможно, так как файл cookie кажется потерянным. Используемый вами браузер должен думать об этом для совершенно другого домена.

Какой браузер вы используете?

Ответ 11

По умолчанию я ожидаю, что браузер будет обрабатывать соединения с http и https как совершенно разные сеансы. Хотя соглашение состоит в том, что http://someUrl/ и https://someUrl/ указывает на ту же страницу, что она не гарантируется. У вас могут быть совершенно разные сайты, работающие на порту 80 (http) и на порту 443 (https).

Я не знаю PHP, но обычно я бы не ожидал, что переменные сеанса будут свободно доступны между безопасными и незащищенными сеансами, например. Я бы не ожидал, что номер кредитной карты с моего последнего заказа будет доступен для всех последующих небезопасных страниц, которые я посещаю.

Простите не авторитарный ответ, но я подумал, что я задрожаю в своем 2c, так как ответов не так много.

Ответ 12

Есть ли у вас выделенный IP-адрес? в некоторых общих средах https и http маршрутизируются через разные серверы, поэтому переключение фактически теряет доступ к файлам cookie, поскольку они находятся в разных доменах.

были бы: выделенный ip

принудительно https на всех страницах

Ответ 13

У меня была аналогичная проблема, однако это решение было полезно для меня, возможно, поможет другим в будущем

добавьте это в свой php.ini

suhosin.session.cryptdocroot = Выкл

suhosin.cookie.cryptdocroot = Выкл.

Ответ 14

У меня есть решение этого... Попробуйте.

$_SESSION['test'] = 'test';
session_regenerate_id(true);

header("Location: /");// the header must be sent before session close
session_write_close(); // here you could also use exit();

Ответ 15

Не беспокойтесь, это нормальное поведение, потому что HTTPS должен быть безопасным, и он делает свою часть.

Ниже приведены некоторые трюки, благодаря которым вы можете поддерживать сеанс при переключении с HTTP на HTTPS.

  • Передавать идентификатор сеанса между страницами с помощью GET

  • Идентификатор сеанса POST по POST

  • Использовать файлы для сохранения сеансов

  • Использование файлов cookie для сеансов

  • Использовать базу данных для сохранения сеанса

Надеюсь, что вы получите что-то через мой ответ.