0Pricing
Frontend Academy · บทเรียน

การป้องกัน XSS: การเข้ารหัสเอาต์พุตและ CSP

ทำความเข้าใจ XSS แบบสะท้อนกลับ แบบจัดเก็บ และแบบอิง DOM หลีกเลี่ยงเอาต์พุตที่ผู้ใช้ควบคุม หลีกเลี่ยง innerHTML กับข้อมูลที่ไม่น่าเชื่อถือ และเพิ่มส่วนหัว Content Security Policy

การป้องกัน XSS: การเข้ารหัสเอาต์พุตและ CSP เป็นบทเรียน Frontend Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Frontend Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน

XSS คืออะไร

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

XSS สามรูปแบบ

แบบจัดเก็บ: สคริปต์อันตรายถูกบันทึกไว้ในฐานข้อมูลและส่งให้ผู้เข้าชมทุกคน แบบสะท้อนกลับ: อินพุตถูกส่งกลับมาในคำตอบ (?q=<script>...) แบบอิง DOM: JS ฝั่งไคลเอ็นต์เขียนข้อมูลที่ไม่น่าเชื่อถือลงใน DOM

สาเหตุหลัก: innerHTML กับข้อมูลที่ไม่น่าเชื่อถือ

การใช้ innerHTML (หรือ v-html, dangerouslySetInnerHTML) กับสตริงที่ผู้ใช้ควบคุมได้ เป็นช่องทาง XSS อันดับหนึ่ง

// BAD: user input rendered as HTML
el.innerHTML = userComment;  // attacker submits <img onerror=alert(1)>

// Vue equivalent:
<div v-html="userComment"></div>  // same bug

// React equivalent:
<div dangerouslySetInnerHTML={{ __html: userComment }} />  // same bug

การเข้ารหัสเอาต์พุต (ค่าเริ่มต้นที่ปลอดภัย)

ปฏิบัติต่อสตริงที่ไม่น่าเชื่อถือในฐานะข้อความ ไม่ใช่ HTML โดย React, Vue, Angular และ Svelte จะทำเช่นนี้เป็นค่าเริ่มต้นในการแทรกค่า {value}

// SAFE: text content, not HTML
el.textContent = userComment;  // <script> shows as literal text

// React (auto-escaped):
<div>{userComment}</div>

// Vue (auto-escaped):
<div>{{ userComment }}</div>

การทำให้ปลอดภัยเมื่อต้องแสดงผล HTML

หากจำเป็นต้องแสดง HTML ที่ผู้ใช้ป้อนจริง ๆ เช่น ในเครื่องมือแก้ไขข้อความแบบมีรูปแบบ ให้ทำให้ข้อมูลปลอดภัยด้วย DOMPurify อย่าเขียนตัวกรองด้วยนิพจน์ทั่วไปขึ้นมาเอง

import DOMPurify from 'dompurify';

const clean = DOMPurify.sanitize(userHtml);
el.innerHTML = clean; // strips <script>, on* handlers, dangerous URLs

การตรวจสอบ URL

URL ที่ผู้ใช้ควบคุมได้ใน href หรือ src อาจทำให้เกิด XSS ผ่านรูปแบบ javascript: ได้

// BAD:
<a href={userUrl}>Click</a>
// attacker submits: javascript:alert(1)

// GOOD: whitelist protocols:
function safeUrl(url) {
  if (!/^https?:\/\//.test(url) && !url.startsWith('/')) return '#';
  return url;
}

นโยบายความปลอดภัยของเนื้อหา (CSP)

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

Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.trusted.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:

CSP ที่เข้มงวดด้วย Nonces

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

// Server generates a random nonce per request:
const nonce = crypto.randomBytes(16).toString('base64');
res.setHeader('Content-Security-Policy', `script-src 'nonce-${nonce}' 'strict-dynamic'`);

// Inject into the HTML:
<script nonce="abc123">/* trusted inline code */</script>

คุกกี้ HttpOnly + Secure

ตั้งค่าคุกกี้เซสชันด้วย HttpOnly เพื่อไม่ให้ JavaScript อ่านคุกกี้ได้ แม้จะเกิด XSS ผู้โจมตีก็ไม่สามารถขโมยโทเค็นเซสชันได้

Set-Cookie: session=abc; HttpOnly; Secure; SameSite=Strict

ความสมบูรณ์ของทรัพยากรย่อย (SRI)

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

<script
  src="https://cdn.example.com/lib.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
  crossorigin="anonymous"
></script>

ประเภทที่เชื่อถือได้ (ทดลอง)

ประเภทที่เชื่อถือได้เป็นความสามารถของเบราว์เซอร์ (ที่ใช้ Chromium) ซึ่งบังคับให้จุดรับข้อมูลอันตราย (innerHTML) ต้องได้รับออบเจ็กต์ประเภทที่เชื่อถือได้ จึงป้องกันไม่ให้แทรกสตริงได้โดยสิ้นเชิง

การทดสอบหา XSS

ลองแทรก <img src=x onerror=alert(1)> ลงในช่องป้อนข้อความทุกช่องที่ถูกนำมาแสดงผลอีกครั้ง หากเห็นการแจ้งเตือน แสดงว่ามีช่องโหว่ XSS ใช้เครื่องมืออย่าง OWASP ZAP เพื่อสแกนอัตโนมัติ

ตรวจสอบอย่างรวดเร็ว

เหตุใด {userInput} ของ React จึงปลอดภัยโดยค่าเริ่มต้น แต่ dangerouslySetInnerHTML กลับไม่ปลอดภัย

สรุป: การป้องกัน XSS

เลือกใช้การแสดงผลเป็นข้อความเป็นค่าเริ่มต้น ({x} ของ React และ {{ x }} ของ Vue ปลอดภัย) ใช้ DOMPurify กรองเมื่อแสดงผล HTML กำหนดรายการโปรโตคอล URL ที่อนุญาต ส่วนหัว CSP (ที่มีค่า nonce หรือ 'strict-dynamic') จะบล็อกสคริปต์ที่ถูกแทรก คุกกี้ HttpOnly ป้องกันการขโมยโดย JS ใช้ค่า hash ของ SRI สำหรับสคริปต์จาก CDN ทดสอบข้อมูลป้อนเข้าด้วยเพย์โหลดแบบคลาสสิก

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

บทเรียน “การป้องกัน XSS: การเข้ารหัสเอาต์พุตและ CSP” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การป้องกัน XSS: การเข้ารหัสเอาต์พุตและ CSP” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Frontend Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การป้องกัน XSS: การเข้ารหัสเอาต์พุตและ CSP”

ทำความเข้าใจ XSS แบบสะท้อนกลับ แบบจัดเก็บ และแบบอิง DOM หลีกเลี่ยงเอาต์พุตที่ผู้ใช้ควบคุม หลีกเลี่ยง innerHTML กับข้อมูลที่ไม่น่าเชื่อถือ และเพิ่มส่วนหัว Content Security Policy คุณปฏิบัติ Frontend Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Frontend Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Frontend Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “การป้องกัน XSS: การเข้ารหัสเอาต์พุตและ CSP” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Frontend Academy นี้ได้ไหม

ได้ บทเรียน Frontend Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การป้องกัน XSS: การเข้ารหัสเอาต์พุตและ CSP
  2. CSRF: คุกกี้และโทเค็น SameSite
  3. Content Security Policy: nonce และแฮช
  4. โฟลว์ OAuth จากฟรอนต์เอนด์
← กลับไปที่ Frontend Academy