ตกลงมีสองแยกต่างหาก แต่ปัญหาที่เกี่ยวข้องและแต่ละจัดการแตกต่างกัน
การแก้ไขเซสชัน
นี่คือที่ผู้โจมตีตั้งค่าตัวระบุเซสชันของเซสชันสำหรับผู้ใช้อย่างชัดเจน โดยปกติใน PHP มันทำโดยให้พวกเขา 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
ไฟล์ของคุณ สิ่งนี้จะบอก PHP ว่าจะไม่ใช้ URL กับตัวระบุเซสชัน
สร้างรหัสเซสชันขึ้นใหม่ทุกครั้งที่มีการเปลี่ยนแปลงสถานะของเซสชัน นั่นหมายถึงสิ่งใดสิ่งหนึ่งต่อไปนี้:
- การตรวจสอบผู้ใช้
- การจัดเก็บข้อมูลที่ละเอียดอ่อนในเซสชั่น
- การเปลี่ยนแปลงอะไรก็ได้เกี่ยวกับเซสชั่น
- ฯลฯ ...
เซสชั่นหักหลัง
นี่คือที่ผู้โจมตีได้รับการถือตัวระบุเซสชั่นและสามารถส่งคำขอราวกับว่าพวกเขาเป็นผู้ใช้ที่ ซึ่งหมายความว่าเนื่องจากผู้โจมตีมีตัวระบุพวกเขาล้วน แต่แยกไม่ออกจากผู้ใช้ที่ถูกต้องเกี่ยวกับเซิร์ฟเวอร์
คุณไม่สามารถป้องกันการจี้เซสชันโดยตรง อย่างไรก็ตามคุณสามารถใส่ขั้นตอนต่าง ๆ ในการทำให้ใช้งานได้ยากมากขึ้น
ใช้ตัวระบุแฮชเซสชั่นที่แข็งแกร่ง: ใน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']
โดยทั่วไปเมื่อเซสชั่นเริ่มต้นเก็บไว้ในสิ่งที่ต้องการ นี่อาจเป็นปัญหาจาก ISP บางรายที่ใช้ที่อยู่ IP หลายรายการสำหรับผู้ใช้ (เช่น AOL เคยทำ) แต่ถ้าคุณใช้มันจะปลอดภัยกว่ามาก วิธีเดียวที่ผู้โจมตีจะปลอมที่อยู่ IP คือการประนีประนอมเครือข่ายในบางจุดระหว่างผู้ใช้จริงกับคุณ และหากพวกเขาประนีประนอมเครือข่ายพวกเขาสามารถทำได้แย่กว่าการจี้ (เช่นการโจมตี MITM และอื่น ๆ )
รวมโทเค็นในเซสชันและทางด้านเบราว์เซอร์ที่คุณเพิ่มและเปรียบเทียบบ่อยครั้ง โดยทั่วไปสำหรับแต่ละคำขอทำ$_SESSION['counter']++
ในฝั่งเซิร์ฟเวอร์ ทำบางสิ่งบางอย่างใน JS ที่ด้านเบราว์เซอร์เพื่อทำสิ่งเดียวกัน (ใช้ที่เก็บข้อมูลในเครื่อง) จากนั้นเมื่อคุณส่งคำร้องขอเพียงรับโทเค็นที่ไม่ได้ระบุและตรวจสอบว่า nonce นั้นเหมือนกันบนเซิร์ฟเวอร์ โดยการทำเช่นนี้คุณควรจะสามารถตรวจพบเซสชั่น hijacked เนื่องจากผู้โจมตีจะไม่มีตัวนับที่แน่นอนหรือถ้าพวกเขาทำคุณจะมี 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();
}