PHP에서 HTTP에서 HTTPS로 전환 할 때 세션 손실
사용자를 결제 페이지로 보내면에서로 전환 http://sitename.com됩니다 https://sitename.com.
결과적으로 $_SESSION변수가 손실됩니다.
사이트에 일부 사용 여부에 관계없이 유효한 SSL 인증서가 있습니다.
동일한 서버에서 HTTP와 HTTPS 서비스간에 전환하면 HTTP 세션 ID가 HTTPS 세션으로 전달되지 않습니다. 다음 세 가지 방법 중 하나로 HTTP 페이지에서 HTTPS 페이지로 세션 ID를 전달하여 설정할 수 있습니다.
session_start()GET, POST 또는 쿠키와 같은 요청을 통해 전달되는 현재 세션 ID를 기반으로 세션을 생성하거나 현재 세션을 재개합니다.
세션을 사용할 때 일반적으로 session_start(). 브라우저에 세션 ID 쿠키 세트 session_start()가있는 경우 해당 세션 ID를 사용합니다. 브라우저에 세션 ID 쿠키가 설정되어 있지 않으면 session_start()에서 새 쿠키 를 만듭니다.
세션 ID가 설정되지 않은 경우 (예 : 브라우저가 HTTPS 세션에 대한 새 세션 ID 쿠키를 생성하고 있음) session_id()함수를 사용하여 설정할 수 있습니다 . session_id()또한 편리하게 세션 ID를 문자열로 반환합니다. 그래서
...
$currentSessionID = session_id();
...
$currentSessionID현재 세션 ID와 동일한 변수를 설정 하고
...
session_id($aSessionID);
...
브라우저의 sessionID 쿠키를로 설정합니다 $aSessionID. 에서 PHP : SESSION_ID
다음은 두 개의 스크립트가있는 예입니다. 하나는 HTTP를 통해 액세스되고 다른 하나는 HTTPS를 통해 액세스됩니다. 세션 데이터를 유지하려면 동일한 서버에 있어야합니다.
스크립트 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>';
?>
스크립트 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 .
추신, 실제로 이러한 스크립트를 실행하지 않았으므로 제대로 실행되지 못하게하는 오타가있을 수 있습니다.
세션 쿠키가 안전하도록 설정된 것 같습니다. 쿠키에는 "보안" 플래그가 있습니다. true로 설정하면 쿠키가 비 https 사이트로 전송되지 않음을 의미합니다. PHP는 아마도 세션 쿠키에 이것을 사용하고있을 것입니다. session_set_cookie_params 함수 또는 php.ini 의 session.cookie_secure 설정을 사용하여 이를 변경할 수 있습니다 .
우리도이 문제가있었습니다. PHP 설치에 suhosin 패치를 사용했기 때문 입니다. 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) 에서 수정 사항을 찾았습니다 .
다음 솔루션은 보안 및 비보안 서버가 동일한 백엔드 서비스 (캐시, 데이터베이스 저장소 등)에 액세스 할 수 있다고 가정합니다.
사용자가 쇼핑을 마쳤을 때 결제 흐름으로 보낼 때도 이와 동일한 문제를 처리해야했습니다. 이를 해결하기 위해 캐싱 레이어를 배치하고 모든 관련 데이터를 캐시했습니다. 예를 들어 세션 값에서 제품 ID와 사용자 ID를 수집하고 직렬화하고 해시를 생성 한 다음 마지막으로 해시를 키로 사용하여 캐시에 세션 데이터를 저장합니다. 그런 다음 URL에 해시가있는 보안 사이트로 사용자를 리디렉션합니다.
사용자가 보안 사이트에 접속하면 해시를 기반으로 캐시에서 데이터를 가져 오려고합니다. 그런 다음 사용자 ID와 제품 ID를 사용하여 모든 가격 및 설명 데이터를 데이터베이스에서로드하고 최종 결제 검토를 위해 사용자에게 제공 할 수 있습니다.
캐시 데이터가 휘발성이라는 상속 위험이 있지만 리디렉션이 빠르게 발생하므로 문제가 발생하지 않았습니다.
세션 쿠키가 보안 플래그로 생성 된 것 같습니다.하지만 세션 쿠키가 전달되지 않아 결제 페이지의 URL에 무언가가 있습니다.
또는 세션 쿠키가 안전하지 않을 수 있습니다. 체크 아웃 페이지의 URL이 브라우저가 쿠키를 보내지 않을만큼 충분히 다른 경우 ( http://mysite.com 대 http://www.mysite.com ).
http에서 https로 또는 그 반대로 뒤집는 방법에 대해 자세히 알아 보려면 선택적 SSL에 대한 내 글을 살펴보십시오. :-)
다른 도메인간에 세션 값을 전달할 수 없습니다. 값을 전달하려면 http post-get 또는 데이터베이스를 사용해야합니다. 보안을 위해 문자열의 모든 값을 연결하고
sha1($string)
값과 함께 게시하고 다른 페이지가 얻는 값에 대한 sha1을 계산 한 다음 해시를 비교하십시오.
다른 도메인의 게시 방법으로 인해 브라우저에 보안 메시지가 표시되므로 사용하지 마십시오.
get 메소드에 url을 사용하는 것은 안전하지 않습니다. 시스템에서 get 매개 변수를 허용하려면 리디렉션 된 페이지에서 비밀번호를 요청해야합니다.
보안이 필요한 경우 쿠키를 사용하지 마십시오.
내가 제안하는 방법은 데이터베이스에 값을 저장하고 키를 생성 한 다음 키를 사용하여 리디렉션 링크를 만들고 키가있는 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
이것은 매우 안전합니다.
일어날 수있는 일 : 웹 사이트에서 데이터를 메모리에로드하도록 매개 변수 "키"에 임의의 값을 입력하는 스크립트?
사용 후 항목을 삭제했기 때문에 발생하지 않습니다. 일반적인 오해는 get 값이 안전하지 않으며 항상 피해야한다는 것입니다.
성능 완벽을 원하면 mysql에서 테이블 엔진 유형을 "메모리"로 설정할 수 있습니다.
암호화 된 정보 전송에 대해 여기에서 언급 한 내용 외에도 타사 API를 통해 민감한 정보를 전송하는 것과 동일하게 살펴 보는 것이 좋습니다. 누군가가 요청을 스푸핑하지 않는지 어떻게 알 수 있습니까? 설정의 민감도에 따라 요청의 진위를 실제로 확인하기위한 많은 프로토콜이 있습니다. 조심하지 않으면 계정이 손상 될 수 있습니다.
동일한 서버에 있더라도 다음을 고려하십시오.
누군가가 암호화 된 키를 통해 전달되는 링크, 양식 작업 등을 따라갈 때 누군가가 귀하의 사이트의 보안 버전에 도달하기 전에이를 스니핑하지 못하게하는 것은 무엇입니까? 내가 공공 WIFI 스팟에 있었다면 너무 과도하지 않을 것입니다. 나는 귀하의 사이트 인 척하고, 요청을 내 노트북으로 다시 라우팅하고, 토큰을 가져와 방문자를 그들이 온 곳으로 다시 리디렉션 할 수 있습니다. 그들은 그것이 결함이라고 생각하고 전혀 모를 것입니다. 이제 나는 그들로 로그인하여 신용 카드로 $ 10,000 상당의 물건을 사서 다른 곳으로 배송 할 수 있습니다. 여기서주의를 기울이는 정도는 감도와 일치해야합니다.
또한 토큰이 만료되었는지 확인하십시오 (한 번만 사용, X 초 후 등).하지만 양쪽 끝에서 Post-Redirect-Get 패턴을 사용하는 것도 고려할 것입니다. 즉 :
Don't show the direct link on a page or in the form of the unsecured site, but show a link that will then redirect on the backend (and handle all the token/encryption stuff). When you arrive at the secured version, do the same (don't leave a "?token=asdfjalksfjla" parameter just sitting there in the URL; redirect it).
So, formal token-based systems were designed to solve this very problem, but implementing OAuth just for this might be overkill. Spend some time planning the potential vulnerabilities before executing. Just because it'd be really hard to guess the token doesn't mean it's impossible (or there couldn't be collisions, etc.), so plan accordingly.
You also might need a more sophisticated session management system than PHP's built-in handlers. I don't know if you can force PHP to continue a session across multiple visits (switching protocols is treated that way).
Think about using HTTPS for all pages, that's the easiest way to avoid this problem and it will improve the security of your site.
If SSL for all pages is not an option to you, then you could use this approach: Switching between HTTP and HTTPS pages with secure session-cookie. The idea behind is, that you leave the session cookie unsecure (and therefore available to HTTP and HTTPS pages), but have a second secure cookie to handle the authentication. It's a good way to separate the two concerns "maintaining the session" and "authentication".
You can manage session between HTTP to HTTPS or HTTPS to HTTP:
Transmit session ID between page using GET
POST session ID by POST
Use files to save sessions
Use Cookies for sessions
Use database to save session
Below example can be used to transmit using GET….
File : 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>’;
?>
File: https.php ……………
<?php
$sessionID = $_GET['session'];
session_id($sessionID);
session_start();
if (!empty($_SESSION['demo'])) {
echo $_SESSION['svnlabs'];
} else {
echo ‘Demo session failed’;
}
?>
IE7 : This page contains both secure and nonsecure items
You have to use relative path for all static resource on page like css, js, images, flash etc. to avoid IE message secure and nonsecure items…
IE Message
This may not be possible since the cookie seems to be getting lost. The browser you're using must think it's for a completely different domain.
What browser are you using specifically?
By default I would expect a browser to treat connections to http and https as completely different sessions. Although the convention is that http://someUrl/ and https://someUrl/ will point to the same page it isn't guaranteed. You could have completely different sites running on port 80 (http) and port 443 (https).
I don't know PHP, but generally I would not expect session variables to be freely available between secure and non-secure sessions e.g. I wouldn't expect the credit card number from my last checkout to be available to all the subsequent insecure pages I visit.
Forgive the non-authoritative answer but I thought I'd chuck in my 2c since there aren't many answers.
Do you have a dedicated IP? on some shared environments the https and the http are routed through different servers, so switching actually loses access to the cookies since they're on different domains.
solutions would be: dedicated ip
forcing https on all pages at all times
I had a similar problem, however, this solution was good for me, perhaps will help others in the future
add this in your php.ini
suhosin.session.cryptdocroot = Off
suhosin.cookie.cryptdocroot = Off
I have got a solution by this..Try it.
$_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();
Don't worry this is a normal behavior because HTTPS is meant to be secure and it is doing his part.
Below are some tricks through which you can maintain the session while switching from HTTP to HTTPS.
Transmit session ID between page using GET
POST session ID by POST
Use files to save sessions
Use Cookies for sessions
Use database to save session
Hope you will get something through my reply.
참고URL : https://stackoverflow.com/questions/441496/session-lost-when-switching-from-http-to-https-in-php
'IT TIP' 카테고리의 다른 글
| CLion : xcode에서와 같이 헤더와 구현 파일 사이를 전환하는 키보드 cmd (0) | 2020.11.27 |
|---|---|
| Django 관리 인터페이스에서 항목을 복제하는 방법이 있습니까? (0) | 2020.11.27 |
| CSS에서 정렬되지 않은 목록을 쉼표로 구분 된 텍스트로 스타일링하는 방법 (0) | 2020.11.27 |
| fromPromise가 Observable 유형에 존재하지 않습니다. (0) | 2020.11.26 |
| Xcode 누락 지원 파일 iOS 12.2 (16E227) (0) | 2020.11.26 |