WordPress Nonces นั้นก็คือวิธีการ ป้องกันช่องโหว่ประเภท Cross-Site Request Forgery(CSRF) อย่างหนึ่ง ซึ่งช่องโหว่ประเภท CSRF นี้ จะเกิดจากการที่แฮกเกอร์ แอบส่ง HTTP request ไปยังเว็บที่ผู้ใช้งานได้ทำการ Login ไว้แล้ว เพื่อกระทำการบางอย่าง เช่น ส่งแบบฟอร์มการโอนไปยังเว็บธนาคารเพื่อโอนไปยังบัญชีของแฮกเกอร์ หรือ แอบสั่งสินค้าในเว็บออนไลน์เพื่อส่งไปยังที่อยู่ของแฮกเกอร์เอง
ก่อนจะอธิบายต่อ ผมขออธิบายเพิ่มเติมว่า HTTP request คืออะไร
HTTP request นั้นก็คือ การที่ผู้ใช้งาน ( client ) ส่งข้อมูลไปหาเครื่อง server ซึ่งเราใช้งานกันอยู่ทุกๆ วัน เช่น การกรอก url ลงใน web browser เพื่อไปดึงข้อมูลเว็บจาก server มาแสดงบน browser รวมถึงการอ่านบทความนี้ก็คือ การที่ ผู้อ่านส่ง HTTP request มาขอข้อมูลเนื้อหาจาก server ของ webnocode นั่นเอง
การส่งข้อมูลแบบฟอร์มบนเว็บไซต์นั้นจะแบ่งได้เป็น 2 รูปแบบคือ GET กับ POST ซึ่งต่างกันตรงที่ส่งแบบ GET จะเป็นการส่งผ่าน url ซึ่งเราไม่จำเป็นต้องกรอกแบบฟอร์มก็ยังส่งข้อมูลได้ แค่มี URL ที่อยู่ต้อง ดังตัวอย่างต่อไปนี้

จากแบบฟอร์มด้านบน คือ แบบฟอร์มการสั่งซื้อสินค้าจากเว็บๆ หนึ่ง ยกตัวอย่างเป็น xxx.com ที่คุณได้ทำการ Login ไว้แล้ว แถมยังผูกบัตรเครดิตไว้แล้วด้วย
หากเป็นการส่งข้อมูลแบบ GET หลังจากคลิกที่ปุ่ม checkout URL บน web browser จะเปลี่ยนไปเป็น
http://xxx.com?product_sku=abc123&quantity=10&address=123/456%20บ้านนาย%ก
ซึ่งเว็บไซต์ก็จะทำการสั่งซื้อสินค้าเสร็จเรียบร้อยแล้ว ซึ่งหากต้องการสั่งซื้อใหม่โดยเพิ่มจำนวนสินค้าจาก 10 เป็น 20 ( ตัวหนา ) โดยที่ไม่ต้องการกรอกแบบฟอร์มใหม่ก็ สามารถทำได้ผ่าน URL เลย เพียงแก้เป็นดังนี้
http://xxx.com?product_sku=abc123&quantity=20&address=123/456%20บ้านนาย%ก
เพียงเท่านี้ก็จะเป็นการสั่งออเดอร์ใหม่โดยเพิ่มจำนวนการสั่งซื้อเป็น 20 ชิ้นแล้ว และหาก URL ถูกเปลี่ยนเป็นแบบนี้ละ
http://xxx.com?product_sku=abc123&quantity=2000&address=999/888%20บ้านแฮกเกอร์
ก็เท่ากับเราซื้อของขวัญให้แฮกเกอร์ไปเลย 2000 ชิ้น
และจากแบบฟอร์ม หากเป็นการส่งข้อมูลแบบ POST ก็สามารถทำได้เช่นกันแม้จะไม่ได้ง่ายเหมือนการแก้ไข URL แต่ก็ทำได้ไม่ยากนัก
แล้วแฮกเกอร์รู้ URL นี้ได้อย่างไร และดำเนินการอย่างไร
การที่จะรู้ URL ข้างต้นนั้น อย่างง่ายๆ เลย ก็คือแฮกเกอร์ไปลองสั่งซื้อของในเว็บ someweb.com แล้วพบช่องโหว่นี้ แต่การดำเนินการทั้งหมดจะมีประมาณนี้คือ
แนวทางการในการป้องกัน CSRF
- ผู้ใช้งาน Login เข้าเว็บไซต์ someweb.com ( ซึ่งเคยผูกบัตรเครดิตไว้แล้ว )
- Login สำเร็จ
- จากนั้นไปหน้าแบบฟอร์มการสั่งซื้อ และทำการสั่งซื้อ
- จากนั้นก็ไปเข้าเว็บอื่นๆ ต่อโดยที่ไม่ได้ Logout
- เผลอเข้ามาที่เว็บไซต์ของแฮกเกอร์
- แฮกเกอร์สร้างปุ่มที่ชวนให้คลิกเช่น “รับคูปองส่วนลดเว็บ someweb.com 90% ฟรี” โดยที่ปุ่มนี้ลิงก์ไปที่ http://xxx.com?product_sku=abc123&quantity=2000&address=999/888%20บ้านแฮกเกอร์
- ผู้ใช้งานกดคลิกปุ่มดังกล่าว
- จากนั้นเว็บ someweb.com ก็ทำการสั่งซื้อสินค้าให้แฮกเกอร์ไปเรียบร้อยแล้ว
แนวทางแก้มีด้วยกันหลายทาง แต่ทางที่เกี่ยวข้องกับ WordPress Nonce นั้นก็คือ การสร้าง Token ( ตัวอักษรแบบสุ่มมั่ว ๆ ) สำหรับใช้ครั้งเดียวขึ้นมาคู่กับการแสดงหน้าแบบฟอร์ม ซึ่ง Token นี้ WordPress เรียกว่า Nonce นั่นเอง
การทำงานของ WordPress Nonce
- ผู้ใช้งาน Login เข้าเว็บไซต์ someweb.com ( ซึ่งเคยผูกบัตรเครดิตไว้แล้ว )
- Login สำเร็จ
- จากนั้นไปหน้าแบบฟอร์มการสั่งซื้อ โดย server จะสร้าง session ที่มีค่าเดียวกับค่า nonce พร้อมกับ แสดง hidden field ในฟอร์มการสั่งซื้อเป็นค่า nonce เดียวกันด้วย
- เมื่อคลิก checkout แล้ว URL ที่ได้จะเป็น http://xxx.com?product_sku=abc123&quantity=2000&address= 123/456%20บ้านนาย%20ก&nonce=as5ds468f4sd35 ( จะเห็นว่ามีค่า nonce เพิ่มเข้ามาเป็นค่าเฉพาะของผู้ใช้งานแต่ละคน )
- ทำการสั่งซื้อสำเร็จ
- จากนั้นก็ไปเข้าเว็บอื่นๆ ต่อโดยที่ไม่ได้ Logout
- เผลอเข้ามาที่เว็บไซต์ของแฮกเกอร์
- แฮกเกอร์สร้างปุ่มที่ชวนให้คลิกเช่น “รับคูปองส่วนลดเว็บ someweb.com 90% ฟรี” โดยที่ปุ่มนี้ลิงก์ไปที่ http://xxx.com?product_sku=abc123&quantity=2000&address=999/888%20บ้านแฮกเกอร์&nonce=????( จะเห็นว่าค่า nonce ไม่ตรงกับของผู้ใช้งานเนื่องจากแฮกเกอร์ไม่สามารถรู้ค่านี้ได้ )
- ผู้ใช้งานกดคลิกปุ่มดังกล่าว
- จากนั้นเว็บ someweb.com ก็จะทำการตรวจสอบค่า nonce ว่าตรงกับที่เก็บไว้ใน session หรือไม่ หากไม่ตรงกัน การสั่งซื้อจะไม่สำเร็จ
การใช้งาน WordPress Nonce
ด้านล่างคือโค้ดการสร้าง hidden field สำหรับเก็บค่า nonce ซึ่งการใช้งานฟังก์ชั่น wp_nonce_field จะเป็นการสร้าง hidden field ให้ฟอร์มพร้อมกับสร้าง session บน server ด้วย
<form method="post">
<!-- some inputs here ... -->
<?php wp_nonce_field( 'name_of_my_action', 'name_of_nonce_field' ); ?>
</form>
โค้ดการตรวจสอบ Nonce
if (
! isset( $_POST['name_of_nonce_field'] )
|| ! wp_verify_nonce( $_POST['name_of_nonce_field'], 'name_of_my_action' )
) {
print 'Sorry, your nonce did not verify.';
exit;
} else {
// process form data
}
จากโค้ดข้างต้น จะเห็นว่า ค่า Nonce ต้องตรงกันจึงจะดำเนินการใดๆ ต่อไปได้ เช่น การสร้างออเดอร์ เป็นต้น
สรุป WordPress Nonce
จากเนื้อหาทั้งหมดจะเห็นว่าการใช้งาน WordPress Nonce นั้นมีประโยชน์อย่างมาก ดังนั้นหากคุณคือ WordPress Developer ควรจะใช้ Nonce ในทุกๆ ฟอร์มที่สำคัญๆ ทั้งในส่วนของหน้าบ้านและหลังบ้านด้วย
แหล่งที่มา