ตามคำจำกัดความของ CSRF กล่าว
โทเค็น CSRF เป็นโทเค็นแบบสุ่มที่ปลอดภัย (เช่น โทเค็นการซิงโครไนซ์หรือ
โทเค็นการท้าทาย) ที่ใช้เพื่อป้องกันการโจมตี CSRF โทเค็นต้องการ
ไม่ซ้ำกันต่อเซสชันของผู้ใช้และควรมีค่าสุ่มมาก
ทำให้คาดเดาได้ยาก แอปพลิเคชันที่ปลอดภัยของ CSRF กำหนดเฉพาะ
โทเค็น CSRF สำหรับทุกเซสชันของผู้ใช้
มันปกป้อง BE เพื่อให้แน่ใจว่าการโพสต์ที่ BE มาจากแบบฟอร์มที่สร้างโดย BE เว้นแต่ใครก็ตามสามารถโพสต์ข้อมูลไปยัง BE จากแหล่งใดก็ได้
เช่น ในฟอร์มล็อกอิน แฮ็กเกอร์สามารถเขียนโค้ดเพื่อลองชุดค่าผสมต่างๆ ได้ (แน่นอนว่า drupal มีนโยบาย max retry ซึ่งป้องกันไม่ให้ผู้ใช้ลองรหัสผ่านผิดเกิน 5 ครั้ง และมีการตรวจจับน้ำท่วมใน drupal ที่ป้องกันการโจมตีด้วยกำลังดุร้าย ). แต่ถึงกระนั้น แบบฟอร์มที่ไม่มีการป้องกัน CSRF ก็เป็นสถานที่ที่ดีสำหรับบอทและสแปมเมอร์ในการโพสต์ข้อมูลหลายครั้ง
ดังนั้นจะเป็นการดีกว่าถ้าแบบฟอร์มของคุณเปิดให้ไม่ระบุชื่อเพื่อปกป้องพวกเขา หม้อน้ำผึ้ง และโซลูชันการตรวจจับมนุษย์ ( captcha, รีแคปชา, Recaptcha 3 แคปต์ชาคณิตศาสตร์ ฯลฯ)
นอกจากนี้ยังมี โมดูลชุดรักษาความปลอดภัย ทำให้ปลอดภัยยิ่งขึ้น
อัปเดตส่วนหนึ่งหลังจากที่ฉันสังเกตเห็นว่าเกิดขึ้นสำหรับผู้ใช้ที่เข้าสู่ระบบ
ด้วยเหตุผลที่ฉันได้กล่าวมาข้างต้น โดยเฉพาะอย่างยิ่งเพื่อให้มีฟังก์ชันการแคชที่ดีขึ้น สำหรับผู้ใช้ที่ไม่ระบุตัวตน จึงไม่ได้รับการรีเฟรช
แต่สำหรับผู้ใช้ที่เข้าสู่ระบบ หลังจากตรวจสอบระดับรหัสแล้ว ฉันพบว่าไม่ใช่จุดบกพร่อง
มันถูกสร้างขึ้นตาม form_id และจนกว่าคุณจะยังไม่ได้ส่งฟอร์ม มันจะเหมือนเดิมและการรีเฟรชจะไม่สร้างใหม่ ดังนั้น, form_token
และ form_build_id
เป็นสิ่งที่ป้องกันรูปแบบจาก
สำหรับการอ้างอิงและดูข้อมูลเพิ่มเติมเกี่ยวกับ:
// เพิ่มโทเค็นตาม #token หรือ form_id ให้กับฟอร์มที่แสดง
// ผู้ใช้ที่รับรองความถูกต้องสิ่งนี้ทำให้มั่นใจได้ว่าแบบฟอร์มที่ส่งมานั้นเป็นจริง
// ผู้ใช้ร้องขอก่อนหน้านี้และป้องกันการร้องขอข้ามไซต์
//ของปลอม.
// สิ่งนี้ใช้ไม่ได้กับแบบฟอร์มที่ส่งทางโปรแกรม นอกจากนี้,
// เนื่องจากโทเค็นถูกผูกไว้กับเซสชันและรูปแบบที่แสดงต่อผู้ใช้ที่ไม่ระบุตัวตน
// เป็นไปได้มากที่แคชไว้ เราไม่สามารถกำหนดโทเค็นให้กับพวกมันได้
// ระหว่างการติดตั้ง ยังไม่มี $user
// ตัวสร้างฟอร์มอาจตั้งค่า #token เป็น FALSE อย่างชัดเจนเมื่อข้ามไซต์
// การปลอมแปลงคำขอไม่เกี่ยวข้องกับแบบฟอร์ม เช่น แบบฟอร์มการค้นหา
ถ้า ($form_state
->เป็นโปรแกรม () || isset($form['#token']) && $form['#token'] === FALSE) {
unset($form['#token']);
}
อื่น {
$form['#cache']['contexts'][] = 'user.roles:authenticated';
ถ้า ($user && $user
->isAuthenticated()) {
// สร้างโทเค็นสาธารณะและตัวยึดตามรหัสแบบฟอร์ม
$placeholder = 'form_token_placeholder_' Crypt::hashBase64($form_id);
$form['#token'] = $placeholder;
$แบบฟอร์ม['form_token'] = [
'#id' => Html::getUniqueId('edit-' . $form_id . '-form-token'),
'#type' => 'โทเค็น',
'#default_value' => $placeholder,
// การประมวลผลแบบฟอร์มและการตรวจสอบต้องใช้ค่านี้ รับรองว่า
// ค่าแบบฟอร์มที่ส่งจะปรากฏตามตัวอักษร โดยไม่คำนึงถึง #tree ที่กำหนดเอง
// และ #parents ถูกตั้งค่าไว้ที่อื่น
'#ผู้ปกครอง' => [
'ฟอร์ม_โทเค็น',
]
อ้างอิง : https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21FormBuilder.php/function/FormBuilder%3A%3AprepareForm/9.3.x