แนวทางในการรักษาความปลอดภัยของเซสชันที่รับผิดชอบด้วย PHP มีอะไรบ้าง? มีข้อมูลอยู่ทั่วเว็บและถึงเวลาแล้วที่ทุกอย่างจะมารวมอยู่ในที่เดียว!
แนวทางในการรักษาความปลอดภัยของเซสชันที่รับผิดชอบด้วย PHP มีอะไรบ้าง? มีข้อมูลอยู่ทั่วเว็บและถึงเวลาแล้วที่ทุกอย่างจะมารวมอยู่ในที่เดียว!
คำตอบ:
มีสองสิ่งที่ต้องทำเพื่อให้เซสชันของคุณปลอดภัย:
$_SERVER['HTTP_USER_AGENT']
. สิ่งนี้จะเพิ่มอุปสรรคเล็กน้อยในการจี้เซสชัน คุณยังสามารถตรวจสอบที่อยู่ IP แต่สิ่งนี้ทำให้เกิดปัญหาสำหรับผู้ใช้ที่มีการเปลี่ยนที่อยู่ IP เนื่องจากการโหลดบาลานซ์ในการเชื่อมต่ออินเทอร์เน็ตหลายรายการเป็นต้น (ซึ่งเป็นกรณีนี้ในสภาพแวดล้อมของเราที่นี่)แนวทางหนึ่งคือการเรียกsession_regenerate_idทุกครั้งที่ระดับความปลอดภัยของเซสชันเปลี่ยนแปลง ซึ่งช่วยป้องกันการจี้เซสชัน
สองเซ็นต์ (หรือมากกว่า) ของฉัน:
มีหนังสือเล่มเล็ก ๆ แต่ดีในหัวข้อนี้: Essential PHP Security โดย Chris ShiflettShiflett
การรักษาความปลอดภัย PHP ที่จำเป็น http://shiflett.org/images/essential-php-security-small.png
ในหน้าแรกของหนังสือคุณจะพบตัวอย่างโค้ดที่น่าสนใจและบทตัวอย่าง
คุณอาจใช้เทคนิคที่กล่าวถึงข้างต้น (IP & UserAgent) อธิบายไว้ที่นี่: วิธีหลีกเลี่ยงการโจรกรรม
ฉันคิดว่าปัญหาสำคัญอย่างหนึ่ง (ซึ่งได้รับการแก้ไขใน PHP 6) คือ register_globals ตอนนี้เป็นหนึ่งในวิธีการมาตรฐานที่ใช้ในการหลีกเลี่ยงregister_globals
คือการใช้$_REQUEST
, $_GET
หรือ$_POST
อาร์เรย์
"ถูกต้อง" วิธีที่จะทำ (ราว 5.2 แม้ว่ามันจะเป็นรถเล็ก ๆ น้อย ๆ มี แต่มั่นคง ณ วันที่ 6 ซึ่งเป็นเร็ว ๆ นี้) คือผ่านฟิลเตอร์
แทนที่จะเป็น:
$username = $_POST["username"];
คุณจะทำ:
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
หรือแม้แต่:
$username = filter_input(INPUT_POST, 'username');
เอกสารการตรึงเซสชันนี้มีคำแนะนำที่ดีมากที่อาจเกิดการโจมตี ดูเพิ่มเติมหน้าตรึงเซสชั่นที่วิกิพีเดีย
การใช้ที่อยู่ IP ไม่ใช่ความคิดที่ดีที่สุดในประสบการณ์ของฉัน ตัวอย่างเช่น; สำนักงานของฉันมีที่อยู่ IP สองแห่งที่ถูกใช้โดยขึ้นอยู่กับการโหลดและเราพบปัญหาในการใช้ที่อยู่ IP อยู่ตลอดเวลา
แต่ฉันได้เลือกที่จะจัดเก็บเซสชันในฐานข้อมูลแยกต่างหากสำหรับโดเมนบนเซิร์ฟเวอร์ของฉัน วิธีนี้จะไม่มีใครในระบบไฟล์เข้าถึงข้อมูลเซสชันนั้นได้ สิ่งนี้มีประโยชน์มากกับ phpBB ก่อน 3.0 (พวกเขาได้แก้ไขสิ่งนี้แล้ว) แต่ก็ยังเป็นความคิดที่ดีที่ฉันคิด
นี่เป็นเรื่องเล็กน้อยและชัดเจน แต่อย่าลืมsession_destroyทุกครั้งหลังการใช้งาน การดำเนินการนี้อาจเป็นเรื่องยากหากผู้ใช้ไม่ออกจากระบบอย่างชัดเจนดังนั้นจึงสามารถตั้งเวลาให้ทำเช่นนี้ได้
ปัญหาหลักเกี่ยวกับเซสชัน PHP และความปลอดภัย (นอกเหนือจากการจี้เซสชัน) มาพร้อมกับสภาพแวดล้อมที่คุณอยู่โดยค่าเริ่มต้น PHP จะเก็บข้อมูลเซสชันไว้ในไฟล์ในไดเร็กทอรี temp ของ OS โดยไม่ต้องคิดหรือวางแผนเป็นพิเศษนี่คือไดเร็กทอรีที่สามารถอ่านได้ทั่วโลกดังนั้นข้อมูลเซสชันทั้งหมดของคุณจึงเป็นแบบสาธารณะสำหรับทุกคนที่เข้าถึงเซิร์ฟเวอร์
สำหรับการดูแลเซสชันบนเซิร์ฟเวอร์หลายเครื่อง เมื่อถึงจุดนั้นจะเป็นการดีกว่าถ้าเปลี่ยน PHP เป็นเซสชันที่จัดการโดยผู้ใช้ซึ่งจะเรียกฟังก์ชันที่คุณให้มาเป็น CRUD (สร้างอ่านอัปเดตลบ) ข้อมูลเซสชัน เมื่อถึงจุดนั้นคุณสามารถจัดเก็บข้อมูลเซสชันในฐานข้อมูลหรือ memcache เช่นโซลูชันเพื่อให้แอปพลิเคชันเซิร์ฟเวอร์ทั้งหมดสามารถเข้าถึงข้อมูลได้
การจัดเก็บเซสชันของคุณเองอาจเป็นประโยชน์หากคุณอยู่บนเซิร์ฟเวอร์ที่ใช้ร่วมกันเนื่องจากจะช่วยให้คุณจัดเก็บไว้ในฐานข้อมูลซึ่งบ่อยครั้งคุณสามารถควบคุมระบบไฟล์ได้มากกว่า
ฉันตั้งเซสชันของฉันแบบนี้ -
ในหน้าเข้าสู่ระบบ:
$_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR']);
(วลีที่กำหนดในหน้าการกำหนดค่า)
จากนั้นในส่วนหัวที่อยู่ตลอดส่วนที่เหลือของไซต์:
session_start();
if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR'])) {
session_destroy();
header('Location: http://website login page/');
exit();
}
session.cookie_httponly = 1
change session name from default PHPSESSID
X-XSS-Protection 1
X-XSS-Protection
ไม่มีประโยชน์เลย ในความเป็นจริงอัลกอริทึมการปกป้องนั้นสามารถใช้ประโยชน์ได้จริงทำให้แย่ลงกว่าเดิม
ฉันจะตรวจสอบทั้ง IP และ User Agent เพื่อดูว่ามีการเปลี่ยนแปลงหรือไม่
if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']
|| $_SESSION['user_ip'] != $_SERVER['REMOTE_ADDR'])
{
//Something fishy is going on here?
}
หากคุณใช้session_set_save_handler ()คุณสามารถตั้งค่าตัวจัดการเซสชันของคุณเองได้ ตัวอย่างเช่นคุณสามารถจัดเก็บเซสชันของคุณในฐานข้อมูล อ้างถึงความคิดเห็นของ php.net สำหรับตัวอย่างของตัวจัดการเซสชันฐานข้อมูล
เซสชัน DB ยังดีหากคุณมีเซิร์ฟเวอร์หลายเครื่องหากคุณใช้เซสชันแบบไฟล์คุณจะต้องตรวจสอบให้แน่ใจว่าแต่ละเว็บเซิร์ฟเวอร์มีสิทธิ์เข้าถึงระบบไฟล์เดียวกันเพื่ออ่าน / เขียนเซสชัน
คุณต้องแน่ใจว่าข้อมูลเซสชันปลอดภัย โดยดูที่ php.ini ของคุณหรือใช้ phpinfo () คุณจะพบการตั้งค่าเซสชันของคุณ _session.save_path_ บอกคุณว่าบันทึกไว้ที่ไหน
ตรวจสอบสิทธิ์ของโฟลเดอร์และของผู้ปกครอง ไม่ควรเป็นสาธารณะ (/ tmp) หรือสามารถเข้าถึงได้โดยเว็บไซต์อื่นบนเซิร์ฟเวอร์ที่ใช้ร่วมกันของคุณ
สมมติว่าคุณยังต้องการใช้เซสชัน php คุณสามารถตั้งค่า php ให้ใช้โฟลเดอร์อื่นได้โดยเปลี่ยน _session.save_path_ หรือบันทึกข้อมูลในฐานข้อมูลโดยเปลี่ยน _session.save_handler_
คุณอาจสามารถตั้งค่า _session.save_path_ ใน php.ini ของคุณ (ผู้ให้บริการบางรายอนุญาต) หรือสำหรับ apache + mod_php ในไฟล์. htaccess ในโฟลเดอร์รูทของไซต์ของคุณ:
php_value session.save_path "/home/example.com/html/session"
ไฟล์ในโฟลเดอร์รากเว็บไซต์ของคุณ: คุณยังสามารถตั้งค่าในขณะรันได้ด้วย _session_save_path () _
ตรวจสอบบทช่วยสอนของ Chris ShiflettหรือZend_Session_SaveHandler_DbTableเพื่อตั้งค่าและตัวจัดการเซสชันทางเลือก