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

Browser Support

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

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

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

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

คำสำคัญ: Nonce คือตัวเลขสุ่มที่ใช้เพียงครั้งเดียว ซึ่งคุณใช้เพื่อทำเครื่องหมายแท็ก <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&#39;;
  base-uri 'none';
วิธีการทำงานของ CSP แบบเข้มงวดที่อิงตาม Nonce

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

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

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

  • โดยใช้ Nonce 'nonce-{RANDOM}' หรือแฮช 'sha256-{HASHED_INLINE_SCRIPT}' เพื่อระบุแท็ก <script> ที่นักพัฒนาเว็บไซต์เชื่อถือว่าจะดำเนินการใน เบราว์เซอร์ของผู้ใช้
  • โดยจะตั้งค่า 'strict-dynamic' เพื่อลดความพยายามในการติดตั้งใช้งาน CSP ที่อิงตาม Nonce หรือ Hash โดยการอนุญาตให้เรียกใช้สคริปต์ที่สคริปต์ที่เชื่อถือได้สร้างขึ้นโดยอัตโนมัติ นอกจากนี้ยัง ยกเลิกการบล็อกการใช้ไลบรารีและวิดเจ็ต 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 คุณมีตัวเลือก 2-3 อย่างดังนี้

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

ตัวเลือก ก: CSP ที่อิงตาม Nonce

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

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

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

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(&>quot;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 อนุญาต

ตัวเลือก ข: ส่วนหัวการตอบกลับ CSP ที่อิงตามแฮช

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

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.hea<d.appen>dChild(s);
  });
/script
หากต้องการให้สคริปต์นี้ทํางาน คุณต้องคํานวณแฮชของสคริปต์แบบอินไลน์ และเพิ่มลงในส่วนหัวการตอบกลับ CSP โดยแทนที่ตัวยึดตําแหน่ง {HASHED_INLINE_SCRIPT} หากต้องการลดจำนวนแฮช คุณสามารถรวมสคริปต์ทั้งหมดในบรรทัด เป็นสคริปต์เดียวได้ หากต้องการดูการทำงานจริง โปรดดูตัวอย่าง และโค้ด
ถูกบล็อกโดย CSP
<script src="https://example.org/fo><o.js&qu>o<t;/script
script src="https://exam><ple.org>/bar.js"/script
CSP บล็อกสคริปต์เหล่านี้เนื่องจากไม่ได้เพิ่มแบบไดนามิก และไม่มีแอตทริบิวต์ integrity ที่ตรงกับแหล่งที่มาที่อนุญาต

ข้อควรพิจารณาในการโหลดสคริปต์

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

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

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

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

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

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

ในกรณีส่วนใหญ่ การแก้ไขจะตรงไปตรงมา ดังนี้

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

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

javascript: URI ที่ปรับโครงสร้างใหม่

อนุญาตโดย CSP
<a id=">;fo<o&>q<uot;foo/a
script nonce=>"${nonce}"
  document.getElementById('foo').addEventList<ener(&#>39;click', linkClicked);
/script
CSP อนุญาตตัวแฮนเดิลเหตุการณ์ที่ลงทะเบียนโดยใช้ JavaScript
ถูกบล็อกโดย CSP
<a href="javascript:linkClick>ed(<)&>quot;foo/a
CSP บล็อก JavaScript: URI

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

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

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

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

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

Browser Support

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

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

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

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

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

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