[Hacking] อย่าไว้ใจการเขียนโปรแกรมแสดงผลบน Web หากคุณไม่รู้จัก Stored XSS ดีพอ

Jame Sirichai
2 min readSep 16, 2019

--

บทความนี้ สำหรับชาว Geek ที่กำลังพัฒนาเว็บไซต์ และคิดว่าเว็บเราเขียนมาอย่างปลอดภัยดีแล้ว อ่านบทความนี้อาจจะคิดผิดก็ได้ครับ บทความนี้เราจะมาพูดถึงช่องโหว่ ที่ยอดนิยมมากๆ นั้นก็คือ Cross-site Scripting(XSS)

Cross-site Scripting(XSS)

อธิบายช่องโหว่นี้คร่าวๆ ก็คือ เป็นช่องโหว่ที่สามารถฝังตัว Script เช่นการฝังตัว Javascript เข้าไปบนตัวเว็บ ฝั่งเบราว์เซอร์ เพื่อโจมตีผู้ใช้งานคนอื่นๆ ที่ Run ตัว Script นี้ โดยช่องโหว่นี้อาศัยการโจมตีจาก การใช้อินพุตจากผู้ใช้งาน เช่นการกรอกข้อมูลบนฟอร์มต่างๆ โดยไม่มีการ validating หรือ encoding อย่างถูกวิธี

ช่องโหว่นี้เป็นจัดเป็นช่องโหว่ที่โดนแฮก TOP 10 อันดับที่โดนแฮกบ่อยมากๆ อ้างอิงจากตัว OWASP TOP 10 ปี 2017 ในส่วนของ A7 โดยแบ่งการโจมตีได้ 3 รูปแบบคือ

  1. Reflected XSS
  2. Stored XSS
  3. DOM XSS

ซึ่งซอฟแวร์ระดับโลกก็มีพลาดให้เห็นอยู่เรื่อยๆ ในโครงการ Bug Bounty ซึ่งมีการจ่ายเงินให้กับผู้เจอช่องโหว่ ยกตัวอย่างเช่นในกรณีของ Paypal ก็จ่ายให้มากถึง 2 หมื่นเหรียญ (ราวๆ 6 แสนบาท)

ที่ผมบอกไปมีสามรูปแบบ แต่ในวันนี้ผมจะมาพูดถึง Stored XSS อย่างเดียวก่อนนะครับเนื่องจากการโจมตีรูปแบบนี้ค่อนข้างซับซ้อน และการป้องกันแตกต่างกันไปในแต่ล่ะกรณี

Stored XSS

เป็นหนึ่งในรูปแบบการโจมตีของ XSS โดยการโจมตี Hacker จะส่ง Script ไปเก็บไว้ เช่นที่ฐานข้อมูล โดยหากมีผู้ใช้คนใดก็ตาม เรียกใช้ข้อมูลนี้ภายหลัง จะโดนโจมตีทันที เดียวไปดูตัวอย่างจริงๆกันครับ

วิธีการโจมตี

เรามาดูตัวอย่างจริงๆกันนะครับ หน้าตาเว็บที่ผมเตรียมไว้ประมาณนี้ เป็นหน้าเว็บสำหรับสมาชิก ให้ใส่ Email กับ Password วิธีการโจมตีก็คือ ฝังตัว Javascript ลงในช่อง Email เพื่อทำการสมัครสมาชิก ข้อมูลการสมัครสมาชิกก็จะอยู่ในฐานข้อมูล เมื่อมีผู้ดูแลระบบ เข้ามาเรียกใช้ข้อมูลนี้ เช่นการเปิดหน้าเว็บดูว่ามีสมัครชิกคนไหนอยู่ในระบบบ้าง ก็จะถูกแฮกทันที (เหตุผลที่ต้องฝังไปกับ Email เพราะ Password ส่วนใหญ่จะผ่านการ Hashing ซึ่งตัว Script จะถูกเปลี่ยนรูปกลายเป็น Hash เลยโจมตีไม่ได้ แต่ถ้าเก็บเป็น plant text ก็โดนเหมือนกัน )

หรือตัวอย่างเว็บ OLX สามารถฝัง Javascript เข้าไปได้ในช่องกรอกข้อมูล โดยไม่มีการตรวจสอบข้อมูล เมื่อมีผู้ใช้คนอื่นมาก็ดูข้อมูลโปรไฟล์ของเรา ผู้ใช้งานคนนั้นจะถูกแฮกทันที โดยในตัวอย่างสามารถยึด Account ได้ทันที จากการใช้ Javascript ขโมยค่า Cookie (กรณีตัวอย่างที่ได้รับการแก้ไขแล้ว)

วิธีการป้องกัน

มี 2 อย่างคือ ทำ validating หรือ encoding อย่างถูกวิธี ขึ้นอยู่กับว่าข้อมูลไปแสดงผลที่ตรงไหน ยกตัวอย่างเช่น ข้อมูลมันแสดงผลใน form input

<input type=”text” value=”<script>alert(1)</script>”>

ในส่วนของ value ถ้าใน php สั่ง echo แบบตรงๆเลยโดยแฮกนะครับ alert(1) ในตัวอย่างจะทำงานทันที เราต้องทำการ encode ก่อนเรียกว่าการทำ HTML Entity Encoding ใน PHP จะใช้ฟังชั่น htmlentities() เครื่องหมาย <>มันถูก encode ทำให้ javascript ไม่สามารถทำงานได้

!! แต่ป้องกันไม่ได้ 100 % ขึ้นอยู่กับกรณีครับ ถ้าเกิดว่าข้อมูลมันไปอยู่ในส่วนของ Javascript จะป้องกันไม่ได้นะครับ เช่นข้อมูลที่ได้อาจจะถูก Javascript นำไปประมวลผลต่อเช่น ทำให้ Hack ไม่ต้องใส่ tag script ก็สามารถ Run คำสั่ง Javascript ได้เลย ยกตัวอย่างเช่น

var name = ‘ ’; // ตัวอย่างvar name = ‘’;alert(1);//‘; // การโจมตี

วิธีการป้องกันในกรณีที่ข้อมูลถูก Javascript นำไปใช้ต่อก็คือ ใช้ฟังชั่นเดิม แต่เติม ENT_QUOTES ตามตัวอย่าง เพื่อ encode ตัว ‘ ด้วย จะได้ bypass ไม่ได้

htmlentities($string, ENT_QUOTES) 

!! แต่เดียวก่อนยังมีอีก ถ้ามันไปแสดงผลอยู่บน link เช่น tag a

<a href="www.google.com" >Click</a> // ตัวอย่าง
<a href="javascript:alert(1)" >Click</a> // การโจมตี

ถ้าเราใส่ javascript:alert(1) ไปแทน ในช่อง href ก็จะเกิด XSS ได้เหมือนกันโดยไม่ต้องพึ่งเครื่องหมาย ‘ และ tag script เลย การป้องกันให้ใช้ pattern การเช็คค่า URL ที่เชื่อถือได้ อย่าเขียน Regular Expression ใช้เองเพราะมันเคยโดน Bypass เนื่องจากมีคนคิดวิธีการโจมตีที่เรียกว่า XSS Polyglot แนะนำว่าให้ใช้ตัว Native ฟังชั่นของภาษานั้นๆ ในการป้องกันช่องโหว่นี้เคยเกิดกับ instagram เมื่อปี 2016 และเว็บดังๆ ของโลกอีกมากมาย ระวังกันไว้ให้ดีนะครับ

สรุป

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

วันนี้ผมขอตัว ไปนอนก่อนเขียนบล็อคนนี้เสร็จตี 3 พอดี เดี๋ยววันหลังจะมาเขียนการโจมตี อีก 2 รูปแบบที่เหลือนะครับ บายยยย

--

--