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

การสนับสนุนเบราว์เซอร์

  • 52
  • 79
  • 52
  • 15.4

แหล่งที่มา

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

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

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

คำสำคัญ: nonce คือหมายเลขสุ่มที่ใช้เพียงครั้งเดียวเท่านั้นซึ่งสามารถใช้เพื่อทำเครื่องหมายแท็ก <script> ว่าเชื่อถือได้

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

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

เหตุใดคุณจึงควรใช้ CSP ที่เข้มงวด

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

CSP ที่เข้มงวดโดยอิงจาก nonces หรือแฮชการเข้ารหัสจะช่วยหลีกเลี่ยงหลุมพรางเหล่านี้ได้

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

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

CSP แบบเข้มงวดที่อิงตามสถานการณ์

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

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

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

พร็อพเพอร์ตี้ต่อไปนี้ทำให้ CSP เหมือนกับเนื้อหานี้ "เข้มงวด" ดังนั้นจึงมีความปลอดภัย

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

ใช้ CSP ที่เข้มงวด

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

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

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

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

ขั้นตอนที่ 1: ตัดสินใจว่าจำเป็นต้องใช้ CSP แบบ nonce หรือ แฮชหรือไม่

นี่คือวิธีการทำงานของ CSP ที่เข้มงวด 2 ประเภท

CSP ที่อิงตาม Nonce

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

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

CSP ตามแฮช

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

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

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

เมื่อตั้งค่า CSP คุณมีตัวเลือก 3 รายการดังนี้

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

ตัวเลือก A: 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

ตัวอย่างวิธีเพิ่ม 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("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 ที่อิงตาม Noce องค์ประกอบ <script> ทุกรายการต้องมีแอตทริบิวต์ nonce ที่ตรงกับค่า Nonce แบบสุ่มที่ระบุไว้ในส่วนหัว CSP สคริปต์ทั้งหมดมีค่าที่ได้จากการสุ่มเดียวกันได้ ขั้นตอนแรกคือเพิ่มแอตทริบิวต์เหล่านี้ลงในสคริปต์ทั้งหมดเพื่อให้ 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 ในเบราว์เซอร์ต่างๆ สำหรับสคริปต์แทรกในบรรทัดเท่านั้น คุณจึงต้องโหลดสคริปต์ของบุคคลที่สามทั้งหมดแบบไดนามิกโดยใช้สคริปต์ในหน้า แฮชสำหรับสคริปต์ที่มาจากแอปไม่ได้รับการรองรับเป็นอย่างดีในเบราว์เซอร์ต่างๆ

ตัวอย่างวิธีแทรกสคริปต์ในหน้า
อนุญาตโดย 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 บล็อกสคริปต์เหล่านี้เนื่องจากคุณแฮชได้เฉพาะสคริปต์ในบรรทัดเท่านั้น

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

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

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

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

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

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

รายงานการละเมิด CSP ใน Developer Console ของ 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 (ไม่บังคับ): เพิ่มรายการสำรองเพื่อรองรับเบราว์เซอร์เวอร์ชันเก่า

การสนับสนุนเบราว์เซอร์

  • 52
  • 79
  • 52
  • 15.4

แหล่งที่มา

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

  • การใช้ strict-dynamic จำเป็นต้องมีการเพิ่ม https: เป็นทางเลือกสำหรับ Safari เวอร์ชันก่อนหน้า สิ่งที่จะเกิดขึ้นเมื่อคุณดำเนินการต่อไปนี้
    • เบราว์เซอร์ทั้งหมดที่รองรับ strict-dynamic จะไม่สนใจ https: สำรอง ดังนั้นการดำเนินการนี้จะไม่ลดความเข้มงวดของนโยบายลง
    • ในเบราว์เซอร์รุ่นเก่า สคริปต์ที่มาจากภายนอกจะโหลดได้เฉพาะสคริปต์ที่มาจากต้นทาง HTTPS เท่านั้น การดำเนินการนี้มีความปลอดภัยน้อยกว่า CSP ที่เข้มงวด แต่ยังคงป้องกันสาเหตุทั่วไปบางอย่างของ XSS ได้ เช่น การแทรก URI javascript:
  • คุณเพิ่ม 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 จะลดรูปแบบการโจมตีลงได้อย่างมากโดยการปฏิเสธรูปแบบที่เป็นอันตราย เช่น URI javascript: อย่างไรก็ตาม อาจมีกรณีที่ CSP ไม่ปกป้องแอปของคุณด้วย ทั้งนี้ขึ้นอยู่กับประเภทของ CSP ที่คุณใช้ (Nonces, Hasss, มีหรือไม่มี '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 อื่นๆ ที่ไม่ค่อยได้ใช้

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

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