X-Line-Signature ตัวช่วยจาก LINE ที่จะยกระดับความปลอดภัยให้กับ Webhook ของคุณ
หากพูดถึงวิธีการพัฒนา LINE Bot แบบเขียนโค้ดเอง ให้โต้ตอบกับผู้ใช้ หรือการสร้าง Webhook สำหรับนักพัฒนาแล้วก็คงตอบได้เลยว่าไม่ยาก แต่คุณรู้หรือไม่ว่าโค้ดที่คุณเขียนขึ้นมานั้น มันอาจมีช่องโหว่บางอย่างที่มองไม่เห็นด้วยตาเปล่า
เรามาเริ่มจากรูปด้านบน เมื่อมีผู้ใช้เข้ามาโต้ตอบกับ LINE Bot ไม่ว่าจะเป็นการส่งข้อความประเภทต่างๆ, เพิ่ม Bot เป็นเพื่อน, เข้าร่วมกลุ่ม, เข้าใกล้ Beacon และอื่นๆ จะมีสิ่งที่เรียกว่า Event ส่งไปหา LINE Platform ซึ่งตัว LINE Platform ก็จะ forward ข้อมูลต่อไปยัง Webhook ที่เราผูกไว้ใน Developer Console ด้วย POST method
หมายเหตุ: บทความนี้จะแสดงตัวอย่างการพัฒนา Webhook ด้วย Cloud Functions for Firebase ที่ตอบสนอง Event ต่างๆ ดังนั้นใครที่ยังไม่รู้จัก แนะนำให้อ่านบทความด้านล่างนี้ก่อนครับ
คราวนี้เราจะรู้ได้อย่างไรว่าทุก Request ที่วิ่งเข้ามา Webhook ของเรามาจาก LINE Platform จริงๆ(ถึงแม้เราจะคิดว่าคงไม่มีใครรู้หรอกว่า URL ของ Webhook ที่เราสร้างมันคืออะไรก็ตาม)
และถ้าถามว่าทำไมเราต้องรู้ด้วยหละว่า Request นั้นมาจาก LINE Platform จริงหรือไม่…งั้นลองมาดูตัวอย่างโค้ดชุดนี้กัน
exports.LineBotReply = functions.https.onRequest((req, res) => {
if (req.method === "POST") {
// 1. Query and Insert Data into DB
// 2. Write an image file in cloud server
// 3. Predict something from an image you wrote
// ...
reply(req.body);
}
return res.status(200).send(req.method)
})
จากโค้ดด้านบน เมื่อมี Request ที่ไม่ได้มาจาก LINE Platform เข้ามา Webhook ของคุณ ตัว Webhook ของคุณก็จะมีช่องโหว่ที่อาจก่อให้เกิดความเสี่ยงเหล่านี้ได้
- ถูกเปลี่ยนแปลงข้อมูลกลางทางก่อนส่งมาถึง Webhook (เนื่องจาก API เป็น HTTPS กรณีนี้จะเกิดขึ้นได้จากการที่เราไปยอมรับ cer ของพวก Man-in-the-Middle)
- Database เกิดการ operation สูง ซึ่งส่งผลให้ Bandwidth สูงขึ้นตาม
- Storage บวมจากการ Write ไฟล์
- ค่าใช้จ่ายสูงขึ้นจากการไปต่อบริการต่างๆ
จริงๆก็ยังมีโอกาสเกิดช่องโหว่อื่นๆอีก ขึ้นอยู่กับฟังก์ชันที่เราพัฒนา แต่แค่ 4 ข้อนี้ ก็หนาวละ(ใครเปิดแอร์ ผ่าง!)
รู้จัก X-Line-Signature พระเอกของเรา
X-Line-Signature คือค่าที่ได้จากการเข้ารหัสตัว Request Body ด้วยอัลกอริทึม HMAC-SHA256 และใช้ Channel Secret จาก LINE Developers Console มาเป็น Key และ encode ด้วย Base64 ในตอนจบ
โดยที่ทาง LINE Platform จะมีการส่งค่า X-Line-Signature ใน Headers กับทุก Request ที่จะเข้ามา Webhook ของเรา ทำให้เราสามารถจะสร้าง Signature ในรูปแบบเดียวกันเพื่อมาตรวจสอบด้วยการเปรียบเทียบได้
ตัวอย่างหน้าตาของ Headers ที่วิ่งเข้ามาหา Webhook
วิธีการตรวจสอบ Request ที่เข้ามาด้วย X-Line-Signature
1. ปรับแต่งโค้ด
ลงมือแก้ไขโค้ดตามตัวอย่างด้านล่าง โดยคำอธิบายทั้ง 5 ขั้นตอนมีอยู่ใน comment ซึ่งเราจะเห็นได้ว่าสิ่งสำคัญที่ทำให้ผู้อื่นไม่สามารถสร้าง Signature ได้เหมือนกับเรา ก็คือ LINE Channel Secret นั่นเอง
2. ทดสอบส่ง Request หา Webhook ด้วย Postman
ขั้นตอนนี้ต้องเริ่มจากการไป log ดู Headers และ Body จากการที่เราไปโต้ตอบกับ LINE Bot ก่อน
เมื่อได้ Payload ของทั้งคู่มาแล้ว ก็เปิด Postman มา โดยเริ่มจากการระบุตัว URL ที่เป็น Webhook ของเรา ตามด้วยระบุตัวแปรใน headers 2 ตัว ได้แก่ x-line-signature ที่ได้จากการ log และ content-type ตามรูป
ถัดมาก็ระบุ Body แบบ raw ตามข้อมูลที่ได้ log มา เสร็จแล้วก็ยิงโลด
อ้างอิงจากโค้ดในข้อ 2 ผลลัพธ์ที่ได้ เมื่อไม่มีการแก้ไขใดๆจะได้ผลลัพธ์เป็น POST แต่หากแก้ไข Body payload แม้เพียงเล็กน้อย ผลลัพธ์ก็จะเป็น Unauthorized ทันที แบบนี้ถือว่า สำเร็จ!!!
บทสรุป
จะเห็นว่าการลงทุนเรื่องการตรวจสอบ X-Line-Signature นั้นมีต้นทุนที่ต่ำมาก ใช้เวลาอ่านบทความนี้ไม่เกิน 5 นาที และเพิ่มโค้ดอีกเพียง 4–5 บรรทัด แต่ได้ประโยชน์มหาศาล ดังนั้นใครอ่านมาถึงตรงนี้ บอกเลยว่าลงทุนเถอะครับ จะได้ไม่เป็นภาระของลูกหลานในวันข้างหน้า มาครับมาทำให้ Webhook ของเราปลอดภัยขึ้นด้วยกัน แล้วพบกันใหม่บทความหน้า สำหรับวันนี้ราตรีสวัสดิ์พี่น้องนักพัฒนาชาวไทย