นโยบายรักษาความปลอดภัยเนื้อหา (CSP) ช่วยให้เจ้าของเว็บไซต์เชื่อถือเนื้อหาทั้งหมดที่โหลดในหน้า CSP จะลดการโจมตี Cross-site Scripting (XSS) เนื่องจากสามารถบล็อกสคริปต์ที่ไม่ปลอดภัยที่ผู้โจมตีแทรกเข้ามาได้ อย่างไรก็ตาม คุณสามารถข้าม CSP ได้โดยง่ายหากยังไม่เข้มงวดพอ ดูข้อมูลเพิ่มเติมได้ที่ลดการใช้สคริปต์ข้ามเว็บไซต์ (XSS) ด้วยนโยบายรักษาความปลอดภัยเนื้อหา (CSP) ที่เข้มงวด Lighthouse จะรวบรวม CSP ที่บังคับใช้ในเอกสารหลักและรายงานปัญหาจาก CSP Evaluator หากข้ามได้
แนวทางปฏิบัติที่จำเป็นสำหรับ CSP ที่ข้ามไม่ได้
ใช้แนวทางปฏิบัติต่อไปนี้เพื่อไม่ให้ข้าม CSP ไปได้ หากข้าม CSP ได้ Lighthouse จะส่งคำเตือนความรุนแรงระดับสูง
CSP กำหนดเป้าหมายเป็น XSS
หากต้องการกำหนดเป้าหมายเป็น XSS นั้น CSP ควรมีคำสั่ง script-src
, object-src
และ base-uri
CSP ไม่ควรมีข้อผิดพลาดทางไวยากรณ์
script-src
และ object-src
จะรักษาความปลอดภัยหน้าเว็บจากสคริปต์ที่ไม่ปลอดภัยและปลั๊กอินที่ไม่ปลอดภัยตามลำดับ นอกจากนี้ คุณยังใช้ default-src
เพื่อกำหนดค่านโยบายแบบกว้างแทนคำสั่งหลายรายการ ซึ่งรวมถึง script-src
และ object-src
ได้ด้วย
base-uri
ป้องกันการแทรกแท็ก <base>
ที่ไม่ได้รับอนุญาต ซึ่งอาจใช้เพื่อเปลี่ยนเส้นทาง URL (เช่น สคริปต์) ทั้งหมด (เช่น สคริปต์) ไปยังโดเมนที่ผู้โจมตีควบคุม
CSP ใช้ Nonce หรือแฮชเพื่อหลีกเลี่ยงการข้ามรายการที่อนุญาต
CSP ที่กำหนดค่ารายการที่อนุญาตสำหรับ script-src
จะใช้สมมติฐานที่ว่าการตอบกลับทั้งหมดที่มาจากโดเมนที่เชื่อถือนั้นปลอดภัยและดำเนินการเป็นสคริปต์ได้ อย่างไรก็ตาม ข้อสันนิษฐานดังกล่าวไม่ได้ใช้กับแอปพลิเคชันสมัยใหม่ รูปแบบทั่วไปที่ไม่เป็นอันตราย เช่น การเปิดเผยอินเทอร์เฟซ JSONP และการโฮสต์สำเนาของไลบรารี AngularJS ทำให้ผู้โจมตีสามารถหลบหนีจากข้อจำกัดของ CSP ได้
ในทางปฏิบัติ ผู้โจมตีที่มีข้อบกพร่อง XSS อาจหลบเลี่ยงรายการที่อนุญาตของ script-src
ส่วนใหญ่ได้ และป้องกันการแทรกสคริปต์เพียงเล็กน้อยจากที่ผู้เขียนแอปพลิเคชันอาจไม่เห็นได้ชัดเจน ในทางตรงกันข้าม วิธีการแบบอิงตามหมายเหตุและแบบอิงตามแฮชไม่ได้รับผลกระทบจากปัญหาเหล่านี้ และช่วยให้ใช้นโยบายได้ง่ายขึ้นและคงนโยบายให้ปลอดภัยยิ่งขึ้น
ตัวอย่างเช่น โค้ดนี้ใช้ปลายทาง JSONP ที่โฮสต์ในโดเมนที่เชื่อถือได้เพื่อแทรกสคริปต์ที่ผู้โจมตีควบคุม
CSP:
script-src https://trusted.example.com
HTML:
<script src="https://trusted.example.com/path/jsonp?callback=alert(document.domain)//"></script>
เพื่อหลีกเลี่ยงการข้ามขั้นตอน CSP ควรอนุญาตสคริปต์แต่ละรายการซึ่งใช้ nonces หรือแฮช และใช้ "strict-dynamic" แทนรายการที่อนุญาต
คำแนะนำเพิ่มเติมสำหรับ CSP ที่ปลอดภัย
ใช้แนวทางปฏิบัติต่อไปนี้เพื่อเพิ่มความปลอดภัยและความเข้ากันได้ หาก CSP ไม่ปฏิบัติตามคำแนะนำข้อใดข้อหนึ่ง Lighthouse จะส่งคำเตือนระดับความรุนแรงปานกลาง
กำหนดค่าการรายงาน CSP
การกำหนดค่าปลายทางการรายงานจะช่วยตรวจสอบข้อขัดข้องต่างๆ คุณตั้งค่าปลายทางการรายงานได้โดยใช้คําสั่ง report-uri
หรือ report-to
ขณะนี้ report-to
ยังไม่รองรับเบราว์เซอร์รุ่นใหม่ๆ จึงขอแนะนำให้ใช้ทั้ง 2 ประเภทหรือใช้เพียง report-uri
หากมีเนื้อหาที่ละเมิด CSP เบราว์เซอร์จะส่งรายงานไปยังปลายทางที่กำหนดค่าไว้ โปรดตรวจสอบว่าคุณได้กำหนดค่าแอปพลิเคชันที่ปลายทางนี้จัดการรายงานเหล่านี้แล้ว
กำหนด CSP ในส่วนหัว HTTP
คุณกำหนด CSP ในเมตาแท็กได้ดังนี้
<meta http-equiv="Content-Security-Policy" content="script-src 'none'">
อย่างไรก็ตาม คุณควรกำหนด CSP ในส่วนหัวการตอบกลับ HTTP หากทำได้ การแทรกก่อนเมตาแท็กจะข้าม CSP นอกจากนี้ ระบบยังไม่รองรับ frame-ancestors
, sandbox
และการรายงานในเมตาแท็ก CSP
ตรวจสอบว่า CSP เข้ากันได้แบบย้อนหลัง
เบราว์เซอร์บางรายการอาจไม่รองรับ nonces/hashes ของ CSP จึงขอแนะนำให้เพิ่ม unsafe-inline
เป็นเบราว์เซอร์สำรองสำหรับเบราว์เซอร์ที่ไม่เป็นไปตามข้อกำหนด หากเบราว์เซอร์รองรับ nonces/hashes ระบบจะไม่สนใจ unsafe-inline
ในทำนองเดียวกัน strict-dynamic
ไม่ได้รับการสนับสนุนในเบราว์เซอร์ทั้งหมด เราขอแนะนำให้ตั้งค่ารายการที่อนุญาตเป็นทางเลือกสำรองสำหรับเบราว์เซอร์ที่ไม่เป็นไปตามข้อกำหนด โดยจะไม่สนใจรายการที่อนุญาตในเบราว์เซอร์ที่รองรับ strict-dynamic
วิธีพัฒนา CSP ที่เข้มงวด
ด้านล่างคือตัวอย่างการใช้ CSP ที่เข้มงวดกับนโยบายแบบ nonce
CSP:
script-src 'nonce-random123' 'strict-dynamic' 'unsafe-inline' https:;
object-src 'none';
base-uri 'none';
report-uri https://reporting.example.com;
HTML:
<script nonce="random123" src="https://trusted.example.com/trusted_script.js"></script>
random123
จะเป็นสตริง base64 ที่ฝั่งเซิร์ฟเวอร์สร้างขึ้นทุกครั้งที่หน้าเว็บโหลด unsafe-inline
และ https:
จะถูกละเว้นในเบราว์เซอร์รุ่นใหม่เนื่องจาก Nonce และ strict-dynamic
ดูข้อมูลเพิ่มเติมเกี่ยวกับการปรับใช้ CSP ที่เข้มงวดได้ในคู่มือ CSP แบบเข้มงวด
คุณสามารถตรวจสอบ CSP เพื่อหาการข้ามที่อาจเกิดขึ้นโดยใช้ Lighthouse และผู้ประเมิน CSP หากต้องการทดสอบ CSP ใหม่โดยไม่เสี่ยงต่อการทำให้หน้าเว็บที่มีอยู่เสียหาย ให้กำหนด CSP ในโหมดรายงานเท่านั้นโดยใช้ Content-Security-Policy-Report-Only
เป็นชื่อส่วนหัว การดำเนินการนี้จะส่งการละเมิด CSP ไปยังปลายทางการรายงานทั้งหมดที่คุณกำหนดค่าไว้กับ report-to
และ report-uri
แต่จริงๆ แล้วจะไม่มีการบังคับใช้ CSP