최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday

티스토리 뷰


   PHP 에서 사용할 CSRF 방지용 토큰 스크립트 처리

적용 이유 : 보안 때문에.

로직 : 하단 그림 참조.
     
       매번 새로운 토큰값을 세션과 폼에 hidden으로 부여하고 submit되면 session과 post_token을 비교하여 CSRF를 방지한다.




   토큰 처리 스크립트

<? /**************************************************************************************************** * * 2015.06.18 serpiko@hanmail.net * ****************************************************************************************************/ session_start(); /**************************************************************************************************** * * Prev Token and Post Token Compare * ****************************************************************************************************/ $PREV_VToken = $_SESSION['CSRF_TK']; $POST_VToken = $_POST['VToken']; if ( !empty($PREV_VToken) && !empty($POST_VToken) ) { if( strcasecmp($PREV_VToken, $POST_VToken) != 0 ) { echo "<script>alert('토큰값에러');</script>"; }else{ echo "<script>alert('정상');</script>"; } }//end if /**************************************************************************************************** * * Token Generate * ****************************************************************************************************/ $_SESSION['CSRF_TK'] = csrfGuard_generateToken(); function csrfGuard_generateToken() { if ( function_exists("hash_algos") and in_array("sha512",hash_algos()) ) { $token=hash("sha512",mt_rand(0,mt_getrandmax())); }else{ $token=' '; for ($i=0;$i<128;++$i) { $r=mt_rand(0,35); if ($r<26) { $c=chr(ord('a')+$r); }else{ $c=chr(ord('0')+$r-26); } $token.=$c; } } return $token; }// end csrfGuard_generateToken ?> <!DOCTYPE html> <html lang="en"> <head> <!-- meta --> <meta name="Author" content="serpiko@hanmail.net" /> <meta name="description" content="http://serpiko.tistory.com" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0" /> <meta name="format-detection" content="telephone=no" /> <!-- link --> <link rel="stylesheet" type="text/css" href="" /> <link rel="shortcut icon" href="" /> <!-- script --> <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script> <title>Document</title> <style> * { box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; } </style> </head> <body> <div id="wrap"> <form method='post' action='<?=$PHP_SELF?>'> PREV_VToken : <input type='text' size='200' value='<?=$PREV_VToken?>' /> <br /> POST_VToken : <input type='text' name='' size='200' value='<?=$POST_VToken?>' /> <br /><br /> 다시할당된 토큰<br /> VToken : <input type='text' size='200' name='VToken' value='<?=$_SESSION['CSRF_TK']?>' /> <br /> <button type='submit'>확인</button> </form> </div> </body> </html>


  결과



   PHP 세션값이 엉뚱하게 입력되는 상황

아래와 같이 세션값이 요상하게 바뀌어서 입력됨 PHP 레퍼런스를 아무리 뒤져봐도 관련된 내용 없음.

ob_start, ob_flush 같은 버퍼링 처리를 해봐도 안먹힘. 심지어 session_id도 둘다 동일함.

구글링해도 비슷한 상황이 아예 존재하지 않음.

역대 버그 중 제일 황당하고 잡기 어려운 버그였다. webkit엔진 계열의 브라우저가 전부 이런것 같다.

IE에서 실행하면 정상적으로 동작한다. (이게 더 위험)

원인을 알아내기까지 본인과 더불어 베테랑 개발자도 한명 투입하여 만 5시간 이상 소요...아..

오류상황)




정상적으로 해결한 상황)




   원인

<link rel = 'shortcut icon' href='' /> 에서 href 속성이 공백일 경우 발생.






'■ 백엔드 ■ > PHP' 카테고리의 다른 글

jpgraph - php graph to image  (0) 2017.04.18
php captcha  (0) 2015.06.23
rand( [int $min, int $max] )  (0) 2015.03.03
클라이언트 소켓 함수  (0) 2015.02.04
list - 순차적인 값 바인딩  (0) 2015.01.22
댓글