Dev to webs {Coding…}

เรียนรู้การพัฒนาซอฟเวอร์ เพื่อความรู้ที่ยั่งยืน

บทที่ 45: การป้องกัน XSS


1. ความเข้าใจเกี่ยวกับ XSS (Cross-Site Scripting)

XSS (Cross-Site Scripting) เป็นช่องโหว่ด้านความปลอดภัยที่เกิดจากการแทรกโค้ด JavaScript ที่ไม่ปลอดภัยลงในหน้าเว็บ

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

การป้องกัน XSS เป็นสิ่งสำคัญในการพัฒนาเว็บที่ปลอดภัย โดยเฉพาะเมื่อใช้ JavaScript Framework อย่าง Alpine.js


2. การใช้ x-text แทน x-html

ตัวอย่าง 1: ใช้ x-text เพื่อป้องกัน XSS
<div x-data="{ message: '<script>alert(\"XSS\")</script>' }">
    <p x-text="message"></p>
</div>

คำอธิบาย:

  • x-text จะแสดงข้อความเป็น Plain Text โดยไม่แปลงเป็น HTML
  • ข้อความ <script> จะไม่ถูกประมวลผล ทำให้โค้ด JavaScript ไม่ทำงาน

3. การใช้ x-html อย่างปลอดภัย

ตัวอย่าง 2: กรอง HTML ก่อนแสดงด้วย x-html
<div x-data="{ rawHtml: '<h1>Hello</h1>' }">
    <p x-html="sanitize(rawHtml)"></p>
</div>

<script>
    function sanitize(html) {
        const div = document.createElement('div');
        div.textContent = html;
        return div.innerHTML;
    }
</script>

คำอธิบาย:

  • ฟังก์ชัน sanitize กรอง HTML โดยแปลงข้อความเป็น Plain Text ก่อนแสดง
  • ป้องกันไม่ให้โค้ด JavaScript ใน HTML ถูกประมวลผล

4. การใช้ Libraries สำหรับการป้องกัน XSS

ตัวอย่าง 3: ใช้ DOMPurify เพื่อกรอง HTML
<div x-data="{ rawHtml: '<script>alert(\"XSS\")</script><p>Safe Content</p>' }">
    <p x-html="DOMPurify.sanitize(rawHtml)"></p>
</div>

<script src="https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js"></script>

คำอธิบาย:

  • DOMPurify เป็น Library ที่ช่วยกรอง HTML และป้องกัน XSS
  • HTML ที่ไม่ปลอดภัยจะถูกลบออกก่อนแสดง

5. การป้องกัน XSS ในฟอร์ม

ตัวอย่าง 4: กรองข้อมูลที่ป้อนในฟอร์ม
<div x-data="{ input: '', sanitizedInput: '' }">
    <form @submit.prevent="sanitizedInput = sanitize(input)">
        <label for="message">Message:</label>
        <input type="text" id="message" x-model="input">
        <button type="submit">Submit</button>
    </form>
    <p>Sanitized Output: <span x-text="sanitizedInput"></span></p>
</div>

<script>
    function sanitize(input) {
        const div = document.createElement('div');
        div.textContent = input;
        return div.innerHTML;
    }
</script>

คำอธิบาย:

  • ฟังก์ชัน sanitize กรองข้อมูลที่ผู้ใช้ป้อนเพื่อป้องกัน XSS
  • ข้อความที่ไม่ปลอดภัยจะถูกแปลงเป็น Plain Text

6. การหลีกเลี่ยงการใช้ JavaScript ใน HTML

ตัวอย่าง 5: หลีกเลี่ยงการใช้ Event Inline
<div x-data="{ message: 'Click me' }">
    <!-- ไม่ควรใช้ -->
    <!-- <button onclick="alert('XSS')">Click</button> -->
    
    <!-- ควรใช้ -->
    <button @click="alert(message)">Click</button>
</div>

คำอธิบาย:

  • หลีกเลี่ยงการใช้ Event Inline เช่น onclick เพื่อป้องกันการแทรกโค้ด JavaScript ที่ไม่ปลอดภัย

7. การตรวจสอบและกรองข้อมูลใน Backend

ตัวอย่าง 6: กรองข้อมูลก่อนส่งกลับจากเซิร์ฟเวอร์
const express = require('express');
const app = express();
const DOMPurify = require('dompurify');

app.use(express.json());

app.post('/sanitize', (req, res) => {
    const sanitized = DOMPurify.sanitize(req.body.input);
    res.send({ sanitized });
});

คำอธิบาย:

  • การกรองข้อมูลในฝั่งเซิร์ฟเวอร์ช่วยเพิ่มความปลอดภัย
  • ใช้ Library เช่น DOMPurify เพื่อกรองข้อมูลก่อนส่งกลับไปยังผู้ใช้

8. ข้อควรระวังในการป้องกัน XSS

  1. หลีกเลี่ยงการใช้ eval:
    • การใช้ eval ทำให้โค้ดมีช่องโหว่สำหรับ XSS
  2. จำกัดการใช้ x-html:
    • ใช้เฉพาะในกรณีที่จำเป็น และกรอง HTML ด้วย Library
  3. ตรวจสอบข้อมูลที่ป้อน:
    • กรองข้อมูลจากผู้ใช้ในทั้งฝั่ง Frontend และ Backend

สรุป

ในบทนี้ คุณได้เรียนรู้วิธีป้องกัน XSS ใน Alpine.js ด้วยการใช้ x-text, x-html อย่างปลอดภัย, และการกรองข้อมูลด้วยฟังก์ชันหรือ Library เช่น DOMPurify การป้องกัน XSS ช่วยรักษาความปลอดภัยของแอปพลิเคชันและลดความเสี่ยงที่ข้อมูลผู้ใช้งานจะถูกโจมตี!