Content Security Policy กับ CMP ของคุณ: ทำให้ CSP และความยินยอมทำงานร่วมกัน
เลเยอร์ความปลอดภัยสองชั้นที่ต้องไปด้วยกัน
Content Security Policy (CSP) บอกเบราว์เซอร์ว่าหน้าเว็บโหลดสคริปต์ สไตล์ รูปภาพ เฟรม และคำขอเครือข่ายจากแหล่งใดได้บ้าง แพลตฟอร์มจัดการความยินยอมทำหน้าที่ตรงข้าม คือตัดสินว่าสคริปต์เหล่านั้นตัวใดได้รับอนุญาตให้ทำงานตามทางเลือกของผู้ใช้ เมื่อตั้งค่าทั้งสองแยกกันก็จะชนกัน CMP โหลดไม่ขึ้นเพราะ CSP บล็อก หรือ CSP ถูกผ่อนจนหลวมเพื่อรองรับ CMP และแท็กโฆษณา จนไม่ได้ปกป้องอะไรอีกต่อไป
คู่มือนี้อธิบายว่า CMP โดยทั่วไปต้องใช้ directive ของ CSP ใดบ้าง nonce เกี่ยวข้องกับการแทรกสคริปต์อย่างไร และเปิดใช้การเปลี่ยนแปลงโดยไม่ทำให้แบนเนอร์พังได้อย่างไร
สิ่งที่ CMP มักต้องการจาก CSP
ข้อกำหนดที่แน่นอนขึ้นอยู่กับผู้ให้บริการ ดังนั้นให้เริ่มจากเอกสารของ CMP ของคุณเสมอ โดยทั่วไปให้ตรวจ directive เหล่านี้:
script-src— โดเมนที่สคริปต์ CMP โหลดจาก รวมถึงไฟล์สคริปต์เพิ่มเติมที่โหลดconnect-src— เอนด์พอยต์ที่ CMP เรียกด้วยfetchหรือ XHR เช่น เอนด์พอยต์ของการกำหนดค่า รายชื่อผู้ขาย การระบุตำแหน่ง และการบันทึกความยินยอมstyle-src— โดเมนของสไตล์ชีต และอาจรวมถึงสไตล์แบบอินไลน์ หาก CMP แทรกองค์ประกอบ<style>หรือตั้งแอตทริบิวต์ styleimg-src— โลโก้ ไอคอน และพิกเซลที่ไม่ติดตามที่ CMP ใช้font-src— หากแบนเนอร์โหลดฟอนต์ของตนเองframe-src— หาก CMP ใช้ iframe เช่น เพื่อแชร์ความยินยอมข้ามโดเมน
บนเว็บไซต์ TCF โปรดจำไว้ว่า CMP ยังสร้างเฟรมตัวระบุตำแหน่งชื่อ __tcfapiLocator บนหน้าด้วย เฟรมนั้นถูกสร้างโดยไม่มีแหล่งระยะไกล จึงมักไม่ต้องมีรายการ frame-src แต่ควรยืนยันระหว่างการทดสอบ
ปัญหาของสตับแบบอินไลน์
CMP ส่วนใหญ่ให้คุณวางสคริปต์อินไลน์ขนาดเล็ก — สตับ — ไว้ใน head ของหน้า เพื่อให้สคริปต์อื่นจัดคิวการเรียกได้ก่อนที่ CMP หลักจะโหลด CSP ที่เข้มงวดจะบล็อกสคริปต์อินไลน์ เว้นแต่คุณอนุญาตอย่างชัดแจ้ง คุณมีสามทางเลือก:
- nonce สร้างค่าสุ่มต่อการตอบกลับแต่ละครั้ง ใส่ลงในส่วนหัว CSP เป็น
'nonce-...'และในแท็ก<script>ของสตับ นี่เป็นทางเลือกที่ยืดหยุ่นที่สุดสำหรับหน้าแบบไดนามิก - แฮช เพิ่มแฮช SHA-256 ของเนื้อหาสตับที่ตรงกันทุกตัวอักษรลงใน
script-srcใช้ได้ดีกับเว็บไซต์แบบสถิต แต่การเปลี่ยนแปลงใดๆ ในสตับ แม้แต่ช่องว่าง ก็ทำให้พัง - โฮสต์สตับเอง เป็นไฟล์ภายนอกบนโดเมนของคุณ ซึ่งครอบคลุมด้วย
'self'ต้องระวังให้โหลดเร็วพอ
หลีกเลี่ยง 'unsafe-inline' เป็นทางลัด เพราะอนุญาตสคริปต์อินไลน์ทุกตัว ทำให้การป้องกันที่ CSP มอบให้หายไปมาก
nonce และสคริปต์ที่ CMP แทรก
CMP ที่บล็อกสคริปต์จนกว่าจะได้รับความยินยอมมักทำงานโดยหน่วงสคริปต์ไว้แล้วแทรกภายหลัง ภายใต้ CSP แบบ nonce สคริปต์ที่แทรกเหล่านั้นก็ต้องได้รับอนุญาตด้วย มีสองแนวทางที่พบบ่อย:
- การส่งต่อ nonce CMP อ่าน nonce จากแท็กสคริปต์ของตนเองและเพิ่มลงในทุกสคริปต์ที่แทรก ตรวจสอบว่า CMP ของคุณรองรับหรือไม่
'strict-dynamic'คีย์เวิร์ดนี้บอกเบราว์เซอร์ที่รองรับให้เชื่อถือสคริปต์ที่โหลดโดยสคริปต์ที่เชื่อถืออยู่แล้ว ช่วยให้ชีวิตง่ายขึ้นกับตัวจัดการแท็กและ CMP ที่แทรกสคริปต์ แต่ก็หมายความว่าสคริปต์ที่คุณเชื่อถือตัวใดก็โหลดตัวอื่นได้ ดังนั้นต้องเชื่อถืออย่างระมัดระวัง
ตัวจัดการแท็กก็ทำให้เกิดคำถามเดียวกัน หากคุณโหลดแท็กโฆษณาและการวิเคราะห์ผ่านตัวจัดการแท็ก ให้ทำตามเอกสารของมันเรื่อง nonce และตรวจให้แน่ใจว่า CMP และตัวจัดการแท็กใช้แนวทางที่สอดคล้องกัน
แท็กโฆษณาทำให้ CSP ยากขึ้น
โฆษณาแบบโปรแกรมเมติกโหลดสคริปต์และเฟรมจากโดเมนจำนวนมาก และรายการเปลี่ยนไปเมื่อพาร์ตเนอร์ด้านความต้องการซื้อเปลี่ยน ผู้เผยแพร่มักเลือกหนึ่งในสองทาง:
- CSP ที่เข้มงวดบนหน้าที่ไม่มีโฆษณาแบบโปรแกรมเมติก และนโยบายที่กว้างกว่าในที่ที่โฆษณาทำงาน
- นโยบายที่เน้น directive ที่ยังจัดการได้ เช่น
frame-ancestors,object-src 'none'และbase-uriขณะที่แหล่งสคริปต์ยังกว้างอยู่
ไม่ว่าทางใด CMP ควรอยู่ในรายการอนุญาตที่ระบุชัดเจน ไม่ใช่ครอบคลุมเพียงด้วยไวลด์การ์ด เพื่อไม่ให้การเปลี่ยน CSP ทำให้แบนเนอร์หยุดทำงานโดยไม่มีใครรู้
เปิดใช้ด้วยโหมด Report-Only
ใช้ส่วนหัว Content-Security-Policy-Report-Only ก่อน เบราว์เซอร์จะรายงานการละเมิดโดยไม่บล็อกอะไร คุณจึงเห็นได้ว่านโยบายใหม่จะทำให้อะไรพัง
- ติดตั้งนโยบายในโหมด report-only พร้อมเอนด์พอยต์สำหรับรายงาน
- โหลดหน้าในโปรไฟล์เบราว์เซอร์ที่สะอาดและทำตามขั้นตอนความยินยอมทั้งหมด: เข้าชมครั้งแรก ยอมรับทั้งหมด ปฏิเสธทั้งหมด เลือกเอง ถอนความยินยอม
- ตรวจรายงานการละเมิดและคอนโซลของเบราว์เซอร์เพื่อหาทรัพยากรของ CMP ที่ถูกบล็อก
- ปรับนโยบาย แล้วสลับไปใช้งานจริง
- เปิดการรายงานไว้ต่อหลังบังคับใช้เพื่อจับการถดถอย
อาการของ CSP ที่ขัดแย้ง
- แบนเนอร์ไม่ปรากฏเลย และคอนโซลแสดงการละเมิด CSP ของสคริปต์ CMP
- แบนเนอร์ปรากฏแต่ไม่มีสไตล์ เพราะ
style-srcบล็อก CSS ของมัน - ตัวเลือกไม่ถูกบันทึก เพราะ
connect-srcบล็อกการเรียกบันทึกความยินยอม - โฆษณาหรือการวิเคราะห์ไม่เคยโหลดหลังให้ความยินยอม เพราะสคริปต์ที่แทรกไม่มี nonce
__tcfapiไม่ถูกกำหนด เพราะสตับแบบอินไลน์ถูกบล็อก
ประเด็นสำคัญ
- ตรวจ
script-src,connect-src,style-src,img-srcและframe-srcสำหรับ CMP ของคุณ - อนุญาตสตับแบบอินไลน์ด้วย nonce หรือแฮช ไม่ใช่
'unsafe-inline' - ตรวจให้แน่ใจว่าสคริปต์ที่แทรกหลังได้รับความยินยอมได้ nonce หรือถูกครอบคลุมด้วย
'strict-dynamic' - ทดสอบทุกเส้นทางความยินยอมในโหมด report-only ก่อนบังคับใช้
- ให้ CMP อยู่ในรายการอนุญาตอย่างชัดเจน เพื่อไม่ให้การเปลี่ยน CSP ปิดการทำงานของมันได้