ป้องกันการโจมตีผ่าน CDN ด้วย Subresource Integrity
หลายคนที่เคยใช้งานไลบรารี่จาก CDN เช่น Bootstrap 4 จะพบว่าลิงก์จาก CDN นั้นมีอักขระยึกยือติดมาด้วย
1<link2 rel="stylesheet"3 href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"4 integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4"5 crossorigin="anonymous"
ตัวอักษรอันยืดยาวราวกับปริศนาธรรมนี้มีชื่อเรียกกิ๊บเก๋ว่า Subresource Integrity แต่จะมีความสำคัญยังไงนั้น เชิญเสพฮะ~
CDN อาจไม่ปลอดภัยเสมอไป
บริการออนไลน์อย่าง CDN แม้จะช่วยให้เพิ่มประสิทธิภาพในการเข้าถึงข้อมูล ไม่ว่าจะเป็น JavaScript หรือ Stylesheet แต่ไม่ได้หมายความว่าบริการนี้จะปลอดภัยเสมอไป
เพราะเหล่าแฮ็กเกอร์รู้ดีว่า CDN ที่เปิดกว้างนั้นเป็นบริการที่มีหลายเว็บไซต์ใช้งานอยู่ หากเขาได้สิทธิ์ในการเข้าถึงเหล่าผู้โจมตีคงมิปล่อยโอกาสทองเป็นแน่ อย่างน้อย ๆ ก็แค่ดัดแปลงไฟล์ซักนิด ยัดโค้ดไว้โจมตีซักหน่อย ก่อนจะจรลีไปจิบกาแฟต่อที่สตาร์บัค
สถานการณ์ที่ไม่สู้ดีเช่นนี้ ในฐานะที่เราเป็นเบราเซอร์ก็คงทำได้อย่างเดียวคือขอตรวจสอบดูซักหน่อยว่าไฟล์ที่กำลังจะใช้งานนั้นมีข้อมูลเหมือนต้นฉบับหรือไม่ หากมีสิ่งแปลกปลอมเราก็คงขอ #ตายแผล็บ
แล้วเว็บเบราเซอร์จะรู้ได้ยังไงว่าข้อมูลในไฟล์นั้นถูกเปลี่ยนแปลงมาแล้วหรือไม่?
ตรวจสอบข้อมูลด้วย Integrity
เพื่อเป็นการยืนยันว่าข้อมูลที่เราจะได้รับจาก CDN นั้นไม่ได้ถูกแก้ไขโดยผู้ประสงค์ร้าย เราจึงต้องมี flag บางอย่างให้เบราเซอร์คอยตรวจสอบได้ flag ที่ว่านี้ก็คือแอตทริบิวต์ที่ชื่อ integrity นั่นเอง
ทราบกันดีว่าหากเรามีข้อมูลชุดหนึ่ง หลังจากผ่าน hash function แล้วเราจะได้ค่าคงที่เสมอ ๆ อาศัยความจริงข้อนี้เราจึงโยนข้อมูลในไฟล์ของเราลง hash function แล้วจัดการนำค่าที่ได้ไปใส่ใน integrity เพียงแต่ว่าก่อนจะนำค่านี้ไปใส่ เราก็ทำการแปลงเป็น base64 เสียก่อน
ภายหลังที่เว็บเบราเซอร์ได้รับข้อมูลของไฟล์ที่อยู่ในแท็ก <script>
หรือ <link>
หากมี integrity มันจึงสามารถตรวจสอบว่าไฟล์นี้ถูกแก้ไขหรือไม่ด้วยการดูรหัสดังกล่าว หากข้อมูลเป็นเช่นเดิมข้อมูลที่เบราเซอร์ดูดมาพอผ่าน hash ก็ต้องได้ค่าเดียวกันกับค่าใน integrity
เราสามารถสร้างค่าข้อมูลนี้ได้โดยอาศัยเครื่องมืออย่าง openssl
1cat <FILENAME> | openssl dgst -sha384 -binary | openssl enc -base64 -A
จากคำสั่งข้างต้นจะสังเกตเห็นว่าเราต้องมีการระบุอัลกอริทึมของการแฮชด้วย (ในตัวอย่างคือ SHA384) นั่นแสดงว่าเมื่อข้อมูลมาถึงเบราเซอร์ ตัวมันเองก็ต้องทราบว่าจะเทียบค่าด้วยการใช้อัลกอริทึมของ hash ตัวใดเช่นกัน กรณีของการระบุค่า integrity เราจึงจำเป็นต้องใส่อัลกอริทึมที่ใช้นำหน้า ตามด้วยเครื่องหมายขีด และค่าที่ได้จากการทำ base64 ของค่าแฮช เช่น
1sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4
จะเกิดอะไรขึ้นเมื่อค่า integrity เปลี่ยนไป
ภายใต้แท็ก HTML อันสวยงาม หากเบราเซอร์พบแท็ก <script>
หรือ <link>
ที่มีการระบุแอตทริบิวต์ที่ชื่อ integrity ภายหลังการโหลดข้อมูลเสร็จสิ้นเว็บเบราเซอร์จะไม่ทำการประมวลผลข้อมูลในไฟล์ทันที แต่จะทำการตรวจสอบเนื้อหากับค่าจาก integrity ว่าตรงกันหรือไม่ ถ้าโอเคก็ปล่อยผ่าน แต่ถ้าโป๊ะเช๊ะว่าไม่ใช่เบราเซอร์ก็เลือกที่จะเมินหน้าหนีพร้อมปฏิเสธอย่างนางงามว่า Network Error
เอกสารอ้างอิง
Subresource Integrity. Retrieved May, 18, 2018, from https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
สารบัญ
- CDN อาจไม่ปลอดภัยเสมอไป
- ตรวจสอบข้อมูลด้วย Integrity
- จะเกิดอะไรขึ้นเมื่อค่า integrity เปลี่ยนไป
- เอกสารอ้างอิง