좋아, 별개의 두 가지 관련 문제가 있으며 각각 다르게 처리됩니다.
세션 고정
공격자가 사용자 세션의 세션 식별자를 명시 적으로 설정하는 곳입니다. 일반적으로 PHP에서는 URL과 같은 URL을 제공하여 수행됩니다 http://www.example.com/index...?session_name=sessionid
. 공격자가 클라이언트에 URL을 제공하면 세션 하이재킹 공격과 동일합니다.
세션 고정을 방지하는 몇 가지 방법이 있습니다 (모두 수행).
파일 session.use_trans_sid = 0
에서 설정 php.ini
하십시오. 이것은 PHP에게 URL에 식별자를 포함하지 말고 식별자에 대한 URL을 읽지 말라고 지시합니다.
파일 session.use_only_cookies = 1
에서 설정 php.ini
하십시오. 이것은 세션 식별자와 함께 URL을 사용하지 않도록 PHP에 지시합니다.
세션 상태가 변경 될 때마다 세션 ID를 재생성하십시오. 이는 다음 중 하나를 의미합니다.
- 사용자 인증
- 세션에 민감한 정보 저장
- 세션에 대한 변경
- 기타...
세션 도용
공격자가 세션 식별자를 보유하고 해당 사용자 인 것처럼 요청을 보낼 수 있습니다. 이는 공격자가 식별자를 가지고 있기 때문에 서버와 관련하여 유효한 사용자와 구분할 수는 없습니다.
세션 하이재킹을 직접 방지 할 수는 없습니다. 그러나 사용하기 매우 어렵고 어렵게하기위한 단계를 수행 할 수 있습니다.
강력한 세션 해시 식별자를 사용 session.hash_function
에서 php.ini
. PHP <5.3 인 경우 session.hash_function = 1
SHA1 에 대해 설정하십시오 . PHP> = 5.3 인 경우 session.hash_function = sha256
또는로 설정하십시오 session.hash_function = sha512
.
강력한 해시 보내기 session.hash_bits_per_character
에서 php.ini
. 이것을로 설정하십시오 session.hash_bits_per_character = 5
. 이것은 크랙 하기 어렵지 않지만 공격자가 세션 식별자를 추측하려고 할 때 차이를 만듭니다. ID는 짧지 만 더 많은 문자를 사용합니다.
함께 추가 엔트로피를 설정 session.entropy_file
하고 session.entropy_length
당신의 php.ini
파일. 전자를 session.entropy_file = /dev/urandom
엔트로피 파일에서 읽을 바이트 수로 설정합니다 session.entropy_length = 256
.
기본 PHPSESSID에서 세션 이름을 변경하십시오. 이는 호출 session_name()
하기 전에 첫 번째 매개 변수로 고유 한 식별자 이름으로 호출 하여 수행됩니다 session_start
.
당신이 경우 정말 너무 세션 이름을 회전하지만 (당신은 시간에 의존 할 경우, 예를 들어)이을 변경하면 모든 세션이 자동으로 무효화 될 것으로 조심 수 편집증. 그러나 사용 사례에 따라 옵션 일 수 있습니다 ...
세션 식별자를 자주 회전하십시오. 모든 요청 ( 이러한 수준의 보안 이 실제로 필요한 경우가 아니라면 )을 수행하지는 않지만 임의의 간격으로 수행합니다. 공격자가 세션을 가로 채면 너무 오랫동안 세션을 사용할 수 없기 때문에 자주 변경하려고합니다.
세션에 사용자 에이전트를$_SERVER['HTTP_USER_AGENT']
포함시킵니다 . 기본적으로 세션이 시작되면 다음과 같은 곳에 저장하십시오 $_SESSION['user_agent']
. 그런 다음 각 후속 요청에서 일치하는지 확인하십시오. 이것은 가짜 일 수 있으므로 100 % 신뢰할 수는 없지만 그렇지 않은 것이 좋습니다.
세션 에서 사용자의 IP 주소를$_SERVER['REMOTE_ADDR']
포함하십시오 . 기본적으로 세션이 시작되면 다음과 같은 곳에 저장하십시오 $_SESSION['remote_ip']
. 사용자에 대해 여러 IP 주소를 사용하는 일부 ISP (예 : AOL에 사용 된)에서 문제가 될 수 있습니다. 그러나 사용하면 훨씬 더 안전합니다. 공격자가 IP 주소를 위조하는 유일한 방법은 실제 사용자와 사용자 사이의 어느 시점에서 네트워크를 손상시키는 것입니다. 또한 네트워크를 손상 시키면 하이재킹 (MITM 공격 등)보다 훨씬 나빠질 수 있습니다.
자주 증가하고 비교하는 세션 및 브라우저 측에 토큰을 포함하십시오. 기본적으로 각 요청 $_SESSION['counter']++
에 대해 서버 측에서 수행하십시오. 또한 브라우저 측의 JS에서 동일한 작업을 수행하기 위해 로컬 저장소를 사용하여 무언가를하십시오. 그런 다음 요청을 보낼 때 간단히 토큰을 가져 와서 서버에서 nonce가 동일한 지 확인하십시오. 이렇게하면 공격자가 정확한 카운터를 가지지 못하기 때문에 하이재킹 된 세션을 감지 할 수 있어야합니다. 그렇지 않은 경우 2 개의 시스템이 동일한 수를 전송하고 하나의 시스템이 위조되었음을 알 수 있습니다. 모든 응용 프로그램에서 작동하지는 않지만 문제를 해결하는 한 가지 방법입니다.
둘에 대한 메모
세션 고정과 하이재킹의 차이점은 세션 식별자가 어떻게 손상되는지에 대한 것입니다. 수정시 식별자는 공격자가 미리 알고있는 값으로 설정됩니다. 하이재킹에서는 사용자가 추측하거나 도난당했습니다. 그렇지 않으면 식별자가 손상되면 두 가지의 효과는 동일합니다.
세션 ID 재생성
session_regenerate_id
이전 세션을 사용하여 세션 식별자를 재생성 할 때마다 삭제해야합니다. 이것은 코어 세션 핸들러에서 투명하게 발생합니다. 그러나 일부 사용자 지정 세션 처리기session_set_save_handler()
는이 작업 을 수행하지 않으며 이전 세션 식별자를 공격 할 수 있습니다. 사용자 정의 세션 핸들러를 사용중인 경우, 열린 식별자를 추적하고, 저장 한 식별자와 동일하지 않은 경우 이전 식별자를 명시 적으로 삭제 (또는 변경) 한 것을 확인하십시오.
기본 세션 처리기를 사용하면을 호출하면 session_regenerate_id(true)
됩니다. 이전 세션 정보가 제거됩니다. 이전 ID는 더 이상 유효하지 않으며 공격자 (또는 그 문제에 대한 다른 사람)가이를 사용하려고하면 새 세션이 생성됩니다. 그래도 사용자 정의 세션 처리기에주의하십시오 ....
세션 파괴
로그 아웃 등의 세션을 파괴하려는 경우 세션을 철저히 파괴해야합니다. 쿠키 설정 해제가 포함됩니다. 사용 session_destroy
:
function destroySession() {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
session_destroy();
}