ตรวจสอบว่า CSP มีผลกับการโจมตี XSS

นโยบายรักษาความปลอดภัยเนื้อหา (CSP) ช่วยให้เจ้าของเว็บไซต์เชื่อถือเนื้อหาทั้งหมดที่โหลดในหน้า CSP จะลดการโจมตี Cross-site Scripting (XSS) เนื่องจากสามารถบล็อกสคริปต์ที่ไม่ปลอดภัยที่ผู้โจมตีแทรกเข้ามาได้ อย่างไรก็ตาม คุณสามารถข้าม CSP ได้โดยง่ายหากยังไม่เข้มงวดพอ ดูข้อมูลเพิ่มเติมได้ที่ลดการใช้สคริปต์ข้ามเว็บไซต์ (XSS) ด้วยนโยบายรักษาความปลอดภัยเนื้อหา (CSP) ที่เข้มงวด Lighthouse จะรวบรวม CSP ที่บังคับใช้ในเอกสารหลักและรายงานปัญหาจาก CSP Evaluator หากข้ามได้

คําเตือนของรายงาน Lighthouse ว่าไม่พบ CSP ในโหมดบังคับใช้
คำเตือนจากรายงาน Lighthouse ว่าไม่พบ CSP ในโหมดบังคับใช้

แนวทางปฏิบัติที่จำเป็นสำหรับ 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