사이트 내 전체검색
PHP
[함수] 다른 서버, 다른 도메인간 세션 공유 방법 1차 개선 (백업)
로빈아빠
https://cmd.kr/php/792 URL이 복사되었습니다.

본문

[함수] 다른 서버, 다른 도메인간 세션 공유 방법 1차 개선
글쓴이TarauS날 짜03-04-26 09:41조 회17148
안녕하세요...바로 밑에서 세션 공유에 대한 글을 올렸던 TarauS입니다.
제가 올렸던 글에 대해서 많은 분들이 좋은 의견들을 남겨 주셔서 그 글을 참고하여
보안부분을 조금 더 강화한 소스를 다시 올립니다.

달라진 점이라면 그전에는 세션키만을 전송하였기에 세션키만 알아내면 뚫을 수 있는 취약점이 있었으나 이번에는 세션키를 검증할 수 있는 암호화된 키를 함께 체크합니다.
암호화된 키는 사용자가 고유하게 가지는 값들을 암호화 한 값으로 따로 전송할 필요는 없습니다.(사용자의 환경값이나 아이피값을 가지고 만드는 것이기 때문에 한 사용자가 계속 사용중이라면 변하지 않을테니까요^^)
결론적으로 세션키는 예전처럼 iframe를 이용해서 전송하고 그 대신 DB와의 쿼리 부분에 사용자키도 함께 넣어 체크하도록 한 것입니다.
그리고 또한 레퍼러 및 세션키를 받아서 설정하는 파일명도 함께 체크하도록 하여 조금이라도 보안적으로 강력해지도록 노력하였습니다.
이번 수정된 소스를 보시고 또 여러 의견 남겨 주시기 바랍니다.

아~ 그리고...사용자키를 암호화하는 함수는 넣지 않았습니다... 이 부분은 여러분들이 찾아서 넣으시기 바랍니다.^^ 

설정에 관련된 것은 밑의 게시물을 열어서 보시기 바랍니다. 참고만 하시고 session.inc 파일의 소스는 지금 올린 것을 사용하세요.
http://www.phpschool.com/bbs2/inc_view.html?id=8923&code=tnt2&start=0&mode=&field=&operator=&period=&category_id=&s_que=

############## session.inc 파일 ###################################################
<?
header('P3P: CP="NOI CURa ADMa DEVa TAIa OUR DELa BUS IND PHY ONL UNI COM NAV INT DEM PRE"');
/* ------------------------------------------------------------------------ 
Table Scheme 

CREATE TABLE sessions ( 
session_key char(32) not null, 
session_expiry int(11) unsigned not null, 
session_value text not null, 
session_check varchar(250) not null,
PRIMARY KEY (session_key) 
); 
*/

#### DB 관련설정
$Cfg_DB_Host = "db_host";
$Cfg_DB_User = "db_user";
$Cfg_DB_Pass = "db_pass";
$Cfg_DB_Name = "db_name";

#### 쿠키 관련 설정
$Cfg_Cookie_Domain = ".aaa.com";

#### 보안 관련 설정
## 상대편 서버에서 현재 서버의 link.php 파일을 아이프레임으로 호출하는 파일
$Cfg_Http_Referer = "http://www.bbb.com/member/login_process.php";
## 현재 서버에서 상대편 서버로부터 넘어오는 세션키를 받는 파일
$Cfg_Php_Self = "/member/link.php"; 

#### 세션 관련 기본 설정
$SESS_DBH = ""; 
$SESS_LIFE = get_cfg_var("session.gc_maxlifetime"); 

#### 세션키의 유효성을 체크하기 위한 사용자 키
#### 사용자 키는 사용자가 고유하게 가지는 값들을 이용하여 만들어주면 됨
## 서버키를 설정 (이 값은 아무것이나 정하시면 됩니다.)
$SERVER_KEY = "~1234567890";
## 사용자의 접속 환경
$USER_AGENT = $_SERVER["HTTP_USER_AGENT"];
## 사용자의 접속 아이피
$USER_ADDR = $_SERVER["REMOTE_ADDR"];
## 사용자 키 (각각의 정보를 이용한 조합은 여러분들이 직접 정하세요. 여기서 보여드리는 것은 예시입니다.)
$USER_KEY = $USER_AGENT."||".$USER_ADDR."||".$SERVER_KEY;

#### 암호화 함수(유일한 암호화 함수를 직접 제작함)
function encrypt($key) {
## 이부분에 암호화 루틴을 넣으면 됨 ##
}

#### 암호화 함수를 통해 인코딩된 사용자 키 값
$ENCODE_KEY = encrypt($USER_KEY);

function sess_open($save_path, $session_name){ 
global $SESS_DBH,$Cfg_DB_Host,$Cfg_DB_User,$Cfg_DB_Pass,$Cfg_DB_Name;

$SESS_DBH = mysql_pconnect($Cfg_DB_Host,$Cfg_DB_User,$Cfg_DB_Pass) or die("SQL 서버에 접속할 수 없습니다."); 
mysql_select_db($Cfg_DB_Name, $SESS_DBH) or die("SQL 서버에 접속할 수 없습니다."); 

return true; 


function sess_close(){ 
return true; 


function sess_read($key){
global $SESS_DBH, $SESS_LIFE,$ENCODE_KEY;

$qry = "SELECT session_value FROM sessions WHERE session_key = '$key' AND session_check='$ENCODE_KEY' and session_expiry > " . time(); 
$qid = mysql_query($qry, $SESS_DBH); 

if (list($value) = mysql_fetch_row($qid)) { 
return $value; 


return false; 


function sess_write($key, $val){
global $SESS_DBH, $SESS_LIFE, $ENCODE_KEY; 

$expiry = time() + $SESS_LIFE; 
$value = addslashes($val);

$qry = "INSERT INTO sessions (session_key,session_expiry,session_value,session_check) VALUES ('$key', $expiry, '$value', '$ENCODE_KEY')";
$qid = mysql_query($qry, $SESS_DBH);

if (! $qid) {
$qry = "UPDATE sessions SET session_expiry = $expiry, session_value = '$value' WHERE session_key = '$key' AND session_check='$ENCODE_KEY' AND session_expiry > " . time();
$qid = mysql_query($qry, $SESS_DBH);
}

return $qid;
}

function sess_destroy($key){
global $SESS_DBH,$USER_KEY;

$qry = "DELETE FROM sessions WHERE session_key = '$key' AND session_check='$ENCODE_KEY'"; 
$qid = mysql_query($qry, $SESS_DBH); 

return $qid; 


function sess_gc($maxlifetime){
global $SESS_DBH;

$qry = "DELETE FROM sessions WHERE session_expiry < " . time(); 
$qid = mysql_query($qry, $SESS_DBH); 

return mysql_affected_rows($SESS_DBH); 


#### 세션키를 설정하는 함수
function set_session_id($SESSID){
global $HTTP_REFERER, $PHP_SELF;
## 레퍼러 및 현재 파일명을 함께 체크해서 제대로 된 요청일 때만 세션키를 설정
if($SESSID&&$HTTP_REFERER==$Cfg_Http_Referer&&$PHP_SELF==$Cfg_Php_Self) @session_id($SESSID);
}

set_session_id($SESSID);
session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc"); 
session_set_cookie_params(0, "/", $Cfg_Cookie_Domain); 
ini_set('session.cache_limiter' ,'nocache, must-revalidate-revalidate');
session_start(); 
?> 
level_1.giflevel2_1.gif3px_space.gifquery 03-04-25 19:20 |삭제
function sess_close(){ 
    return true; 

에서 mysql_close() 안해주는 이유는 머죠? 
돼는김에 중복로긴 방지도 하면 정말 좋게따 
다른 아이피이면 로긴 자체가 안돼게...
level_1.giflevel2_1.gif3px_space.gifquery 03-04-25 19:20 |삭제
수고하셨습니다 ^^
level_1.giflevel2_1.gif3px_space.gif궁금 03-04-26 02:41 |삭제
암호화라는게 결국 서버단에서는 사용자가 주는 정보가 
키가 되므로 여러가지 짬뽕해도 사용자 키만 알아내면 
뚫리지 않을까요?
level_1.giflevel2_1.gif3px_space.gifTarauS 03-04-26 09:36 |삭제
참고// 
세션을 쓸 때 쿠키를 전혀 사용하지 않을 수는 없습니다.세션을 시작하면 기본적으로 세션키가 쿠키로 등록이됩니다. 
글구 좀 더 보안에 신경을 쓴다면 세션키를 암호화할 수도 있긴 한데 지금 사용하는 방법과 별 차이가 없다고 봅니다. 왜냐면 지금 생각한 방법도 세션키와, 사용자 환경 정보와 서버키를 모두 알아야지만 알 수 있기 때문이죠.. 
여기다가 환경을 register_globals = off로 셋팅하고 넘어오는 값들을 체크하면 더 좋구여... 

궁금// 
그럴 가능성도 있긴합니다. 여기 글에는 올리지 않았지만 그럴 경우에 대비해서 서비키를 따로 두고 있습니다. 이 세션파일을 셋팅하면서 설정하는 변수 중에 서버키 변수를 따로 설정하고 이 값을 유저키랑 조합한 다음에 그걸 암호화하는 것이죠. 그렇게 된다면 뚫기가 좀더 어려워 지겠죠..
level_1.giflevel2_1.gif3px_space.gifTarauS 03-04-26 09:38 |삭제
query// 
중복로긴 기능은 그리 어렵지 않을 것이라 생각됩니다. id 필드와 ip 필드를 추가해서 id 정보와 ip정보를 담고 로그인 체크 부분에서 이 값들을 비교하면 쉽게 구현 가능하리라 봅니다. 이 부분은 이걸 이용하시는 분들의 숙제로 남겨드리겠습니다.
level_1.giflevel2_1.gif

댓글목록

등록된 댓글이 없습니다.

PHP
871 (4/18P)

Search

Copyright © Cmd 명령어 18.188.101.251