Defaults.Exposed

Defaults.Exposedการแก้ไข › การป้องกัน MIME-sniffing (X-Content-Type-Options)

วิธีแก้ไข การป้องกัน MIME-sniffing (X-Content-Type-Options)

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

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

สิ่งนี้อาจทำให้คุณเสียค่าใช้จ่าย

เหตุใดจึงสำคัญ เบราว์เซอร์เมื่อเซิร์ฟเวอร์คลุมเครือเกี่ยวกับประเภทของไฟล์จะพยายามเดา ('sniff') ประเภทเนื้อหา ผู้โจมตีใช้ประโยชน์จากการเดานั้น: อัปโหลดไฟล์ที่เซิร์ฟเวอร์ระบุว่าเป็นภาพอย่างซื่อสัตย์ แต่ทำให้เนื้อหาของมันเพื่อให้เบราว์เซอร์ตัดสินว่าเป็น JavaScript จริงๆ — และรันมัน header `X-Content-Type-Options: nosniff` บอกทุกเบราว์เซอร์ให้หยุดเดาและไว้วางใจประเภทที่เซิร์ฟเวอร์ระบุ ปิดคลาสทั้งหมดของเล่ห์กลนั้น

เวอร์ชันสั้นสำหรับเจ้าของ

มีสมมติฐานเงียบๆ ที่สร้างอยู่ในเบราว์เซอร์ทุกตัว: เมื่อดาวน์โหลดไฟล์จากเว็บไซต์ของคุณ มันพยายามหาว่าไฟล์เป็นประเภทใด โดยปกติมันไว้วางใจเซิร์ฟเวอร์ของคุณ แต่ถ้าเซิร์ฟเวอร์ของคุณคลุมเครือ เบราว์เซอร์จะเดา — และการเดานั้นเรียกว่า MIME-sniffing

ปัญหาคือผู้โจมตีสามารถปรับแต่งการเดาได้ พวกมันสามารถสร้างไฟล์ที่เซิร์ฟเวอร์ของคุณคิดว่าเป็นภาพที่บริสุทธิ์ แต่เบราว์เซอร์ที่ถูกปล่อยให้เดา ตัดสินใจว่าจริงๆ แล้วเป็นโค้ดโปรแกรม — จากนั้นรันมัน ภายในเบราว์เซอร์ของลูกค้า บนโดเมนของคุณ

มีคำสั่งหนึ่งบรรทัดที่ปิดการเดา: X-Content-Type-Options: nosniff มันบอกทุกเบราว์เซอร์ว่า “อย่าเดา — ไว้วางใจสิ่งที่เซิร์ฟเวอร์ของฉันบอกคุณ” นั่นคือการแก้ไขทั้งหมด ฟรี ใช้เวลาประมาณห้านาที และบนเว็บไซต์ที่สร้างอย่างถูกต้องไม่ทำให้อะไรเสียหาย

สิ่งนี้อาจทำให้คุณสูญเสียอะไร

มันคืออะไรจริงๆ

เมื่อเบราว์เซอร์รับไฟล์ เซิร์ฟเวอร์ควรระบุด้วย content type (เช่น image/png สำหรับภาพ PNG หรือ text/html สำหรับหน้าเว็บ) ในอดีต เบราว์เซอร์ไม่ไว้วางใจ label นั้นอย่างเต็มที่ — บางส่วนเพราะเซิร์ฟเวอร์บางตัวทำผิด — ดังนั้นจึงส่องดูไบต์จริงของไฟล์และตัดสินใจด้วยตัวเอง การส่องดูนั้นคือ MIME-sniffing

X-Content-Type-Options: nosniff ลบการเดาออกอย่างสมบูรณ์ ด้วยมันถูกตั้ง เบราว์เซอร์จะถูกบอก: ใช้ประเภทที่เซิร์ฟเวอร์ประกาศและไม่มีอะไรอื่น ไฟล์ที่ระบุว่าเป็นภาพจะถูกปฏิบัติเป็นภาพ จบ — แม้ว่าเนื้อหาของมันดูเหมือนสคริปต์ เวกเตอร์การโจมตีปิด

สิ่งที่ “ดี” ดูเหมือน: ทุก response จากเว็บไซต์ของคุณ — หน้าและ asset เหมือนกัน — มี header นี้อย่างแน่ชัด:

X-Content-Type-Options: nosniff

วิธีแก้ไข (ฟรี ประมาณ 5 นาที)

ส่งส่วนนี้ให้ใครก็ตามที่รันเว็บไซต์ของคุณ — การแก้ไขฟรีและเร็ว ไม่มีอะไรต้องซื้อ สิ่งที่คุณของ่ายๆ: “เพิ่ม response header X-Content-Type-Options: nosniff ไปทุกหน้าและ asset บนเว็บไซต์”

Cloudflare (หรือ CDN/proxy ที่คล้ายกัน):

Nginx:

add_header X-Content-Type-Options "nosniff" always;

Apache:

Header always set X-Content-Type-Options "nosniff"

IIS / Windows hosting — ใน web.config:

<httpProtocol>
  <customHeaders>
    <add name="X-Content-Type-Options" value="nosniff" />
  </customHeaders>
</httpProtocol>

Node / Express:

app.use((req, res, next) => {
  res.setHeader('X-Content-Type-Options', 'nosniff');
  next();
});

(หรือใช้แพ็กเกจ helmet ซึ่งตั้งนี้และ security header อื่นๆ หลายอย่างโดยค่าเริ่มต้น)

หลังจากปรับใช้ ยืนยันมัน รีรันการสแกน หรือให้นักพัฒนาตรวจสอบ response header ใน browser developer tools (Network tab → click any request → Response Headers) และยืนยันว่า X-Content-Type-Options: nosniff มีอยู่

ข้อผิดพลาดทั่วไป

ส่งสิ่งนี้ให้ฝ่าย IT ของคุณ

สรุปทางเทคนิค: การตรวจสอบนี้ตรวจสอบ HTTP response header และผ่านเมื่อ X-Content-Type-Options มีอยู่และค่าของมัน (case-insensitive) ประกอบด้วย nosniff — รวมถึงกรณี multi-source nosniff, nosniff ที่ CDN และต้นทางทั้งสองตั้งมัน ขาดหรือค่าที่ไม่ใช่ nosniff ล้มเหลว มันเป็นการตรวจสอบ P2 ที่มีคะแนน 25 คะแนน ให้คะแนนปานกลางเมื่อล้มเหลว และแผนที่ไปยัง OWASP Top 10 A05 (Security Misconfiguration) การแก้ไขคือ static response header เดียวที่ใช้กับ response ทั้งหมด ตั้งมันที่ edge (CDN) เพื่อความครอบคลุมทั้งไซต์ หรือที่เว็บเซิร์ฟเวอร์ด้วย always semantics

คำถามที่พบบ่อย

เราไม่อนุญาตให้ใครอัปโหลดไฟล์ เราจำเป็นต้องทำสิ่งนี้ไหม?

ใช่ และยังคุ้มค่าที่จะทำ Header นี้เป็นการป้องกันเชิงลึก: มันยังหยุดเบราว์เซอร์จากการอ่านผิดสคริปต์ สไตล์ชีต และไฟล์ข้อมูลที่ให้บริการจากเว็บไซต์ของคุณเอง ซึ่งปกป้องจากเล่ห์กล cross-site-scripting หลายอย่างแม้บนเว็บไซต์ที่ไม่มีแบบฟอร์มอัปโหลด มันไม่มีค่าใช้จ่ายและไม่ทำให้เว็บไซต์ที่กำหนดค่าถูกต้องเสียหาย ดังนั้นไม่มีเหตุผลที่จะข้าม

การเพิ่มสิ่งนี้จะทำให้เว็บไซต์ของเราเสียหายไหม?

แทบไม่เลย nosniff ทำให้เบราว์เซอร์ยึดถือประเภทเนื้อหาที่เซิร์ฟเวอร์ของคุณส่งอยู่แล้ว วิธีเดียวที่มันทำให้เกิดปัญหาคือถ้าเซิร์ฟเวอร์ของคุณระบุประเภทไฟล์ผิด — เช่น ส่งสไตล์ชีทหรือสคริปต์ด้วยประเภทที่ผิด หากมีอะไรเสียหาย นั่นเป็นบั๊กจริงที่ nosniff เปิดเผยแทนที่จะก่อให้เกิด และคุ้มค่าที่จะแก้ไขอยู่แล้ว

สิ่งที่ 'ดี' ดูเหมือนอะไรจริงๆ?

Response header เดียวบนทุกหน้าและ asset: `X-Content-Type-Options: nosniff` นั่นคือการกำหนดค่าที่ถูกต้องทั้งหมด — ไม่มีค่าที่ถูกต้องอื่นๆ และไม่มีการปรับแต่งที่ต้องทำ

CDN ของเรา (Cloudflare หรือที่คล้ายกัน) และเซิร์ฟเวอร์ของเราเพิ่มมันทั้งคู่ — นั่นเป็นปัญหาไหม?

ไม่ การเห็นค่าสองครั้ง ('nosniff, nosniff') เพราะทั้ง CDN และต้นทางตั้งมันเป็นเรื่องปกติและยังผ่าน คุณไม่จำเป็นต้องลบอย่างใดอย่างหนึ่ง

การแก้ไขนี้มีค่าใช้จ่ายไหม?

ไม่ การแก้ไขเป็นการกำหนดค่าหนึ่งบรรทัดฟรีบนเว็บเซิร์ฟเวอร์หรือ CDN ของคุณ ใครก็ตามที่เรียกเก็บเงินจากคุณเพื่อเพิ่ม header เดียวนั้นเกินราคา

สิ่งนี้แตกต่างจาก Content Security Policy (CSP) อย่างไร?

พวกมันเสริมกัน CSP ควบคุมว่าสคริปต์และ resource ใดได้รับอนุญาตให้โหลดเลย nosniff หยุดเบราว์เซอร์จากการจัดประเภทไฟล์ผิดที่โหลด คุณต้องการทั้งสอง nosniff ง่ายกว่าและเร็วกว่ามากในการเพิ่ม ดังนั้นจึงเป็นก้าวแรกที่ดีในระหว่างทางไปยัง CSP ที่สมบูรณ์