วิธีที่ดีที่สุดในการป้องกันการจี้เซสชันคืออะไร?


124

โดยเฉพาะอย่างยิ่งเมื่อใช้คุกกี้เซสชันไคลเอนต์เพื่อระบุเซสชันบนเซิร์ฟเวอร์

เป็นคำตอบที่ดีที่สุดในการใช้การเข้ารหัส SSL / HTTPS สำหรับทั้งเว็บไซต์และคุณมีการรับประกันที่ดีที่สุดว่าจะไม่มีผู้ใดที่อยู่ในการโจมตีระดับกลางสามารถดักจับคุกกี้เซสชันไคลเอ็นต์ที่มีอยู่ได้?

และอาจดีที่สุดเป็นอันดับสองในการใช้การเข้ารหัสบางประเภทกับค่าเซสชันที่เก็บไว้ในคุกกี้เซสชันของคุณ?

หากผู้ใช้ที่ประสงค์ร้ายสามารถเข้าถึงเครื่องได้พวกเขายังสามารถดูที่ระบบไฟล์เพื่อดึงคุกกี้เซสชันที่ถูกต้องและใช้เพื่อจี้เซสชันได้หรือไม่?

คำตอบ:


140

การเข้ารหัสค่าเซสชันจะมีผลเป็นศูนย์ คุกกี้เซสชันเป็นค่าที่กำหนดเองอยู่แล้วการเข้ารหัสจะสร้างค่าอื่นที่สามารถดมได้โดยพลการ

ทางออกเดียวที่แท้จริงคือ HTTPS หากคุณไม่ต้องการทำ SSL ทั้งไซต์ของคุณ (บางทีคุณอาจมีปัญหาด้านประสิทธิภาพ) คุณอาจหลีกเลี่ยงได้โดยมีเพียง SSL เท่านั้นที่ปกป้องพื้นที่ที่ละเอียดอ่อน ก่อนอื่นให้ตรวจสอบว่าหน้าเข้าสู่ระบบของคุณเป็น HTTPS เมื่อผู้ใช้เข้าสู่ระบบให้ตั้งค่าคุกกี้ที่ปลอดภัย (หมายความว่าเบราว์เซอร์จะส่งผ่านลิงก์ SSL เท่านั้น) นอกเหนือจากคุกกี้เซสชันปกติ จากนั้นเมื่อผู้ใช้เยี่ยมชมพื้นที่ที่ "ละเอียดอ่อน" ของคุณให้เปลี่ยนเส้นทางไปยัง HTTPS และตรวจสอบว่ามีคุกกี้ที่ปลอดภัยนั้นอยู่หรือไม่ ผู้ใช้จริงจะมีนักจี้เซสชันจะไม่

แก้ไข : คำตอบนี้เขียนขึ้นครั้งแรกในปี 2008 ตอนนี้เป็นปี 2016 และไม่มีเหตุผลที่จะไม่มี SSL ทั่วทั้งไซต์ของคุณ ไม่มี HTTP ข้อความธรรมดาอีกต่อไป!


28
HTTPS จะป้องกันการดมกลิ่นเท่านั้น แต่ถ้าคุณมี XSS หรือรหัสเซสชันสามารถเดาได้ง่ายหรือคุณเสี่ยงต่อการตรึงเซสชันหรือพื้นที่จัดเก็บ ID เซสชันของคุณอ่อนแอ (การแทรก SQL?) SSL จะไม่ได้รับการปรับปรุงเลย
Calimo

5
@ Josh หากผู้ใช้ที่ประสงค์ร้ายสามารถเข้าถึงเครื่องได้พวกเขายังสามารถดูที่ระบบไฟล์เพื่อดึงคุกกี้เซสชันที่ถูกต้องและใช้เพื่อจี้เซสชันได้?
Pacerier

72
หากผู้ไม่ประสงค์ดีมีสิทธิ์เข้าถึงระบบไฟล์ทางกายภาพพวกเขาไม่จำเป็นต้องจี้เซสชัน
Josh Hinman

25
@ Josh ไม่เป็นความจริงบางครั้งผู้ใช้มีเวลา จำกัด ในการเข้าถึงระบบไฟล์ ลองนึกภาพแล็ปท็อปที่เพื่อนร่วมงานปลดล็อกทิ้งไว้ตอนนี้สิ่งที่ฉันต้องทำคือไปที่แล็ปท็อปเครื่องนั้นติดตั้งปลั๊กอิน EditThisCookie คว้าคุกกี้ของเขาที่ plus.google.com โดยใช้คุณลักษณะการส่งออก EditThisCookie และตอนนี้ฉันมีบัญชีของเขาแล้ว ใช้เวลา: 18 วินาที
Pacerier

1
ฉันค่อนข้างแน่ใจว่า Google จะมีฟีเจอร์ความปลอดภัยบางอย่างในตัวเนื่องจากนี่เป็นสิ่งแรกที่คุณจะนึกถึงเมื่อพูดถึงการจี้เซสชัน
xorinzor

42

SSL ช่วยในการโจมตีด้วยการดมกลิ่นเท่านั้น หากผู้โจมตีสามารถเข้าถึงเครื่องของคุณฉันจะถือว่าพวกเขาสามารถคัดลอกคุกกี้ที่ปลอดภัยของคุณได้เช่นกัน

อย่างน้อยที่สุดตรวจสอบให้แน่ใจว่าคุกกี้เก่าสูญเสียคุณค่าหลังจากนั้นสักครู่ แม้กระทั่งการโจมตีด้วยการหักหลังที่ประสบความสำเร็จก็จะถูกขัดขวางเมื่อคุกกี้หยุดทำงาน หากผู้ใช้มีคุกกี้จากเซสชันที่ลงชื่อเข้าใช้นานกว่าหนึ่งเดือนให้ป้อนรหัสผ่านอีกครั้ง ตรวจสอบให้แน่ใจว่าเมื่อใดก็ตามที่ผู้ใช้คลิกลิงก์ "ออกจากระบบ" ของไซต์ของคุณ UUID ของเซสชันเก่าจะไม่สามารถใช้งานได้อีก

ฉันไม่แน่ใจว่าแนวคิดนี้จะใช้ได้หรือไม่ แต่ต่อไปนี้: เพิ่มหมายเลขซีเรียลลงในคุกกี้เซสชันของคุณอาจเป็นสตริงแบบนี้:

SessionUUID, Serial Num, วันที่ / เวลาปัจจุบัน

เข้ารหัสสตริงนี้และใช้เป็นคุกกี้เซสชันของคุณ เปลี่ยนหมายเลขซีเรียลเป็นประจำ - บางทีเมื่อคุกกี้มีอายุ 5 นาทีแล้วจึงออกคุกกี้ใหม่ คุณสามารถออกใหม่ได้ในทุกการดูหน้าเว็บหากต้องการ ที่ฝั่งเซิร์ฟเวอร์ให้บันทึกหมายเลขซีเรียลล่าสุดที่คุณออกให้สำหรับเซสชันนั้น หากมีผู้ส่งคุกกี้ที่มีหมายเลขซีเรียลไม่ถูกต้องหมายความว่าผู้โจมตีอาจใช้คุกกี้ที่ดักฟังไว้ก่อนหน้านี้จึงทำให้ UUID ของเซสชันเป็นโมฆะและขอให้ผู้ใช้ป้อนรหัสผ่านอีกครั้งจากนั้นจึงออกคุกกี้ใหม่

โปรดจำไว้ว่าผู้ใช้ของคุณอาจมีคอมพิวเตอร์มากกว่าหนึ่งเครื่องดังนั้นพวกเขาอาจมีเซสชันที่ใช้งานอยู่มากกว่าหนึ่งเซสชัน อย่าทำบางสิ่งที่บังคับให้พวกเขาเข้าสู่ระบบอีกครั้งทุกครั้งที่สลับระหว่างคอมพิวเตอร์


ฉันรู้ว่านี่เป็นโพสต์เก่า แต่อยากจะรวมไว้ว่าหากผู้โจมตีต้องการจี้เซสชันภายในหน้าต่างที่กำหนดโดย "หมายเลขซีเรียล" สิ่งนี้จะไม่ส่งผลกระทบต่อเขา
ขยี้

@crush แต่จากนั้นผู้โจมตีจะถูกล็อคหลังจากหน้าต่างที่กำหนดใช่ไหม? ดังนั้นอย่างน้อยที่สุดหน้าต่างการโจมตีก็มีขนาดเล็ก (เอ่อ)
Johanneke

2
ปัญหาเดียวคือหากผู้ใช้ออกจากเว็บไซต์ของคุณเป็นเวลา 5 นาทีพวกเขาจะต้องเข้าสู่ระบบอีกครั้ง
elipoultorak

21

คุณคิดอ่านหนังสือเกี่ยวกับความปลอดภัยของ PHP หรือไม่? ขอแนะนำ

ฉันประสบความสำเร็จอย่างมากกับวิธีการต่อไปนี้สำหรับไซต์ที่ไม่ได้รับการรับรอง SSL

  1. ยกเลิกการอนุญาตหลายเซสชันภายใต้บัญชีเดียวกันตรวจสอบให้แน่ใจว่าคุณไม่ได้ตรวจสอบสิ่งนี้ด้วยที่อยู่ IP เพียงอย่างเดียว ค่อนข้างตรวจสอบโดยโทเค็นที่สร้างขึ้นเมื่อเข้าสู่ระบบซึ่งเก็บไว้กับเซสชันของผู้ใช้ในฐานข้อมูลเช่นเดียวกับที่อยู่ IP HTTP_USER_AGENT เป็นต้น

  2. การใช้การเชื่อมโยงหลายมิติตามความสัมพันธ์สร้างลิงก์ (เช่นhttp://example.com/secure.php?token=2349df98sdf98a9asdf8fas98df8 ) ลิงก์นี้ต่อท้ายด้วยสตริง MD5 แบบสุ่มแบบ x-BYTE (ขนาดที่ต้องการ) เมื่อเปลี่ยนเส้นทางหน้าที่สร้างแบบสุ่ม โทเค็นสอดคล้องกับหน้าที่ร้องขอ

    • เมื่อโหลดซ้ำจะมีการตรวจสอบหลายครั้ง
    • ที่อยู่ IP ต้นทาง
    • HTTP_USER_AGENT
    • โทเค็นเซสชัน
    • คุณเข้าใจแล้ว
  3. คุกกี้การตรวจสอบสิทธิ์เซสชันช่วงอายุสั้น ดังที่โพสต์ไว้ข้างต้นคุกกี้ที่มีสตริงที่ปลอดภัยซึ่งเป็นหนึ่งในการอ้างอิงโดยตรงถึงความถูกต้องของเซสชันเป็นความคิดที่ดี กำหนดให้หมดอายุทุกๆ x นาทีออกโทเค็นนั้นใหม่และซิงค์เซสชันใหม่กับข้อมูลใหม่ หากมีการจับคู่ข้อมูลผิดพลาดให้ล็อกผู้ใช้ออกจากระบบหรือให้พวกเขาตรวจสอบสิทธิ์เซสชันของตนอีกครั้ง

ฉันไม่ได้เป็นผู้เชี่ยวชาญในเรื่องนี้ฉันมีประสบการณ์เล็กน้อยในหัวข้อนี้หวังว่าบางส่วนจะช่วยให้ทุกคนที่นั่น


4
มีหนังสือที่คุณอยากแนะนำไหม?
Rikki

1
โดยเฉพาะอย่างยิ่งเมื่อ OP ไม่ได้ระบุอะไรเกี่ยวกับ PHP โดยเฉพาะฉันจะบอกว่าควรดูแค่หนังสือความปลอดภัยทั่วไป (โดยเฉพาะอย่างยิ่งเมื่อความปลอดภัยระหว่างภาษาต่างๆแตกต่างกันในรายละเอียดการใช้งานเท่านั้น แต่แนวคิดยังคงเหมือนเดิม)
matts1

ในปี 2560 แม้กระทั่ง facebook / gmail เป็นต้นอนุญาตให้มีหลายเซสชันภายใต้บัญชีเดียวกัน (โดยเฉพาะกับอุปกรณ์มือถือ) เว้นแต่คุณจะเกลียดชังผู้ใช้ของคุณ # 1 ค่อนข้างล้าสมัย
cowbert

20
// Collect this information on every request
$aip = $_SERVER['REMOTE_ADDR'];
$bip = $_SERVER['HTTP_X_FORWARDED_FOR'];
$agent = $_SERVER['HTTP_USER_AGENT'];
session_start();

// Do this each time the user successfully logs in.
$_SESSION['ident'] = hash("sha256", $aip . $bip . $agent);

// Do this every time the client makes a request to the server, after authenticating
$ident = hash("sha256", $aip . $bip . $agent);
if ($ident != $_SESSION['ident'])
{
    end_session();
    header("Location: login.php");
    // add some fancy pants GET/POST var headers for login.php, that lets you
    // know in the login page to notify the user of why they're being challenged
    // for login again, etc.
}

สิ่งนี้คือการบันทึกข้อมูล 'ตามบริบท' เกี่ยวกับเซสชันของผู้ใช้ซึ่งเป็นส่วนของข้อมูลที่ไม่ควรเปลี่ยนแปลงในช่วงชีวิตของเซสชันเดียว ผู้ใช้จะไม่ได้ใช้คอมพิวเตอร์ในสหรัฐอเมริกาและจีนในเวลาเดียวกันใช่ไหม? ดังนั้นหากที่อยู่ IP เปลี่ยนแปลงอย่างกะทันหันภายในเซสชันเดียวกันซึ่งมีนัยอย่างมากถึงความพยายามในการจี้เซสชันดังนั้นคุณจึงรักษาความปลอดภัยเซสชันโดยการสิ้นสุดเซสชันและบังคับให้ผู้ใช้ตรวจสอบสิทธิ์อีกครั้ง สิ่งนี้ขัดขวางความพยายามในการแฮ็กผู้โจมตียังถูกบังคับให้เข้าสู่ระบบแทนที่จะเข้าถึงเซสชัน แจ้งให้ผู้ใช้ทราบถึงความพยายาม (ajax ขึ้นเล็กน้อย) และ vola ผู้ใช้ที่ได้รับข้อมูล + รำคาญเล็กน้อยและเซสชัน / ข้อมูลของพวกเขาได้รับการปกป้อง

เราทุ่ม User Agent และ X-FORWARDED-FOR เพื่อพยายามอย่างเต็มที่เพื่อจับภาพเซสชันที่เป็นเอกลักษณ์สำหรับระบบที่อยู่เบื้องหลังพร็อกซี / เครือข่าย คุณอาจสามารถใช้ข้อมูลเพิ่มเติมได้จากนั้นอย่าลังเลที่จะสร้างสรรค์

มันไม่ 100% แต่มันก็ค่อนข้างมีประสิทธิภาพ

มีอะไรอีกมากมายที่คุณสามารถทำได้เพื่อป้องกันเซสชันหมดอายุเมื่อผู้ใช้ออกจากเว็บไซต์และกลับมาบังคับให้พวกเขาเข้าสู่ระบบอีกครั้ง คุณสามารถตรวจจับผู้ใช้ที่ออกไปและกลับมาโดยการจับ HTTP_REFERER ว่าง (โดเมนถูกพิมพ์ลงในแถบ URL) หรือตรวจสอบว่าค่าใน HTTP_REFERER เท่ากับโดเมนของคุณหรือไม่ (ผู้ใช้คลิกลิงก์ภายนอก / ที่สร้างขึ้นเพื่อไปยัง เว็บไซต์).

หมดอายุเซสชันอย่าปล่อยให้มีการใช้งานไปเรื่อย ๆ

อย่าพึ่งคุกกี้เพราะอาจถูกขโมยได้ซึ่งเป็นหนึ่งในเวกเตอร์ของการโจมตีสำหรับการแย่งชิงเซสชัน


3
ฉันเคยเจอสถานการณ์ที่ ISP บางราย (ค่อนข้างใหญ่ แต่ในทางเทคนิคย้อนกลับ) จะเปลี่ยน IP ของเบราว์เซอร์ของผู้ใช้เป็นครั้งคราวโดยพิจารณาจากการกำหนดเส้นทางการเชื่อมต่อของผู้ใช้ใหม่ สิ่งนี้ทำให้การตรวจสอบ REMOTE_ADDR ส่งคืนค่าลบเท็จให้เรา
goofballLogic

ทำไมต้องสร้างแฮช? $_SESSION['ident'] = $aip . $bip . $agent;ก็จะปลอดภัยเช่นเดียวกัน
Dan Bray

2
หากคุณมีผู้ใช้มือถือที่ใช้เว็บไซต์ของคุณในระหว่างเดินทางและย้ายจากจุดเชื่อมต่อหนึ่งไปยังอีกจุดหนึ่ง IP ของพวกเขาจะเปลี่ยนไปเรื่อย ๆ และพวกเขาจะออกจากระบบบัญชีของพวกเขา
Kareem

สิ่งที่เกี่ยวกับพร็อกซีและ VPN ทุกคนที่ใช้พร็อกซี TOR จะถูกนำออกจากระบบบัญชีของตนอย่างต่อเนื่อง .. ในความเป็นจริงทุกสองสามนาที
Bradley

แม้ว่าคุณจะมองข้ามสิ่งนั้นไป แต่ไคลเอนต์ก็สามารถจัดการที่อยู่ IP ได้ดังนั้นสิ่งนี้จะไม่ช่วยขัดขวางผู้โจมตีได้มากนัก
Bradley

9

ลองใช้โปรโตคอล Secure Cookie ที่อธิบายไว้ในเอกสารนี้โดย Liu, Kovacs, Huang และ Gouda:

ตามที่ระบุไว้ในเอกสาร:

โปรโตคอลคุกกี้ที่ปลอดภัยซึ่งทำงานระหว่างไคลเอนต์และเซิร์ฟเวอร์จำเป็นต้องให้บริการสี่อย่างต่อไปนี้: การพิสูจน์ตัวตนการรักษาความลับความสมบูรณ์และการต่อต้านการเล่นซ้ำ

สำหรับความสะดวกในการใช้งาน:

ในแง่ของประสิทธิภาพโปรโตคอลของเราไม่เกี่ยวข้องกับการค้นหาฐานข้อมูลหรือการเข้ารหัสคีย์สาธารณะ ในแง่ของความสามารถในการปรับใช้โปรโตคอลของเราสามารถปรับใช้บนเว็บเซิร์ฟเวอร์ที่มีอยู่ได้อย่างง่ายดายและไม่ต้องการการเปลี่ยนแปลงใด ๆ ในการระบุคุกกี้อินเทอร์เน็ต

กล่าวโดยย่อคือปลอดภัยน้ำหนักเบาเหมาะกับฉันมาก


9
ลิงค์ของคุณเป็นข้อมูลจำเพาะของโปรโตคอล - คุณมีลิงค์ไปยังการนำไปใช้งานหรือไม่? นั่นจะดีมาก - ขอบคุณ
Adam

9

ไม่มีวิธีใดที่จะป้องกันการลักลอบเซสชันได้ 100% แต่ด้วยวิธีการบางอย่างเราสามารถลดเวลาที่ผู้โจมตีจะขโมยเซสชันได้

วิธีป้องกันการขโมยเซสชัน:

1 - ใช้เซสชันกับใบรับรอง ssl เสมอ

2 - ส่งคุกกี้เซสชันโดยตั้งค่า httponly เป็น true เท่านั้น (ป้องกันไม่ให้ javascript เข้าถึงคุกกี้เซสชัน)

2 - ใช้รหัสสร้างเซสชันใหม่เมื่อเข้าสู่ระบบและออกจากระบบ (หมายเหตุ: อย่าใช้เซสชันสร้างใหม่ในแต่ละคำขอเพราะหากคุณมีคำขอ ajax ติดต่อกันคุณจะมีโอกาสสร้างหลายเซสชันได้)

3 - ตั้งค่าระยะหมดเวลาของเซสชัน

4 - จัดเก็บตัวแทนผู้ใช้เบราว์เซอร์ในตัวแปร $ _SESSION เปรียบเทียบกับ $ _SERVER ['HTTP_USER_AGENT'] ในแต่ละคำขอ

5 - ตั้งค่าคุกกี้โทเค็นและตั้งเวลาหมดอายุของคุกกี้นั้นเป็น 0 (จนกว่าเบราว์เซอร์จะปิด) สร้างค่าคุกกี้สำหรับแต่ละคำขอ (สำหรับคำขอ ajax อย่าสร้างโทเค็นคุกกี้ใหม่) EX:

    //set a token cookie if one not exist
    if(!isset($_COOKIE['user_token'])){
                    //generate a random string for cookie value
        $cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM));

        //set a session variable with that random string
        $_SESSION['user_token'] = $cookie_token;
        //set cookie with rand value
        setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true);
    }

    //set a sesison variable with request of www.example.com
    if(!isset($_SESSION['request'])){
        $_SESSION['request'] = -1;
    }
    //increment $_SESSION['request'] with 1 for each request at www.example.com
    $_SESSION['request']++;

    //verify if $_SESSION['user_token'] it's equal with $_COOKIE['user_token'] only for $_SESSION['request'] > 0
    if($_SESSION['request'] > 0){

        // if it's equal then regenerete value of token cookie if not then destroy_session
        if($_SESSION['user_token'] === $_COOKIE['user_token']){
            $cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM));

            $_SESSION['user_token'] = $cookie_token;

            setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true);
        }else{
            //code for session_destroy
        }

    }

            //prevent session hijaking with browser user agent
    if(!isset($_SESSION['user_agent'])){
        $_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
    }

    if($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']){
      die('session hijaking - user agent');
    }

หมายเหตุ: อย่าสร้างคุกกี้โทเค็นใหม่ด้วยหมายเหตุการร้องขอ ajax: โค้ดด้านบนเป็นตัวอย่าง หมายเหตุ: หากผู้ใช้ออกจากระบบโทเค็นคุกกี้จะต้องถูกทำลายเช่นเดียวกับเซสชัน

6 - ไม่ใช่เรื่องดีที่จะใช้ ip ของผู้ใช้เพื่อป้องกันการขโมยเซสชันเนื่องจากผู้ใช้บางราย ip เปลี่ยนไปตามคำขอแต่ละครั้ง ที่มีผลต่อผู้ใช้ที่ถูกต้อง

7 - โดยส่วนตัวแล้วฉันเก็บข้อมูลเซสชันไว้ในฐานข้อมูลขึ้นอยู่กับคุณว่าคุณใช้วิธีใด

หากคุณพบข้อผิดพลาดในแนวทางของฉันโปรดแก้ไขฉัน หากคุณมีวิธีอื่น ๆ ในการป้องกันการแอบดูเซสชันโปรดบอกฉัน


สวัสดีฉันพยายามป้องกันการจี้เซสชัน (ใน ASP.NET) และพิจารณาขั้นตอนข้างต้นทั้งหมดที่คุณแนะนำ มันใช้งานได้โดยประมาณ แต่เมื่อฉันใช้โหมด InPrivateBrowsing / ไม่ระบุตัวตนของเบราว์เซอร์เซสชันจะถูก Hijacked คุณช่วยแนะนำสิ่งเพิ่มเติมที่จะเพิ่มในสตริง sessionId ได้ไหม
Vishwanath Mishra

4

ตรวจสอบให้แน่ใจว่าคุณไม่ได้ใช้จำนวนเต็มเพิ่มสำหรับรหัสเซสชัน ดีกว่ามากในการใช้ GUID หรือสตริงอักขระที่สร้างแบบสุ่มอื่น ๆ


3

มีหลายวิธีในการสร้างการป้องกันจากการจี้เซสชันอย่างไรก็ตามทั้งหมดนี้อาจลดความพึงพอใจของผู้ใช้หรือไม่ปลอดภัย

  • การตรวจสอบ IP และ / หรือ X-FORWARDED-FOR ทำงานเหล่านี้และค่อนข้างปลอดภัย ... แต่ลองนึกภาพความเจ็บปวดของผู้ใช้ พวกเขามาที่สำนักงานพร้อม WiFi พวกเขาได้รับที่อยู่ IP ใหม่และสูญเสียเซสชัน ต้องเข้าสู่ระบบอีกครั้ง

  • การตรวจสอบตัวแทนผู้ใช้ เช่นเดียวกับข้างต้นเบราว์เซอร์เวอร์ชันใหม่หมดและคุณจะเสียเซสชัน นอกจากนี้ยังง่ายต่อการ "แฮ็ก" เป็นเรื่องเล็กน้อยสำหรับแฮกเกอร์ที่จะส่งสตริง UA ปลอม

  • โทเค็น localStorage เมื่อเข้าสู่ระบบสร้างโทเค็นเก็บไว้ในที่เก็บข้อมูลของเบราว์เซอร์และจัดเก็บไว้ในคุกกี้ที่เข้ารหัส (เข้ารหัสทางฝั่งเซิร์ฟเวอร์) สิ่งนี้ไม่มีผลข้างเคียงสำหรับผู้ใช้ (localStorage ยังคงมีอยู่ผ่านการอัพเกรดเบราว์เซอร์) มันไม่ปลอดภัยเท่า - มันเป็นเพียงการรักษาความปลอดภัยผ่านความสับสน นอกจากนี้คุณสามารถเพิ่มตรรกะ (การเข้ารหัส / ถอดรหัส) ให้กับ JS เพื่อปิดบังเพิ่มเติมได้

  • การออกคุกกี้ใหม่ นี่น่าจะเป็นวิธีที่เหมาะสมที่จะทำ เคล็ดลับคืออนุญาตให้ลูกค้าใช้คุกกี้ได้ครั้งละหนึ่งรายการเท่านั้น ดังนั้นผู้ใช้ที่ใช้งานอยู่จะมีการออกคุกกี้ใหม่ทุกชั่วโมงหรือน้อยกว่านั้น คุกกี้เก่าจะไม่ถูกต้องหากมีการออกคุกกี้ใหม่ ยังคงมีการแฮ็กอยู่ แต่ทำได้ยากกว่ามากทั้งแฮ็กเกอร์หรือผู้ใช้ที่ถูกต้องจะถูกปฏิเสธ


1

ให้เราพิจารณาว่าในระหว่างขั้นตอนการเข้าสู่ระบบไคลเอนต์และเซิร์ฟเวอร์สามารถตกลงค่าเกลือลับได้ หลังจากนั้นเซิร์ฟเวอร์จะให้ค่าการนับในการอัปเดตแต่ละครั้งและคาดว่าไคลเอนต์จะตอบสนองด้วยแฮชของ (จำนวนเกลือลับ +) นักจี้ที่มีศักยภาพไม่มีทางที่จะได้รับค่าเกลือลับนี้และไม่สามารถสร้างแฮชถัดไปได้


3
แต่คุณต้องการเก็บเกลือนี้ไว้ที่ฝั่งลูกค้าอย่างไรเพื่อไม่ให้ใครขโมยได้?
Dcortez

1

AFAIK วัตถุเซสชันไม่สามารถเข้าถึงได้ที่ไคลเอนต์เนื่องจากถูกเก็บไว้ที่เว็บเซิร์ฟเวอร์ อย่างไรก็ตามรหัสเซสชันจะถูกจัดเก็บเป็นคุกกี้และช่วยให้เว็บเซิร์ฟเวอร์ติดตามเซสชันของผู้ใช้

เพื่อป้องกันการจี้เซสชันโดยใช้รหัสเซสชันคุณสามารถจัดเก็บสตริงที่แฮชไว้ภายในวัตถุเซสชันโดยใช้การรวมกันของสองแอตทริบิวต์รีโมต addr และพอร์ตระยะไกลที่สามารถเข้าถึงได้ที่เว็บเซิร์ฟเวอร์ภายในออบเจ็กต์คำขอ แอตทริบิวต์เหล่านี้ผูกเซสชันผู้ใช้กับเบราว์เซอร์ที่ผู้ใช้ล็อกอิน

หากผู้ใช้เข้าสู่ระบบจากเบราว์เซอร์อื่นหรือโหมดไม่ระบุตัวตนบนระบบเดียวกันที่อยู่ IP จะยังคงเหมือนเดิม แต่พอร์ตจะแตกต่างกัน ดังนั้นเมื่อเข้าถึงแอปพลิเคชันผู้ใช้จะได้รับการกำหนดรหัสเซสชันอื่นโดยเว็บเซิร์ฟเวอร์

ด้านล่างนี้คือรหัสที่ฉันได้ติดตั้งและทดสอบโดยการคัดลอกรหัสเซสชันจากเซสชันหนึ่งไปยังอีกเซสชันหนึ่ง มันทำงานได้ดีทีเดียว หากมีช่องโหว่โปรดแจ้งให้เราทราบว่าคุณจำลองอย่างไร

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    HttpSession session = request.getSession();
    String sessionKey = (String) session.getAttribute("sessionkey");
    String remoteAddr = request.getRemoteAddr();
    int remotePort = request.getRemotePort();
    String sha256Hex = DigestUtils.sha256Hex(remoteAddr + remotePort);
    if (sessionKey == null || sessionKey.isEmpty()) {
        session.setAttribute("sessionkey", sha256Hex);
        // save mapping to memory to track which user attempted
        Application.userSessionMap.put(sha256Hex, remoteAddr + remotePort);
    } else if (!sha256Hex.equals(sessionKey)) {
        session.invalidate();
        response.getWriter().append(Application.userSessionMap.get(sessionKey));
        response.getWriter().append(" attempted to hijack session id ").append(request.getRequestedSessionId()); 
        response.getWriter().append("of user ").append(Application.userSessionMap.get(sha256Hex));
        return;
    }
    response.getWriter().append("Valid Session\n");
}

ฉันใช้อัลกอริทึม SHA-2 เพื่อแฮชค่าโดยใช้ตัวอย่างที่ให้ไว้ที่SHA-256 Hashing ที่ baeldung

รอความคิดเห็นของคุณ


@zaph ฉันขอโทษ แต่ฉันไม่ได้เพิ่มคำตอบเพื่อรับตัวแทน ประเด็นนี้ไม่ใช่การเข้ารหัส SHA-2 เช่นกัน แต่ความจริงที่ว่าฉันสามารถตรวจจับการใช้งานคุกกี้รหัสเซสชันของผู้ใช้อื่นในเซสชันของผู้ใช้รายอื่นได้นั่นคือการไฮแจ็คเซสชันเหมือนในคำถามเดิม ฉันทดสอบโซลูชันของฉันและพบว่าใช้งานได้ แต่ฉันไม่ใช่ผู้เชี่ยวชาญในเรื่องนี้ดังนั้นฉันจึงอยากให้ชุมชนตรวจสอบว่าคำตอบของฉันดีพอหรือไม่ บางทีคุณอาจเห็นว่าข้อมูลโค้ดของฉันใช้ทำอะไรและตัดสินใจว่าจะตอบคำถามหรือไม่ ขอบคุณ!
Jzf

@zaph ขอบคุณที่ชี้จุดผิดพลาด ฉันได้อัปเดตคำตอบของฉันตามคำแนะนำของคุณ โปรดลบการโหวตลงของคุณหากคุณคิดว่าคำตอบมีประโยชน์
Jzf

0

เพื่อลดความเสี่ยงคุณสามารถเชื่อมโยง IP ต้นทางกับเซสชันได้ ด้วยวิธีนี้ผู้โจมตีจะต้องอยู่ในเครือข่ายส่วนตัวเดียวกันจึงจะสามารถใช้เซสชันได้

การตรวจสอบส่วนหัวของผู้อ้างอิงอาจเป็นทางเลือกหนึ่งได้เช่นกัน แต่จะปลอมแปลงได้ง่ายกว่า


7
ไม่คุณไม่สามารถใช้ IP ต้นทางได้เนื่องจากอาจมีการเปลี่ยนแปลงไม่ว่าจะผ่าน IP แบบไดนามิกเปลี่ยนแปลงเมื่อผู้ใช้ถูกตัดการเชื่อมต่อชั่วคราวหรือผ่านการใช้พร็อกซีฟาร์ม (โดยนัยหรือโดยชัดแจ้ง) นอกจากนี้นักจี้เซสชันที่มาจาก ISP เดียวกันอาจใช้พร็อกซีและ IP เดียวกันกับผู้ใช้ที่ถูกต้อง ...
Olaf Kock

1
PHP-Nuke มีหน้าที่ดีเกี่ยวกับวิธีการเซสชั่นของพวกเขาและพวกเขาพูดคุยในรายละเอียดเกี่ยวกับวิธีการเชื่อมต่อเข้ากับ IP ไม่ได้ทำงานกับทุกผู้ให้บริการอินเทอร์เน็ตphpnuke.org/...
Sembiance

4
การเปลี่ยน Ip เป็นเรื่องปกติของผู้ให้บริการอินเทอร์เน็ตบนมือถือ ด้วย Vodafone IP ของฉันจะเปลี่ยนไปตามคำขอทุกครั้ง
Blaise

1
ค่อนข้างเป็นโพสต์เก่า แต่เพื่อเพิ่มเติมสิ่งนี้ IP นั้นเป็นความคิดที่ไม่ดี ดังที่กล่าวไว้ผู้ใช้มือถือมักจะโรมมิ่ง IP ผู้ให้บริการอินเทอร์เน็ตบางรายในอดีตยังมี IP แบบโรมมิ่ง (เช่น AOL) แต่วิธีนี้กำลังได้รับความนิยมมากขึ้นในขณะนี้เนื่องจากการขาดแคลน IPv4 IP ISP ดังกล่าว ได้แก่ Plus net และ BT
Peter

-15

ป้องกันโดย:

$ip=$_SERVER['REMOTE_ADDER'];
$_SESSEION['ip']=$ip;

12
ฉันไม่เห็นว่าคุณมาทำอะไรที่นี่
samayo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.