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';
![](https://web.developers.google.cn/static/articles/strict-csp/image/er4BaGCJzBwDaESFKfZd.jpg?authuser=5&hl=th)
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 ที่เข้มงวด คุณต้องทำดังนี้
- เลือกว่าจะให้แอปพลิเคชันของคุณตั้งค่า CSP แบบ nonce หรือ แฮช หรือไม่
- คัดลอก CSP จากส่วนโครงสร้าง CSP ที่เข้มงวด และตั้งค่าเป็นส่วนหัวการตอบกลับในแอปพลิเคชัน
- เปลี่ยนโครงสร้างของเทมเพลต HTML และโค้ดฝั่งไคลเอ็นต์เพื่อนำรูปแบบที่ใช้ร่วมกับ CSP ไม่ได้ออก
- ทำให้ CSP ใช้งานได้
คุณสามารถใช้ Lighthouse
(v7.3.0 ขึ้นไปที่มีแฟล็ก --preset=experimental
) การตรวจสอบแนวทางปฏิบัติแนะนำตลอดกระบวนการนี้เพื่อตรวจสอบว่าเว็บไซต์ของคุณมี CSP หรือไม่ และเว็บไซต์มี CSP อย่างเข้มงวดเพียงพอต่อ XSS หรือไม่
![คำเตือนจากรายงาน Lighthouse ว่าไม่พบ CSP ในโหมดบังคับใช้](https://web.developers.google.cn/static/articles/strict-csp/image/lighthouse-report-warning-74f66e2ef76dc.png?authuser=5&hl=th)
ขั้นตอนที่ 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 ไม่รองรับโหมดรายงานเท่านั้น
ตั้งค่าส่วนหัวการตอบกลับ 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 ในเฟรมเวิร์กฝั่งเซิร์ฟเวอร์มีดังนี้
- Django (งูหลาม)
- Express (JavaScript):
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 อนุญาต
ตั้งค่าส่วนหัวการตอบกลับ 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 ในเบราว์เซอร์ต่างๆ สำหรับสคริปต์แทรกในบรรทัดเท่านั้น คุณจึงต้องโหลดสคริปต์ของบุคคลที่สามทั้งหมดแบบไดนามิกโดยใช้สคริปต์ในหน้า แฮชสำหรับสคริปต์ที่มาจากแอปไม่ได้รับการรองรับเป็นอย่างดีในเบราว์เซอร์ต่างๆ
![](https://web.developers.google.cn/static/articles/strict-csp/image/B2YsfJDYw8PRI6kJI7Bs.jpg?authuser=5&hl=th)
<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}
หากต้องการลดจำนวนแฮช ให้ผสานสคริปต์ในบรรทัดทั้งหมดเป็นสคริปต์เดียว หากต้องการดูการทำงานจริง ให้ดูตัวอย่างนี้และโค้ด
<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](https://web.developers.google.cn/static/articles/strict-csp/image/csp-violation-reports-th-ff599b24b17be.jpg?authuser=5&hl=th)
ในกรณีส่วนใหญ่ การแก้ไขจะทำได้ง่ายดังนี้
เปลี่ยนตัวแฮนเดิลเหตุการณ์แบบอินไลน์
<span id="things">A thing.</span> <script nonce="${nonce}"> document.getElementById('things').addEventListener('click', doThings); </script>CSP อนุญาตตัวแฮนเดิลเหตุการณ์ที่ลงทะเบียนโดยใช้ JavaScript
<span onclick="doThings();">A thing.</span>CSP บล็อกเครื่องจัดการเหตุการณ์ในบรรทัด
เปลี่ยนโครงสร้างของ URI javascript:
รายการ
<a id="foo">foo</a> <script nonce="${nonce}"> document.getElementById('foo').addEventListener('click', linkClicked); </script>CSP อนุญาตตัวแฮนเดิลเหตุการณ์ที่ลงทะเบียนโดยใช้ JavaScript
<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 (ไม่บังคับ): เพิ่มรายการสำรองเพื่อรองรับเบราว์เซอร์เวอร์ชันเก่า
หากคุณต้องการรองรับเบราว์เซอร์เวอร์ชันเก่า ให้ทำดังนี้
- การใช้
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 ใช้งานได้ในการทดลองใช้ จากนั้นจึงทำให้ใช้งานได้กับสภาพแวดล้อมการใช้งานจริง ดังนี้
- (ไม่บังคับ) ทำให้ CSP ใช้งานได้ในโหมดรายงานเท่านั้นโดยใช้ส่วนหัว
Content-Security-Policy-Report-Only
โหมดรายงานเท่านั้นมีประโยชน์ในการทดสอบการเปลี่ยนแปลงที่อาจส่งผลเสีย เช่น CSP ใหม่ในเวอร์ชันที่ใช้งานจริงก่อนที่คุณจะเริ่มบังคับใช้ข้อจำกัดของ CSP ในโหมดรายงานเท่านั้น CSP จะไม่ส่งผลกระทบต่อลักษณะการทำงานของแอป แต่เบราว์เซอร์จะยังคงสร้างข้อผิดพลาดของคอนโซลและรายงานการละเมิดเมื่อพบรูปแบบที่เข้ากันไม่ได้กับ CSP ของคุณ คุณจึงดูได้ว่าผู้ใช้ปลายทางมีปัญหาอะไรบ้าง สำหรับข้อมูลเพิ่มเติม โปรดดู Reporting API - เมื่อมั่นใจว่า 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')
) รวมถึงในฟังก์ชันไลบรารีที่สร้างโหนด DOMscript
ตามค่าของอาร์กิวเมนต์ ซึ่งรวมถึง API ทั่วไปบางรายการ เช่น.html()
ของ jQuery รวมถึง.get()
และ.post()
ใน jQuery < 3.0 - หากมีการแทรกเทมเพลตในแอปพลิเคชัน AngularJS เก่า ผู้โจมตีที่สามารถแทรกลงในเทมเพลต AngularJS จะใช้รูปแบบนี้เพื่อเรียกใช้ JavaScript ที่กำหนดเอง
- หากนโยบายมี
'unsafe-eval'
, การแทรกในeval()
,setTimeout()
และ API อื่นๆ ที่ไม่ค่อยได้ใช้
นักพัฒนาซอฟต์แวร์และวิศวกรด้านความปลอดภัยควรให้ความสนใจเป็นพิเศษกับรูปแบบดังกล่าวในระหว่างการตรวจสอบโค้ดและการตรวจสอบความปลอดภัย ดูรายละเอียดเพิ่มเติมเกี่ยวกับกรณีเหล่านี้ได้ในนโยบายรักษาความปลอดภัยเนื้อหา: ความเป็นระเบียบระหว่างการปิดช่องโหว่และการบรรเทาปัญหาให้สำเร็จ
อ่านเพิ่มเติม
- CSP เลิกใช้แล้ว ปล่อยให้ CSP ใช้งานได้นาน เรื่องความปลอดภัยของรายการที่อนุญาตพิเศษและอนาคตของนโยบายรักษาความปลอดภัยเนื้อหา
- ผู้ประเมิน CSP
- การประชุม LocoMoco: นโยบายรักษาความปลอดภัยเนื้อหา - ความยุ่งเหยิงที่เกิดขึ้นระหว่างการปิดช่องโหว่และการบรรเทาปัญหา
- Google I/O Talk: การรักษาความปลอดภัยให้เว็บแอปด้วยฟีเจอร์แพลตฟอร์มที่ทันสมัย