
고급 PHP 프로그래밍 – 웹 보안 – 세션 하이재킹 방지
안녕하세요~ 😊
이번 시간에는 웹 보안의 숨은 복병, **세션 하이재킹(Session Hijacking)**에 대해 알아보겠습니다!
세션은 사용자 인증과 상태 유지를 위해 꼭 필요한 도구이지만,
만약 이 세션이 공격자에게 탈취된다면?
마치 열쇠를 잃어버린 집처럼, 내 정보와 권한이 그대로 노출될 수 있어요 😨
그렇다면 PHP로 개발할 때 어떤 방법으로 이 위험을 방지할 수 있을까요?
지금부터 예시와 함께, 안전한 세션 보안 실천법을 하나하나 알려드릴게요! 🛡️💻
세션 하이재킹이란?
세션 하이재킹은 사용자의 세션 ID를 탈취하여
해당 사용자인 것처럼 위장해 시스템에 접근하는 공격입니다.
🔓 비유하자면?
“PC방에서 로그아웃 안 하고 자리 비운 친구의 계정으로 내가 쇼핑을 막 하는 것”과 같아요.
세션 ID 탈취 방법
방법 | 설명 |
---|---|
쿠키 가로채기 | 네트워크 상에서 세션 쿠키를 스니핑 |
XSS를 통한 쿠키 탈취 | <xss-script>document.cookie</xss-script> 로 쿠키 추출 |
리퍼러 유출 | 외부 사이트로 이동 시 URL에 세션 노출 |
피싱 공격 | 가짜 로그인 페이지로 세션 유도 |
동일 브라우저 세션 복제 | 로그아웃 처리 없이 동일 기기에서 접근 |
PHP에서 세션을 안전하게 관리하려면?
✅ 1. 세션 쿠키 설정 강화
PHP에서 보안성 높은 쿠키 설정을 통해 세션 노출 위험을 줄일 수 있어요.
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => 'yourdomain.com',
'secure' => true, // HTTPS 환경에서만 전송
'httponly' => true, // JavaScript에서 접근 불가
'samesite' => 'Strict' // 크로스사이트 요청 제한
]);
session_start();
옵션 | 설명 |
---|---|
secure | HTTPS에서만 쿠키 전송 (중간자 공격 방지) |
httponly | JS에서 쿠키 접근 차단 (XSS 방지) |
samesite | CSRF 공격 방지 (Strict, Lax, None 중 선택) |
✅ 2. 세션 고정 방지 (Session Fixation)
로그인 시 무조건 세션 ID를 새로 생성해 주세요!
// 로그인 성공 시
session_regenerate_id(true);
기존 세션 ID를 무효화하고 새로운 ID로 갱신해
세션 고정 공격(Session Fixation)을 막을 수 있어요!
✅ 3. 사용자 환경 검증 (User Agent, IP 등)
세션을 로그인한 사용자 환경에 묶어 두면 탈취 위험을 줄일 수 있어요.
session_start();
$ua = $_SERVER['HTTP_USER_AGENT'];
$ip = $_SERVER['REMOTE_ADDR'];
if (!isset($_SESSION['agent'])) {
$_SESSION['agent'] = $ua;
$_SESSION['ip'] = $ip;
} else {
if ($_SESSION['agent'] !== $ua || $_SESSION['ip'] !== $ip) {
session_destroy();
die("비정상적인 접근이 감지되었습니다.");
}
}
IP나 브라우저 정보가 바뀌면 세션을 파기해서 공격을 차단할 수 있어요.
✅ 4. 세션 저장소 보안 강화
PHP는 기본적으로 세션을 서버의 파일 시스템에 저장해요.
주의할 점은?
/tmp
같은 공용 디렉터리에서 권한 문제가 발생할 수 있으므로,php.ini
에서 세션 저장 경로를 안전한 디렉터리로 설정해 주세요.
session.save_path = "/var/lib/php/sessions"
권한도 안전하게!
chmod 700 /var/lib/php/sessions
chown www-data:www-data /var/lib/php/sessions
✅ 5. 세션 타임아웃 설정
세션을 무한히 유지하지 않고 일정 시간 뒤에 만료시키는 것이 중요해요.
// 예: 30분 후 세션 만료
$expire = 1800;
if (!isset($_SESSION['LAST_ACTIVITY'])) {
$_SESSION['LAST_ACTIVITY'] = time();
} elseif (time() - $_SESSION['LAST_ACTIVITY'] > $expire) {
session_unset();
session_destroy();
die("세션이 만료되었습니다. 다시 로그인해주세요.");
}
$_SESSION['LAST_ACTIVITY'] = time();
장시간 방치된 세션은 해커에게 노출될 확률도 높아요!
✅ 6. 세션 ID 직접 전달 금지
세션 ID를 URL 파라미터로 전달하는 방식은 절대 피해야 해요!
❌ 이런 식은 금지!
https://example.com?PHPSESSID=abcd1234
브라우저 히스토리, 리퍼러, 로그 등에 쉽게 노출돼요!
실전 예제: 로그인 후 안전한 세션 구성
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict'
]);
session_start();
// 로그인 시
if (login_success()) {
session_regenerate_id(true); // 세션 고정 방지
$_SESSION['user_id'] = $user['id'];
$_SESSION['agent'] = $_SERVER['HTTP_USER_AGENT'];
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
$_SESSION['LAST_ACTIVITY'] = time();
}
주의해야 할 점 ✅
항목 | 설명 |
---|---|
쿠키 보안 속성 설정 | secure , httponly , samesite 필수 적용 |
세션 고정 방지 | 로그인 시 session_regenerate_id() 호출 |
사용자 환경 고정 | IP 또는 User Agent로 세션 묶기 |
타임아웃 설정 | 일정 시간 이후 세션 자동 종료 |
URL에 세션 노출 금지 | ?PHPSESSID= 금지! |
요약 🎯
방어 방법 | 설명 |
---|---|
세션 쿠키 설정 | 외부 노출 최소화 |
세션 ID 재생성 | 고정된 세션 공격 방지 |
환경 매칭 | 다른 사용자 접근 차단 |
저장 경로 안전화 | 서버 내부 보안 강화 |
시간 제한 | 오랜 시간 접속 방치 방지 |
마무리하며 😊
세션 하이재킹은 눈에 보이지 않지만,
한순간의 방심으로 서버 전체의 보안을 위협할 수 있는 공격입니다.
하지만 지금까지 알려드린 보안 전략을 꼼꼼하게 적용한다면,
여러분의 웹 서비스는 외부 침입자에게 철통같이 잠긴 성벽이 될 거예요! 🏰
💡 기억하세요!
“세션 = 열쇠! 안전하게 잠그지 않으면 도둑이 들어올 수 있다”
다음 시간에는 경로 탐색(Directory Traversal) 방지에 대해 안내해 드릴게요!
오늘도 보안 철저한 개발자 되세요~ 💻🔐✨