ความบาปเมื่อใช้ Textarea ของ Razor กับ vue js รวมกัน

สวัสดีครับ
วันนี้ผมมีเรื่องมาเล่าสู่กันฟัง
คือ
ช่วงนี้โปรเจคผมโดน Penetration Test หนักหน่วงมากครับ
และหนึ่งในหัวข้อที่ผมเจอคือ Cross-site Scripting (XSS)


ซึ่งทางเอกสารที่เขาส่งมาให้ผม ก็บอกถึงจุดโหว่แต่ละจุดครับ ว่าเกิดขึ้นได้อย่างไรบ้าง
และ ผมก็จะยกตัวอย่าง 1 ข้อที่ผมพอเจอมา

นั้นก็คือการใช้ @Html.TextAreaFor เป็น Syntax ของ Razor Template
ควบคู่ไปกับการกำหนด attribute ของ vue.js

ถ้ามองไม่ออกให้ดูตามภาพครับ










** 
ถามว่าทำไมถึงทำแบบนี้ ก็ต้องบอกตามตรงว่า ไม่ควรทำครับ 
แต่ตอนนั้น ผมต้องการจะใช้ คุณสมบัตรของตัว data annotation ของ MVC ในการ Validate ค่าครับ
        เพราะ ไม่อยากเขียน validate แยกอีกรอบ เพราะ model นี้ต้องใช้หลายโปรเจคครับ  เลยทำให้ออกเป็นท่านี้

**

จาก code
คือ ผมต้องการแสดงค่าจาก model.Interview.Note ออกมาครับ
โดยใช้ @Html.TextAreaFor เป็น Syntax ของ Razor Template นั้นเองครับ
แล้วข้างใน tag นี้ ผมก็ใส่ attribute ในส่วนของ vue.js เข้าไป
ซึง มันก็ work นะครับ ทำงานได้โอเครเลยแหละ


Attack
แต่เมื่อเขาลองใส่ script เข้ามาตามภาพ และ กด Save Form (หน้านี้เป็น ฟอร์มเก็บข้อมูลครับ)
ก็ทำให้ตัว script ที่เขาใส่เข้ามา นั้นเก็บไว้ใน database








และ เมื่อ เรากด F5 กลับมาหน้านี้อีกครั้ง มันก็ขึ้น alert ตามภาพนี้ครับ เรียกว่า alert ไม่พักกันเลยทีเดียว




สาเหตุ
แล้วเหตุใดละทำให้มัน alert แบบนี้
ก็เป็นเพราะว่า ตัว @Html.TextAreaFor นั้น เมื่อมีข้อความ 
มันจะเอาข้อความเข้าไปไว้ใน <textarea></textarea> ของตัวมันเองครับ 
แล้วค่อยแสดงผลในกรอบสี่เหลี่ยม

ภาพตัวอย่าง Code HTML ครับ

จากรูปนะครับ ก็จะเห็น script ที่เราเขียนเข้าไป มันแสดงออกมาเป็น code
และ เมื่อตัว vue js อ่านมาเห็น tag นี้
มันก็เอาไป render เพราะว่า script อยู่ใน tag {{ }} นั้นเอง



วิธีแก้
วิธีแก้ก็ง่ายมาก (จริงๆ เรียกว่าเป็นวิธีที่ควรทำตั้งแต่แรกมากกว่าครับ)
ก็คือใช้ html tag + vue js attribute ของมันให้ถูกต้องครับ

ภาพตัวอย่าง


เพียงแค่นี้ ตัว vue.js ก็จะจัดการกับ data ที่อยู่ข้างในของเราให้หมดแล้วครับ
และ ไม่ต้องกลัวจะโดน XSS ต่อเลยนะครับ เพราะ มัน ป้องกันให้เราแล้วครับ

และนี้ก็คือภาพตัวอย่าง ถ้าใช้ tag vue.js ครับ มันจะไม่เอา script นั้นมา render อีกรอบแน่นอน











สิ่งที่ได้เรียนรู้จากเรื่องนี้
- เลือกเอาสักอย่าง จะใช้เครื่องมือของอะไร ไม่ใช่ผสมกันแบบนี้
- แต่ละเครื่องมือ ก็มีวิธีแก้แตกต่างกันไป ถ้าทำข้อข้างบนได้แล้ว วิธีนี้ก็จะหาง่ายไปตาม
- Html.TextArea จะ พ้นข้อความไว้ใน Tag <textarea>   ต้องคำนึงถึงเรื่อง XSS ด้วยเสมอ
- ถ้าใส่ v-pre ใน <textarea> ตัว vue.js จะไม่เอาข้อมูลกลับไปใส่ใน model
- v-model  จัดการเรื่อง xss ให้เราได้ในระดับนึง ถ้าเขียนถูกต้องอะนะ



หลังจากเหตุการณ์นี้เกิดขึ้น ผมก็ไปไล่แก้กรรมเก่า ทั้งหมด ให้เป็น Syntax ของ vue.js ทั้งหมดแล้วครับ


** 
ซึ่งทั้งหมดนี้ ก็ต้องยอมรับเลยว่า ที่เขียนไปแบบนี้ ก็ด้วยความไม่รู้ครับ
อีกอย่าง ยังไม่เคยเจอ pen test แบบนี้ด้วย โปรเจคนี้ถือเป็นโปรเจคแรกเลย
เลยอยากจะมาเล่าเก็บไว้ เผื่อว่าตัวเองจะกลับมาอ่านต่อ
ยังไงก็ขอบคุณที่เข้ามาอ่านครับ
** 








ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

SetUp Theme Monokai On Visual Studio

"zsh: command not found: docker"

คู่มือ Install IIS On Windows Server 2016