นโยบายความปลอดภัยของเนื้อหาทำงานอย่างไร


248

ฉันได้รับข้อผิดพลาดมากมายในคอนโซลนักพัฒนาซอฟต์แวร์:

ปฏิเสธที่จะประเมินสตริง

ปฏิเสธที่จะเรียกใช้สคริปต์แบบอินไลน์เนื่องจากละเมิดคำสั่งนโยบายความปลอดภัยเนื้อหาต่อไปนี้

ปฏิเสธที่จะโหลดสคริปต์

ปฏิเสธที่จะโหลดสไตล์ชีท

ทั้งหมดนี้เกี่ยวกับอะไร นโยบายความปลอดภัยของเนื้อหาทำงานอย่างไร ฉันจะใช้Content-Security-Policyส่วนหัว HTTP ได้อย่างไร

โดยเฉพาะวิธีการ ...

  1. ... อนุญาตให้ใช้หลายแหล่งได้หรือไม่
  2. ... ใช้คำสั่งที่แตกต่างกันอย่างไร
  3. ... ใช้หลายคำสั่งหรือไม่
  4. ... จัดการพอร์ตหรือไม่
  5. ... จัดการโปรโตคอลที่แตกต่างกันอย่างไร
  6. ... อนุญาตfile://โปรโตคอลหรือไม่
  7. ... ใช้สไตล์อินไลน์สคริปต์และแท็ก<style>และ<script>?
  8. ... ช่วยให้eval()?

และในที่สุดก็:

  1. 'self'หมายความว่าอะไรกันแน่?

คำตอบ:


557

Content-Security-Policyเมตาแท็กช่วยให้คุณสามารถลดความเสี่ยงของXSSการโจมตีโดยช่วยให้คุณสามารถกำหนดทรัพยากรที่สามารถโหลดได้จากการป้องกันเบราว์เซอร์จากการโหลดข้อมูลจากสถานที่อื่น ๆ ทำให้ผู้โจมตีสามารถฉีดโค้ดที่เป็นอันตรายลงในไซต์ของคุณได้ยากขึ้น

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

เพื่อความกระชับฉันจะไม่เขียนแท็กแบบเต็มในแต่ละตัวอย่าง แต่ฉันจะแสดงเฉพาะcontentคุณสมบัติเท่านั้นดังนั้นตัวอย่างที่ระบุว่ามีความcontent="default-src 'self'"หมาย:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

1. จะอนุญาตให้ใช้หลายแหล่งได้อย่างไร

คุณสามารถแสดงรายการแหล่งที่มาของคุณหลังจากคำสั่งเป็นรายการคั่นด้วยช่องว่าง:

content="default-src 'self' https://example.com/js/"

ทราบว่ามีคำพูดรอบพารามิเตอร์อื่น ๆ กว่าไม่มีพิเศษ'self'คนเช่น นอกจากนี้ยังไม่มีเครื่องหมายทวิภาค ( :) หลังจากคำสั่ง เพียงแค่คำสั่งแล้วรายการพารามิเตอร์คั่นด้วยช่องว่าง

ทุกอย่างด้านล่างพารามิเตอร์ที่ระบุนั้นได้รับอนุญาตโดยปริยาย ซึ่งหมายความว่าในตัวอย่างข้างต้นเหล่านี้จะเป็นแหล่งข้อมูลที่ถูกต้อง:

https://example.com/js/file.js
https://example.com/js/subdir/anotherfile.js

อย่างไรก็ตามสิ่งเหล่านี้จะไม่ถูกต้อง:

http://example.com/js/file.js
^^^^ wrong protocol

https://example.com/file.js
                   ^^ above the specified path

2. วิธีการใช้คำสั่งต่าง ๆ พวกเขาแต่ละคนจะทำอย่างไร?

คำสั่งที่พบบ่อยที่สุดคือ:

  • default-src นโยบายเริ่มต้นสำหรับการโหลดจาวาสคริปต์รูปภาพ CSS แบบอักษรคำขอ AJAX และอื่น ๆ
  • script-src กำหนดแหล่งที่ถูกต้องสำหรับไฟล์จาวาสคริปต์
  • style-src กำหนดแหล่งที่ถูกต้องสำหรับไฟล์ css
  • img-src กำหนดแหล่งที่มาที่ถูกต้องสำหรับภาพ
  • connect-srcกำหนดเป้าหมายที่ถูกต้องสำหรับ XMLHttpRequest (AJAX), WebSockets หรือ EventSource หากมีการพยายามเชื่อมต่อกับโฮสต์ที่ไม่ได้รับอนุญาตที่นี่เบราว์เซอร์จะเลียนแบบ400ข้อผิดพลาด

มีคนอื่น ๆ แต่สิ่งเหล่านี้เป็นสิ่งที่คุณต้องการมากที่สุด

3. วิธีใช้หลายคำสั่ง?

คุณกำหนดคำสั่งทั้งหมดของคุณภายในหนึ่งเมตาแท็กโดยยกเลิกพวกเขาด้วยเครื่องหมายอัฒภาค ( ;):

content="default-src 'self' https://example.com/js/; style-src 'self'"

4. วิธีจัดการพอร์ต

ทุกอย่างยกเว้นพอร์ตเริ่มต้นจะต้องได้รับอนุญาตอย่างชัดเจนโดยการเพิ่มหมายเลขพอร์ตหรือเครื่องหมายดอกจันหลังจากโดเมนที่อนุญาต:

content="default-src 'self' https://ajax.googleapis.com http://example.com:123/free/stuff/"

ข้างต้นจะส่งผลให้:

https://ajax.googleapis.com:123
                           ^^^^ Not ok, wrong port

https://ajax.googleapis.com - OK

http://example.com/free/stuff/file.js
                 ^^ Not ok, only the port 123 is allowed

http://example.com:123/free/stuff/file.js - OK

ดังที่ได้กล่าวไปแล้วคุณสามารถใช้เครื่องหมายดอกจันเพื่ออนุญาตพอร์ตทั้งหมด:

content="default-src example.com:*"

5. วิธีจัดการโปรโตคอลที่แตกต่างกันอย่างไร

ตามค่าเริ่มต้นอนุญาตให้ใช้โปรโตคอลมาตรฐานเท่านั้น ตัวอย่างเช่นเพื่ออนุญาต WebSockets ws://คุณจะต้องอนุญาตอย่างชัดเจน:

content="default-src 'self'; connect-src ws:; style-src 'self'"
                                         ^^^ web sockets are now allowed on all domains and ports

6. จะอนุญาตให้ใช้โปรโตคอลไฟล์ได้file://อย่างไร

หากคุณจะพยายามกำหนดให้มันไม่ทำงาน คุณจะอนุญาตให้ใช้filesystemพารามิเตอร์แทน:

content="default-src filesystem"

7. วิธีใช้สคริปต์แบบอินไลน์และนิยามสไตล์?

เว้นแต่จะได้รับอนุญาตอย่างชัดเจนคุณไม่สามารถใช้คำจำกัดความสไตล์แบบอินไลน์รหัสภายในแท็กหรือในคุณสมบัติของแท็กเช่น<script> onclickคุณอนุญาตให้พวกเขาชอบ:

content="script-src 'unsafe-inline'; style-src 'unsafe-inline'"

คุณจะต้องอนุญาตรูปภาพที่เข้ารหัสแบบอินไลน์ base64 อย่างชัดเจน:

content="img-src data:"

8. วิธีการอนุญาตให้eval()?

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

content="script-src 'unsafe-eval'"

9. 'self'หมายความว่าอย่างไร

คุณอาจ'self'หมายถึง localhost, ระบบไฟล์โลคอลหรืออะไรก็ได้ในโฮสต์เดียวกัน มันไม่ได้หมายความว่าอย่างใดอย่างหนึ่ง หมายถึงแหล่งที่มีรูปแบบ (โปรโตคอล) โฮสต์เดียวกันและพอร์ตเดียวกันกับไฟล์ที่มีการกำหนดนโยบายเนื้อหาไว้ให้บริการไซต์ของคุณผ่าน HTTP หรือไม่ ไม่มี https สำหรับคุณยกเว้นกรณีที่คุณกำหนดไว้อย่างชัดเจน

ฉันใช้'self'ในตัวอย่างส่วนใหญ่เนื่องจากปกติแล้วจะมีเหตุผลที่จะรวมไว้ แต่ก็ไม่จำเป็นต้องมี ปล่อยทิ้งไว้หากคุณไม่ต้องการ

แต่เดี๋ยวก่อน! ฉันไม่สามารถใช้content="default-src *"และทำได้ด้วยหรือไม่

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

content="default-src * 'unsafe-inline' 'unsafe-eval'"

... แต่ฉันเชื่อว่าคุณจะไม่ทำ

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

http://content-security-policy.com

http://en.wikipedia.org/wiki/Content_Security_Policy


6
โพสต์ยอดเยี่ยม สิ่งหนึ่ง: ไม่ชัดเจนว่าเกิดอะไรขึ้นเมื่อมีการระบุคำสั่งหลายอย่าง การตั้งค่า style-src ในตัวอย่างที่ 3 มีความสำคัญมากกว่า default-src หรือไม่ ฯลฯ ...
track0

30
ดังนั้นเพื่อให้ทุกสิ่งทุกอย่างทุกอย่างเนื้อหาจะเป็นdefault-src *; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'; img-src * data: 'unsafe-inline'; connect-src * 'unsafe-inline'; frame-src *;
Arnold Roa

8
สิ่งสำคัญคือการรู้ว่าcontent="default-src * 'unsafe-inline' 'unsafe-eval'"จำเป็นต้องทำให้แอปพลิเคชันเชิงมุมบางอันทำงานได้
flanger001

2
@Mahesh ว่า "บล็อก" เต็มไปด้วยโพสต์ที่คัดลอกมาจาก SO ดูเหมือนว่ามีผู้ใช้งานจำนวนมากดังนั้นจะคัดลอกเนื้อหาจากบล็อกเกอร์ที่ไม่รู้จัก - ฉันรู้ว่าฉันไม่ได้ทำ
Schlaus

2
หมายเหตุสั้น ๆ เกี่ยวกับconnect-srcและพา ธ : เครื่องหมายสแลชต่อท้ายจำเป็นถ้าคุณต้องการรวมพา ธ ย่อยทั้งหมด เช่น: ไฟล์http://foo.com/files/bar.txtจะถูกบล็อกหากแหล่งที่มาเป็นhttp://foo.com/filesแต่จะให้บริการเมื่อมันhttp://foo.com/files/
Griddo

15

APACHE2 MOD_HEADERS

คุณสามารถเปิดใช้งาน Apache2 mod_headers บน Fedora ได้เปิดใช้งานตามค่าเริ่มต้นแล้วหากคุณใช้ Ubuntu / Debian ให้เปิดใช้งานเช่นนี้:

# First enable headers module for Apache2, 
# then restart the Apache2 service   
a2enmod headers
apache2 -k graceful

บน Ubuntu / Debian คุณสามารถกำหนดค่าส่วนหัวในไฟล์ /etc/apache2/conf-enabled/security.conf

#
# Setting this header will prevent MSIE from interpreting files as something
# else than declared by the content type in the HTTP headers.
# Requires mod_headers to be enabled.
# 
#Header set X-Content-Type-Options: "nosniff"

#
# Setting this header will prevent other sites from embedding pages from this
# site as frames. This defends against clickjacking attacks.
# Requires mod_headers to be enabled.
#
Header always set X-Frame-Options: "sameorigin"
Header always set X-Content-Type-Options nosniff
Header always set X-XSS-Protection "1; mode=block"
Header always set X-Permitted-Cross-Domain-Policies "master-only"
Header always set Cache-Control "no-cache, no-store, must-revalidate"
Header always set Pragma "no-cache"
Header always set Expires "-1"
Header always set Content-Security-Policy: "default-src 'none';"
Header always set Content-Security-Policy: "script-src 'self' www.google-analytics.com adserver.example.com www.example.com;"
Header always set Content-Security-Policy: "style-src 'self' www.example.com;"

หมายเหตุ: นี่คือส่วนล่างของไฟล์เฉพาะ 3 รายการสุดท้ายเท่านั้นที่มีการตั้งค่า CSP

พารามิเตอร์แรกคือคำสั่งที่สองเป็นแหล่งที่จะเป็นสีขาว ฉันได้เพิ่มการวิเคราะห์ของ Google และเซิร์ฟเวอร์โฆษณาซึ่งคุณอาจมี นอกจากนี้ฉันพบว่าหากคุณมีนามแฝงเช่น www.example.com และ example.com กำหนดค่าใน Apache2 คุณควรเพิ่มพวกเขาไปยังรายการสีขาวเช่นกัน

โค้ดอินไลน์ถือว่าเป็นอันตรายคุณควรหลีกเลี่ยง คัดลอก javascripts และ css ทั้งหมดไปยังไฟล์แยกกันและเพิ่มไปยังรายการสีขาว

ในขณะที่คุณอยู่ที่นี่คุณสามารถดูการตั้งค่าส่วนหัวอื่น ๆ และติดตั้ง mod_security

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

https://developers.google.com/web/fundamentals/security/csp/

https://www.w3.org/TR/CSP/


2
ฉันสามารถเพิ่มคำสั่งเดียวกันเหล่านั้นลงในไฟล์. htaccess ของฉันเนื่องจากฉันไม่มีความสามารถในการแก้ไขการกำหนดค่า Apache บนโฮสต์ที่ใช้ร่วมกันของฉัน ผมพบว่าเครื่องมือที่ดีเยี่ยมสำหรับการปรับตั้งค่าเหล่านี้report-uri.io/home/tools
Michael McGinnis

มีวิธีใดบ้างในการแก้ไขปัญหานี้ด้วยโพง 7 7. ฉันได้ลองเพิ่มตัวกรองแล้วใช้งานไม่ได้
Elshan

0

อย่าลืม font-src มันใช้งานได้เหมือนกัน แต่ถ้าคุณใช้แบบอักษรที่โหลดมาจากต้นกำเนิดอื่น - ตรวจสอบให้แน่ใจว่าคุณเพิ่มลงในเมตาแท็ก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.