ลดการใช้ Cross-site Scripting (XSS) ด้วยนโยบายรักษาความปลอดภัยเนื้อหา (CSP) ที่เข้มงวด

การรองรับเบราว์เซอร์

  • Chrome: 52
  • ขอบ: 79
  • Firefox: 52
  • Safari: 15.4

แหล่งที่มา

Cross-site Scripting (XSS) ซึ่งเป็นความสามารถในการแทรกสคริปต์ที่เป็นอันตรายลงในเว็บแอปเป็นหนึ่งในช่องโหว่ด้านความปลอดภัยบนเว็บที่ใหญ่ที่สุดมานานกว่า 10 ปี

นโยบายรักษาความปลอดภัยเนื้อหา (CSP) เป็นการรักษาความปลอดภัยอีกชั้นหนึ่งที่ช่วยลดความเสี่ยงของ XSS หากต้องการกําหนดค่า CSP ให้เพิ่มContent-Security-Policyส่วนหัว HTTP ลงในหน้าเว็บและกําหนดค่าที่จะควบคุมทรัพยากรที่ User Agent สามารถโหลดสําหรับหน้านั้นได้

หน้านี้จะอธิบายวิธีใช้ CSP ตาม nonces หรือแฮชเพื่อลดจำนวน XSS แทน CSP ตามรายการโฮสต์ที่ใช้กันโดยทั่วไปซึ่งมักจะปล่อยให้หน้าแสดง XSS เนื่องจากอาจถูกข้ามในการกำหนดค่าส่วนใหญ่

คําศัพท์สําคัญ: Nonse คือตัวเลขสุ่มที่ใช้เพียงครั้งเดียวที่คุณสามารถใช้เพื่อทําเครื่องหมายแท็ก <script> ว่าเชื่อถือได้

คําศัพท์สําคัญ: ฟังก์ชันแฮชคือฟังก์ชันทางคณิตศาสตร์ที่แปลงค่าอินพุตเป็นค่าตัวเลขที่บีบอัดแล้วเรียกว่าแฮช คุณสามารถใช้แฮช (เช่น SHA-256) เพื่อทําเครื่องหมายแท็ก <script> ในบรรทัดว่าเชื่อถือได้

นโยบายรักษาความปลอดภัยเนื้อหาที่อิงตาม Nonce หรือแฮชมักเรียกว่า CSP ที่เข้มงวด เมื่อแอปพลิเคชันใช้ CSP ที่เข้มงวด ผู้โจมตีที่พบข้อบกพร่องในการแทรก HTML มักจะใช้ข้อบกพร่องดังกล่าวเพื่อบังคับให้เบราว์เซอร์เรียกใช้สคริปต์ที่เป็นอันตรายในเอกสารที่มีช่องโหว่ไม่ได้ เนื่องจาก CSP แบบเข้มงวดจะอนุญาตเฉพาะสคริปต์ที่ผ่านการแฮชหรือสคริปต์ที่มีค่า Nonce ที่ถูกต้องซึ่งสร้างขึ้นบนเซิร์ฟเวอร์เท่านั้น ผู้โจมตีจึงไม่สามารถเรียกใช้สคริปต์ได้หากไม่รู้จัก Nonce ที่ถูกต้องสําหรับคำตอบหนึ่งๆ

เหตุใดจึงควรใช้ CSP แบบเข้มงวด

หากเว็บไซต์มี CSP ที่ดูเหมือน script-src www.googleapis.com อยู่แล้ว ก็อาจไม่มีประสิทธิภาพสำหรับแบบข้ามเว็บไซต์ CSP ประเภทนี้เรียกว่า CSP รายการที่อนุญาต ต้องมีการปรับแต่งอย่างมากและอาจหลบเลี่ยงได้โดยผู้โจมตี

CSP ที่เข้มงวดซึ่งอิงตาม Nonce หรือแฮชที่เข้ารหัสจะหลีกเลี่ยงข้อผิดพลาดเหล่านี้

โครงสร้าง CSP ที่เข้มงวด

นโยบายความปลอดภัยของเนื้อหาแบบเข้มงวดพื้นฐานใช้ส่วนหัวการตอบกลับ HTTP อย่างใดอย่างหนึ่งต่อไปนี้

CSP ที่เข้มงวดซึ่งอิงตาม Nonce

Content-Security-Policy:
  script-src 'nonce-{RANDOM}' 'strict-dynamic';
  object-src 'none';
  base-uri 'none';
วิธีการทำงานของ CSP แบบเข้มงวดที่อิงตาม Nonce

CSP ที่เข้มงวดซึ่งอิงตามแฮช

Content-Security-Policy:
  script-src 'sha256-{HASHED_INLINE_SCRIPT}' 'strict-dynamic';
  object-src 'none';
  base-uri 'none';

พร็อพเพอร์ตี้ต่อไปนี้ทําให้ CSP เช่นนี้ "เข้มงวด" และปลอดภัย

  • โดยใช้ nonces 'nonce-{RANDOM}' หรือแฮช 'sha256-{HASHED_INLINE_SCRIPT}' เพื่อระบุว่าแท็ก <script> ใดที่นักพัฒนาของเว็บไซต์เชื่อถือให้เรียกใช้ในเบราว์เซอร์ของผู้ใช้
  • ซึ่งเป็นการตั้งค่า 'strict-dynamic' เพื่อลดความจำเป็นในการติดตั้งใช้งาน CSP แบบ Nonce หรือแฮชด้วยการอนุญาตการเรียกใช้สคริปต์ที่สคริปต์ที่เชื่อถือได้สร้างขึ้นโดยอัตโนมัติ ซึ่งจะเป็นการเลิกบล็อกการใช้ไลบรารีและวิดเจ็ต JavaScript ของบุคคลที่สามส่วนใหญ่ด้วย
  • ไม่ได้อิงตามรายการที่อนุญาตของ URL จึงไม่ต้องกังวลเกี่ยวกับการหลบเลี่ยง CSP ที่พบบ่อย
  • โดยจะบล็อกสคริปต์ในบรรทัดที่ไม่เชื่อถือ เช่น ตัวจัดการเหตุการณ์ในบรรทัดหรือ javascript: URI
  • โดยจะจำกัด object-src ให้ปิดใช้ปลั๊กอินที่เป็นอันตราย เช่น Flash
  • ซึ่งจะจํากัด base-uri ไม่ให้แทรกแท็ก <base> ซึ่งจะช่วยป้องกันไม่ให้ผู้โจมตีเปลี่ยนตำแหน่งของสคริปต์ที่โหลดจาก URL แบบสัมพัทธ์

ใช้ CSP แบบเข้มงวด

หากต้องการใช้ CSP ที่เข้มงวด คุณต้องดำเนินการต่อไปนี้

  1. ตัดสินใจว่าแอปพลิเคชันควรตั้งค่า CSP ที่ใช้ Nonce หรือ Hash
  2. คัดลอก CSP จากส่วนโครงสร้าง CSP ที่เข้มงวดและตั้งค่าเป็นส่วนหัวการตอบกลับในแอปพลิเคชัน
  3. เปลี่ยนโครงสร้างภายในโค้ดของเทมเพลต HTML และโค้ดฝั่งไคลเอ็นต์เพื่อนำรูปแบบที่ใช้ร่วมกับ CSP ไม่ได้ออก
  4. ติดตั้งใช้งาน CSP

คุณสามารถใช้การตรวจสอบแนวทางปฏิบัติแนะนำของ Lighthouse (เวอร์ชัน 7.3.0 ขึ้นไปที่มี Flag --preset=experimental) ตลอดกระบวนการนี้เพื่อตรวจสอบว่าเว็บไซต์มี CSP หรือไม่ และ CSP นั้นเข้มงวดเพียงพอที่จะป้องกัน XSS ได้หรือไม่

Lighthouse ออกคำเตือนว่าไม่พบ CSP ในโหมดบังคับใช้
หากเว็บไซต์ไม่มี CSP Lighthouse จะแสดงคำเตือนนี้

ขั้นตอนที่ 1: ตัดสินใจว่าคุณต้องการ CSP ที่ใช้ Nonce หรือ Hash

ต่อไปนี้เป็นวิธีการทำงานของ CSP แบบเข้มงวด 2 ประเภท

CSP แบบ Nonce

เมื่อใช้ CSP ที่อิงตาม Nonce คุณจะต้องสร้างตัวเลขสุ่มขณะรันไทม์ รวมไว้ใน CSP และเชื่อมโยงกับแท็กสคริปต์ทุกแท็กในหน้า ผู้โจมตีจะใส่หรือเรียกใช้สคริปต์ที่เป็นอันตรายในหน้าเว็บไม่ได้ เนื่องจากจะต้องเดาตัวเลขสุ่มที่ถูกต้องสำหรับสคริปต์นั้น ตัวเลือกนี้จะทำงานเฉพาะในกรณีที่ คาดเดาหมายเลขไม่ได้ และจะสร้างใหม่ขณะรันไทม์สำหรับทุกคำตอบ

ใช้ CSP ที่อิงตาม Nonce สำหรับหน้า HTML ที่แสดงผลบนเซิร์ฟเวอร์ สำหรับหน้าเหล่านี้ คุณอาจสร้างตัวเลขสุ่มใหม่สำหรับทุกคำตอบ

CSP ตามแฮช

สําหรับ CSP ที่อิงตามแฮช ระบบจะเพิ่มแฮชของแท็กสคริปต์ในบรรทัดไปยัง CSP สคริปต์แต่ละรายการจะมีการแฮชต่างกัน ผู้โจมตีจะรวมหรือเรียกใช้สคริปต์ที่เป็นอันตรายในหน้าเว็บไม่ได้ เนื่องจากแฮชของสคริปต์นั้นจะต้องอยู่ใน CSP จึงจะเรียกใช้ได้

ใช้ CSP ที่อิงตามแฮชสำหรับหน้า HTML ที่แสดงแบบคงที่ หรือหน้าที่ต้องแคช ตัวอย่างเช่น คุณสามารถใช้ CSP ที่อิงตามแฮชสําหรับเว็บแอปพลิเคชันหน้าเดียวที่สร้างด้วยเฟรมเวิร์ก เช่น Angular, React หรืออื่นๆ ซึ่งแสดงแบบคงที่โดยไม่ต้องมีการแสดงผลฝั่งเซิร์ฟเวอร์

ขั้นตอนที่ 2: กำหนด CSP ที่เข้มงวดและเตรียมสคริปต์

เมื่อตั้งค่า CSP คุณจะมีตัวเลือกต่อไปนี้

  • โหมดรายงานเท่านั้น (Content-Security-Policy-Report-Only) หรือโหมดการบังคับใช้ (Content-Security-Policy) ในโหมดรายงานเท่านั้น CSP จะไม่บล็อกทรัพยากรในตอนนี้ ดังนั้นจึงไม่มีสิ่งใดในเว็บไซต์เสียหาย แต่คุณจะเห็นข้อผิดพลาดและรับรายงานเกี่ยวกับสิ่งที่ควรถูกบล็อก คุณไม่จำเป็นต้องตั้งค่า CSP ในเครื่อง เนื่องจากทั้ง 2 โหมดแสดงข้อผิดพลาดในคอนโซลเบราว์เซอร์ โหมดการบังคับใช้จะช่วยคุณค้นหาทรัพยากรที่ CSP ฉบับร่างบล็อกได้ เนื่องจากการบล็อกทรัพยากรอาจทําให้หน้าเว็บดูใช้งานไม่ได้ โหมดรายงานอย่างเดียวจะมีประโยชน์มากที่สุดในขั้นตอนถัดไป (ดูขั้นตอนที่ 5)
  • ส่วนหัวหรือแท็ก HTML <meta> สำหรับการพัฒนาในพื้นที่ แท็ก <meta> จะสะดวกในการปรับแต่ง CSP ซึ่งจะช่วยให้คุณเห็นผลกระทบที่แท็กมีต่อเว็บไซต์ได้อย่างรวดเร็ว อย่างไรก็ตาม
    • เมื่อทำให้ CSP ใช้งานได้จริงในภายหลัง เราขอแนะนำให้ตั้งค่าเป็นส่วนหัว HTTP
    • หากต้องการตั้งค่า CSP ในโหมดรายงานเท่านั้น คุณต้องตั้งค่าเป็นส่วนหัว เนื่องจากเมตาแท็ก CSP ไม่รองรับโหมดรายงานเท่านั้น

ตัวเลือก ก: CSP ตาม Nonce

ตั้งค่าส่วนหัวการตอบกลับ HTTP ของ Content-Security-Policy ต่อไปนี้ในแอปพลิเคชัน

Content-Security-Policy:
  script-src 'nonce-{RANDOM}' 'strict-dynamic';
  object-src 'none';
  base-uri 'none';

สร้าง Nonce สำหรับ CSP

Nonce คือตัวเลขสุ่มที่ใช้เพียงครั้งเดียวต่อการโหลดหน้าเว็บแต่ละครั้ง CSP ที่ใช้ Nonce จะลดความเสี่ยงจาก XSS ได้ก็ต่อเมื่อผู้โจมตีไม่สามารถคาดเดาค่า Nonce ได้ ค่า Nonce ของ CSP ต้องเป็น

  • ค่าแบบสุ่มที่มีการเข้ารหัสที่รัดกุม (ควรมีความยาว 128 บิตขึ้นไป)
  • สร้างใหม่สําหรับทุกคําตอบ
  • เข้ารหัส Base64

ตัวอย่างวิธีเพิ่ม CSP nonce ในเฟรมเวิร์กฝั่งเซิร์ฟเวอร์มีดังนี้

const app = express();

app.get('/', function(request, response) {
  // Generate a new random nonce value for every response.
  const nonce = crypto.randomBytes(16).toString("base64");

  // Set the strict nonce-based CSP response header
  const csp = `script-src 'nonce-${nonce}' 'strict-dynamic'; object-src 'none'; base-uri 'none';`;
  response.set("Content-Security-Policy", csp);

  // Every <script> tag in your application should set the `nonce` attribute to this value.
  response.render(template, { nonce: nonce });
});

เพิ่มแอตทริบิวต์ nonce ลงในองค์ประกอบ <script>

เมื่อใช้ CSP ที่อิงค่า Nonce องค์ประกอบ <script> ทุกรายการต้องมีแอตทริบิวต์ nonce ที่ตรงกับค่า Nonce แบบสุ่มที่ระบุในส่วนหัว CSP สคริปต์ทั้งหมดอาจมี Nonce เดียวกัน ขั้นตอนแรกคือเพิ่มแอตทริบิวต์เหล่านี้ลงในสคริปต์ทั้งหมดเพื่อให้ CSP อนุญาต

ตัวเลือก B: ส่วนหัวการตอบกลับ CSP แบบแฮช

ตั้งค่าส่วนหัวการตอบกลับ HTTP ของ Content-Security-Policy ต่อไปนี้ในแอปพลิเคชัน

Content-Security-Policy:
  script-src 'sha256-{HASHED_INLINE_SCRIPT}' 'strict-dynamic';
  object-src 'none';
  base-uri 'none';

สําหรับสคริปต์ในบรรทัดหลายรายการ ไวยากรณ์จะเป็นดังนี้ 'sha256-{HASHED_INLINE_SCRIPT_1}' 'sha256-{HASHED_INLINE_SCRIPT_2}'

โหลดสคริปต์ที่มาจากแหล่งที่มาแบบไดนามิก

คุณสามารถโหลดสคริปต์ของบุคคลที่สามแบบไดนามิกได้โดยใช้สคริปต์ในบรรทัด

ตัวอย่างวิธีแทรกสคริปต์ในบรรทัด
CSP อนุญาต
<script>
  var scripts = [ 'https://example.org/foo.js', 'https://example.org/bar.js'];

  scripts.forEach(function(scriptUrl) {
    var s = document.createElement('script');
    s.src = scriptUrl;
    s.async = false; // to preserve execution order
    document.head.appendChild(s);
  });
</script>
หากต้องการให้สคริปต์นี้ทำงาน คุณต้องคํานวณแฮชของสคริปต์ในบรรทัดแล้วเพิ่มลงในส่วนหัวการตอบกลับ CSP โดยแทนที่ตัวยึดตําแหน่ง {HASHED_INLINE_SCRIPT} หากต้องการลดจำนวนแฮช คุณผสานสคริปต์ในหน้าทั้งหมดเป็นสคริปต์เดียวได้ หากต้องการดูตัวอย่างการใช้งาน โปรดดูตัวอย่างนี้และโค้ด
ถูกบล็อกโดย CSP
<script src="https://example.org/foo.js"></script>
<script src="https://example.org/bar.js"></script>
CSP บล็อกสคริปต์เหล่านี้เนื่องจากไม่ได้เพิ่มแบบไดนามิกและไม่มีแอตทริบิวต์ integrity ที่ตรงกับแหล่งที่มาที่อนุญาต

ข้อควรพิจารณาเกี่ยวกับการโหลดสคริปต์

ตัวอย่างสคริปต์ในหน้าจะเพิ่ม s.async = false เพื่อให้ foo ทำงานก่อน bar แม้ว่า bar จะโหลดขึ้นก่อนก็ตาม ในสnippet นี้ s.async = false ไม่ได้บล็อกโปรแกรมแยกวิเคราะห์ขณะที่โหลดสคริปต์ เนื่องจากมีการเพิ่มสคริปต์แบบไดนามิก โปรแกรมแยกวิเคราะห์นี้จะหยุดขณะสคริปต์ทํางานเท่านั้น เหมือนกับที่จะดําเนินการกับสคริปต์ async รายการ อย่างไรก็ตาม โปรดทราบว่า

  • สคริปต์อย่างน้อย 1 รายการอาจทำงานก่อนที่เอกสารจะดาวน์โหลดเสร็จ หากต้องการให้เอกสารพร้อมใช้งานเมื่อสคริปต์ทำงาน ให้รอเหตุการณ์ DOMContentLoaded ก่อนเพิ่มสคริปต์ต่อท้าย หากปัญหานี้ก่อให้เกิดปัญหาด้านประสิทธิภาพเนื่องจากสคริปต์ไม่เริ่มดาวน์โหลดตั้งแต่เนิ่นๆ ให้ใช้แท็กการโหลดล่วงหน้าในหน้าเว็บตั้งแต่เนิ่นๆ
  • defer = true ไม่ทําอะไร หากต้องการลักษณะการทำงานดังกล่าว ให้เรียกใช้สคริปต์ด้วยตนเองเมื่อจำเป็น

ขั้นตอนที่ 3: ปรับโครงสร้างเทมเพลต HTML และโค้ดฝั่งไคลเอ็นต์

คุณสามารถใช้ตัวแฮนเดิลเหตุการณ์ในบรรทัด (เช่น onclick="…", onerror="…") และ URI ของ JavaScript (<a href="javascript:…">) เพื่อเรียกใช้สคริปต์ ซึ่งหมายความว่าผู้โจมตีที่พบข้อบกพร่อง XSS สามารถแทรก HTML ประเภทนี้และเรียกใช้ JavaScript ที่เป็นอันตรายได้ CSP ที่ใช้ Nonce หรือ Hash จะห้ามไม่ให้ใช้มาร์กอัปประเภทนี้ หากเว็บไซต์ใช้รูปแบบเหล่านี้ คุณจะต้องเปลี่ยนโครงสร้างภายในโค้ดเพื่อเป็นทางเลือกที่ปลอดภัยกว่า

หากเปิดใช้ CSP ในขั้นตอนก่อนหน้า คุณจะเห็นการละเมิด CSP ในคอนโซลทุกครั้งที่ CSP บล็อกรูปแบบที่เข้ากันไม่ได้

รายงานการละเมิด CSP ในคอนโซลของนักพัฒนาซอฟต์แวร์ Chrome
ข้อผิดพลาดในคอนโซลสําหรับโค้ดที่ถูกบล็อก

ในกรณีส่วนใหญ่ การแก้ไขนั้นทำได้ง่าย

เปลี่ยนโครงสร้างของเครื่องจัดการเหตุการณ์ในบรรทัด

ได้รับอนุญาตจาก CSP
<span id="things">A thing.</span>
<script nonce="${nonce}">
  document.getElementById('things').addEventListener('click', doThings);
</script>
CSP อนุญาตตัวจัดการเหตุการณ์ที่ลงทะเบียนโดยใช้ JavaScript
ถูกบล็อกโดย CSP
<span onclick="doThings();">A thing.</span>
CSP จะบล็อกตัวแฮนเดิลเหตุการณ์ในบรรทัด

ปรับโครงสร้าง URI javascript:

ได้รับอนุญาตจาก CSP
<a id="foo">foo</a>
<script nonce="${nonce}">
  document.getElementById('foo').addEventListener('click', linkClicked);
</script>
CSP อนุญาตตัวแฮนเดิลเหตุการณ์ที่ลงทะเบียนโดยใช้ JavaScript
บล็อกโดย CSP
<a href="javascript:linkClicked()">foo</a>
CSP บล็อก JavaScript: URI

นำ eval() ออกจาก JavaScript

หากแอปพลิเคชันใช้ eval() เพื่อแปลงการแปลงสตริง JSON เป็นออบเจ็กต์ JS คุณควรปรับโครงสร้างอินสแตนซ์ดังกล่าวเป็น JSON.parse() ซึ่งเร็วขึ้นด้วย

หากนำการใช้งาน eval() ทั้งหมดออกไม่ได้ คุณจะยังคงตั้งค่า CSP แบบเข้มงวดตาม Nonce ได้ แต่ต้องใช้คีย์เวิร์ด 'unsafe-eval' ของ CSP ซึ่งทำให้นโยบายมีความปลอดภัยน้อยลงเล็กน้อย

คุณดูตัวอย่างการแยกส่วนดังกล่าวและตัวอย่างอื่นๆ ได้ใน CSP ที่เข้มงวดนี้ codelab

ขั้นตอนที่ 4 (ไม่บังคับ): เพิ่มทางเลือกเพื่อรองรับเบราว์เซอร์เวอร์ชันเก่า

การรองรับเบราว์เซอร์

  • Chrome: 52
  • Edge: 79
  • Firefox: 52
  • Safari: 15.4

แหล่งที่มา

หากต้องการรองรับเบราว์เซอร์เวอร์ชันเก่า ให้ทำดังนี้

  • การใช้ strict-dynamic ทำให้ต้องเพิ่ม https: เป็นทางเลือกสำหรับ Safari เวอร์ชันก่อนหน้า สิ่งที่จะเกิดขึ้นเมื่อคุณดำเนินการนี้มีดังนี้
    • เบราว์เซอร์ทั้งหมดที่รองรับ strict-dynamic จะละเว้นการแสดงผลสำรองของ https: ดังนั้นการดำเนินการนี้จะไม่ลดประสิทธิภาพของนโยบาย
    • ในเบราว์เซอร์รุ่นเก่า สคริปต์ที่มาจากภายนอกจะโหลดได้ต่อเมื่อสคริปต์มาจากต้นทาง HTTPS เท่านั้น วิธีนี้ปลอดภัยน้อยกว่า CSP แบบเข้มงวด แต่ก็ยังคงป้องกันสาเหตุที่พบได้ทั่วไปของ XSS เช่น การส่งผ่าน javascript: URI
  • คุณสามารถเพิ่ม unsafe-inline เป็นทางเลือกสำรองเพื่อให้เข้ากันได้กับเบราว์เซอร์เวอร์ชันเก่ามาก (4 ปีขึ้นไป) เบราว์เซอร์ล่าสุดทั้งหมดจะไม่สนใจ unsafe-inline หากมี Nonce หรือแฮชของ CSP
Content-Security-Policy:
  script-src 'nonce-{random}' 'strict-dynamic' https: 'unsafe-inline';
  object-src 'none';
  base-uri 'none';

ขั้นตอนที่ 5: ติดตั้งใช้งาน CSP

หลังจากยืนยันว่า CSP ไม่ได้บล็อกสคริปต์ที่ถูกต้องในสภาพแวดล้อมการพัฒนาในเครื่องแล้ว คุณสามารถทำให้ CSP ใช้งานได้ในสภาพแวดล้อมการทดสอบ จากนั้นจึงนำไปใช้ในสภาพแวดล้อมที่ใช้งานจริง โดยทำดังนี้

  1. (ไม่บังคับ) ติดตั้งใช้งาน CSP ในโหมดรายงานเท่านั้นโดยใช้ส่วนหัว Content-Security-Policy-Report-Only โหมดรายงานเท่านั้นมีประโยชน์ในการทดสอบการเปลี่ยนแปลงที่อาจส่งผลกับส่วนอื่นอย่าง CSP ใหม่ในเวอร์ชันที่ใช้งานจริงก่อนที่จะเริ่มบังคับใช้ข้อจำกัดของ CSP ในโหมดรายงานเท่านั้น CSP จะไม่ส่งผลต่อลักษณะการทํางานของแอป แต่เบราว์เซอร์จะยังคงสร้างข้อผิดพลาดในคอนโซลและรายงานการละเมิดเมื่อพบรูปแบบที่เข้ากันไม่ได้กับ CSP ของคุณ เพื่อให้คุณเห็นว่ามีอะไรที่ใช้งานไม่ได้สําหรับผู้ใช้ปลายทาง ดูข้อมูลเพิ่มเติมได้ใน Reporting API
  2. เมื่อมั่นใจว่า CSP จะไม่ทำให้เว็บไซต์ใช้งานไม่ได้สำหรับผู้ใช้ปลายทาง ให้ติดตั้งใช้งาน CSP โดยใช้ส่วนหัวการตอบกลับ Content-Security-Policy เราขอแนะนำให้ตั้งค่า CSP โดยใช้ส่วนหัว HTTP ฝั่งเซิร์ฟเวอร์ เนื่องจากปลอดภัยกว่าแท็ก <meta> หลังจากทำขั้นตอนนี้เสร็จแล้ว CSP จะเริ่มปกป้องแอปของคุณจาก XSS

ข้อจำกัด

โดยทั่วไป CSP ที่เข้มงวดจะเพิ่มการรักษาความปลอดภัยอีกชั้นที่มีประสิทธิภาพซึ่งช่วยบรรเทา XSS ได้ ในกรณีส่วนใหญ่ CSP จะลดพื้นที่ในการโจมตีได้อย่างมากด้วยการปฏิเสธรูปแบบที่เป็นอันตราย เช่น javascript: URI อย่างไรก็ตาม ก็มีบางกรณีที่ CSP ไม่ปกป้องแอปของคุณเช่นกัน ทั้งนี้ขึ้นอยู่กับประเภทของ CSP ที่คุณใช้ (nonces, แฮช มีหรือไม่มี 'strict-dynamic')

  • หากคุณสร้างสคริปต์แบบไม่ซ้ำกัน แต่มีการแทรกลงในเนื้อหาหรือพารามิเตอร์ src ขององค์ประกอบ <script> นั้นโดยตรง
  • หากมีการแทรกลงในตำแหน่งของสคริปต์ที่สร้างแบบไดนามิก (document.createElement('script')) รวมถึงในฟังก์ชันไลบรารีที่สร้างโหนด DOM script ตามค่าของอาร์กิวเมนต์ ซึ่งรวมถึง API ทั่วไปบางรายการ เช่น .html() ของ jQuery รวมถึง .get() และ .post() ใน jQuery < 3.0
  • หากมีการแทรกเทมเพลตในแอปพลิเคชัน AngularJS เวอร์ชันเก่า ผู้โจมตีที่แทรกลงในเทมเพลต AngularJS ได้จะใช้เทมเพลตดังกล่าวเพื่อเรียกใช้ JavaScript ที่กำหนดเองได้
  • หากนโยบายมี 'unsafe-eval' การแทรกลงใน eval(), setTimeout() และ API อื่นๆ อีก 2-3 รายการที่ใช้ไม่ค่อยบ่อย

นักพัฒนาซอฟต์แวร์และวิศวกรด้านความปลอดภัยควรให้ความสำคัญกับรูปแบบดังกล่าวเป็นพิเศษในระหว่างการตรวจสอบโค้ดและการตรวจสอบความปลอดภัย ดูรายละเอียดเพิ่มเติมเกี่ยวกับกรณีเหล่านี้ได้ในนโยบายความปลอดภัยของเนื้อหา: ความสับสนที่ประสบความสำเร็จระหว่างการเพิ่มความปลอดภัยและการบรรเทา

อ่านเพิ่มเติม