Sitemap

Allowlist VS Denylist

4 min readMay 21, 2025

สวัสดีทุกท่านที่เข้ามาอ่านบทความนี้นะครับ สำหรับท่านที่เข้ามาอ่านอาจจะสนใจในเรื่องของ Allowlist กับ Denylist ซึ่งหัวข้อในวันนี้อาจจะไม่ได้เกี่ยวข้องกับการโจมตีช่องโหว่ต่างๆ แต่เป็นการเข้าใจสิ่งที่ใช้ในการป้องกันการโจมตีประเภท Input เช่น SQL Injection หรือ Cross-site scripting(XSS) โดยปกติการจะป้องกันการโจมตีรูปแบบ Input ได้ก็จะมีฟังก์ชันต่างๆเข้ามาช่วยเช่น การป้องกัน SQL Injection ด้วย Prepared Statement เป็นต้น สำหรับบทความนี้เราจะมาทำความเข้าใจการป้องกันด้วย Input validation นั่นเองครับ

หัวข้อที่เราจะอธิบายกันในวันนี้ได้แก่

- Input validation คืออะไร?

- Client-side และ Server-side validation คืออะไร?

-ตัวอย่างการใช้งานของ Allowlist และ Denylist

-เราควรเลือกใช้ Input validation แบบไหนในการป้องกัน

Input validation คืออะไร?

มีหลายแหล่งข้อมูลที่อธิบายคำว่า Input validation ซึ่งมีความใกล้เคียงกันโดยจะกล่าวว่าเป็นกระบวนการหนึ่งในการตรวจสอบการรับข้อมูล (input) ว่าเป็นไปตามมาตรฐานที่กำหนดไว้ภายใน Application เพื่อให้แน่ใจว่ามีเฉพาะข้อมูลที่ตรงตามข้อกำหนดของ Application อย่างถูกต้องและเข้าสู่กระบวนการต่อไปภายในระบบ ซึ่งในแต่ละ Application ที่ใช้งานมีความเป็นไปได้ที่จะใช้มาตรฐานที่กำหนดไว้ต่างกัน เช่น บางครั้งอาจจะต้องการค่าที่เป็นตัวเลขเท่านั้น เพื่อให้ข้อมูลถูกต้อง อาจจะใช้เป็น Regular expressions กำหนดให้ค่าที่รับเป็นไปตามที่ระบบต้องการโดย Input Validation แบ่งออกได้เป็น 2 ประเภทนั่นคือ Allowlist validation และ Denylist validation

Client-side และ Server-side validation คืออะไร?

Figure 1.https://en.wikipedia.org/wiki/Client-server_model

หัวข้อนี้อาจมีคนสงสัยว่าเกี่ยวข้องยังไงกับ Allowlist และ Denylist validation เราจะอธิบายให้เข้าใจกันครับจะขออธิบายในฝั่งของ Client-side validation กันก่อนจากนั้นจะอธิบายในส่วนของ Server-side validation ก่อนจะอธิบายกันอยากให้ทุกท่านดูรูปภาพของ Figure 1 จะทำให้เข้าใจว่า Clients ก็คืออุปกรณ์ต่างๆบน Internet ที่เชื่อมต่อไปหา Server จะเป็นการอธิบายแบบย่อเท่านั้น สามารถอ่านเพิ่มเติมได้จาก https://en.wikipedia.org/wiki/Client-server_model ต่อมาขอเริ่มอธิบายในส่วนของ Client-side validation
Client-side validation เป็นการตรวจสอบข้อมูลที่ผู้ใช้งานส่งเข้ามาในหน้าเว็บหรือแอปพลิเคชันของผู้ใช้เองภายในเครื่องคอมพิวเตอร์ หรือ โทรศัพท์มือถือ ก่อนที่จะส่งข้อมูลเข้าสู่ระบบ วิธีนี้เป็นวิธีการที่บังคับให้ผู้ใช้งานกรอกข้อมูลให้ถูกต้องจากหน้าเว็บหรือแอปพลิเคชันเพื่อที่ข้อมูลที่กรอกเข้ามานั้นจะได้ถูกต้อง

Server-side validation เป็นการตรวจสอบที่ฝั่ง Server นั่นคือข้อมูลที่ผู้ใช้กรอกมาจากหน้าเว็บต่างๆจะถูกส่งมาที่ระบบหลังบ้านเพื่อประมวลผลข้อมูลต่างๆ วิธีนี้เป็นวิธีที่ไม่ได้บังคับผู้ใช้งานให้กรอกข้อมูลให้ถูกต้องแต่จะเป็นการตรวจสอบว่าข้อมูลที่ส่งมาให้ถูกต้องหรือไม่และตอบกลับตามความเหมาะสม

เมื่อทุกท่านอ่านดูแล้วอาจเห็นว่าการป้องกันเพียง Client-side validation ก็พอแล้วเพราะถูกบังคับให้ใส่ข้อมูลที่ถูกต้องตั้งแต่แรกจะจริงหรือไม่ จะได้เห็นกันในส่วนของหัวข้อถัดไปครับ

ตัวอย่างการใช้งานของ Allowlist และ Denylist

หัวข้อนี้จะเป็นตัวอย่างต่างๆของ Allowlist และ Denylist ให้ผู้อ่านทุกท่านได้เห็นถึงรูปแบบของ Allowlist และ Denylist นอกจากนี้ยังแสดงให้เห็นว่าการป้องกันกันเพียง Client-side นั้นเพียงพอหรือไม่โดยสถานการณ์ตัวอย่างจะเป็นหน้าเว็บที่ให้กรอกเลขและส่งไปที่ server
***หมายเหตุ ตัวอย่างโค้ด การโจมตี หรือ การป้องกัน เป็นเพียงตัวอย่างที่ผู้เขียนสร้างขึ้นให้เข้าใจ Allowlist และ Denylist อย่างง่ายในกรณีอื่นการใช้งานอาจมีความซับซ้อนกว่านี้ได้***

เรามาเริ่มที่การทำงานของเว็บไซต์นี้กัน

  1. เว็บไซต์นี้จะเป็นเว็บที่ให้เรากรอกข้อมูลตัวเลขดังภาพครับ

ผู้เขียนทำการกรอกข้อมูลพบว่าสามารถใส่ได้แค่ตัวเลขเท่านั้นไม่สามารถใส่ตัวอักษรได้

2.เมื่อเรากรอกตัวเลขแล้วกดปุ่ม “ส่งข้อมูล” จะทำการส่งข้อมูลตัวเลขและแสดงที่หน้าเว็บว่าเรากรอกเลขอะไรเข้ามาดังตัวอย่าง ผู้เขียนกรอกเลข 1 ก็จะมีข้อความแสดงว่า “คุณกรอกเลขตัวเลข: 1”

ต่อมาจะดู source code(โค้ด) ของเว็บข้างต้นครับ

  1. ไฟล์ index.html เป็นหน้าเว็บที่เราจะใช้กรอกข้อมูลจากโค้ดจะเห็นว่ามีการกำหนด input type ให้เป็น number ซึ่งบังคับให้ผู้ใช้งานใส่เพียงตัวเลขเท่านั้นเป็นหนึ่งในการป้องกันที่ฝั่ง Client side validation และ เมื่อกดปุ่ม “ส่งข้อมูล” จะไปประมวลผลต่อที่ไฟล์ “process.php”

2.ไฟล์ “process.php” เป็นไฟล์ที่จะรับค่าต่างๆมาจากไฟล์ “index.html” และแสดงข้อความ “คุณกรอกตัวเลข: ” ตามด้วยค่าที่ใส่มาจากหน้า “index.html”

ผู้อ่านทุกท่านจะได้เห็นกระบวนการทำงานของระบบและโค้ดแล้วต่อไปเราจะลองโจมตีกันจากหน้าเว็บเดิมเราจะทำการเปิดเครื่องมือ inspect ของ browser ทำการดูโค้ดของหน้าเว็บจะเห็น “input type=“number” ” เหมือนโค้ดที่ให้ดูไปข้างต้นจากนั้นทำการเปลี่ยนจาก “number” เป็น “text” กัน

เมื่อทำการแก้ไขแล้วพบว่าสามารถพิมพ์ข้อความอะไรก็ได้แล้วในกล่องข้อความ ผู้เขียนจึงลองใส่คำว่า “test” จากนั้นทำการกดที่ปุ่ม “ส่งข้อมูล”

พบว่าสามารถส่งได้และแสดงคำว่า “test” ขึ้นมาแทนตัวเลขซึ่งผิดวัตถุประสงค์ของระบบที่ใช้เป็นตัวอย่าง

ที่นี้เราลองเปลี่ยนจาก “test” เป็น “<script>alert(“Hacked”)</script>” และ “กดส่งข้อมูล”

พบว่ามีกล่องข้อความแสดงคำว่า “Hacked” ขึ้นมาที่หน้าจอสิ่งนี้เรียกว่า “Reflected cross-site scripting (Reflected XSS)” ต่อไปนี้จะขอเรียกย่อๆว่า XSS จากหัวข้อก่อนหน้าที่ได้ทิ้งคำถามเอาไว้ว่า “การป้องกันเพียง Client-side validation ก็พอแล้ว” จะเห็นได้อย่างชัดเจนจากขั้นตอนนี้ว่าการป้องกันจาก Client-side validation ไม่เพียงพอที่จะป้องกันระบบให้ปลอดภัย

เมื่อเกิดการโจมตีขึ้นดังนั้นการป้องกันก็ควรจะป้องกันที่ Server side เพื่อให้ระบบยังคงปลอดภัยอยู่นั่นเองโดยเราจะแยกให้ดูว่าการป้องกันด้วย Allowlist และ Denylist ต่างกันอย่างไร เราจะมาดู source code ของ “process.php” ในส่วนของการป้องแบบ Denylist กันก่อน

ในส่วนของโค้ดที่เพิ่มมานั้นจะมีตัวแปรเก็บค่าของ Tag ต่างๆเอาไว้จำนวน 4 แบบ และมีการเพิ่ม foreach ลูปสำหรับกรองคำที่ตรงกับ Tag ที่อยู่ในตัวแปร

เมื่อเราลองโจมตีด้วยช่องโหว่ XSS กันอีกครั้งหนึ่งด้วยคำสั่งเดิมผลลัพธ์จะเป็นคำว่า “alert(“Hacked”)” แทนจะเห็นได้ว่าต่อให้เราใส่ Tag <script> เข้าไปก็ยังไม่ถูกโจมตี

ต่อมาผู้เขียนลองเปลี่ยนจาก “<script>alert(“Hacked”)</script>” เป็น “<Script>alert(“Hacked”)</Script>” ผลลัพธ์คือ เกิดกล่องข้อความแสดงคำว่า “Hacked” อีกแล้ว!!! ที่เกิดแบบนี้ขึ้นเพราะการที่เราแก้ไขจาก <script> เป็น <Script> นั้นไม่ตรงกับ Tag ที่เราทำการกำหนดไว้ ทำให้เห็นว่าการใช้งาน Denylist นั้นจำเป็นที่จะต้องเตรียมคำที่เราจะกำจัดทิ้งไว้มากและต้องครบทุกแบบเพื่อป้องกันได้ 100%

ต่อไปจะเป็นตัวอย่างของการใช้งานในส่วนของ Allowlist ก่อนอื่นเรามาดูกันที่โค้ดกันก่อน

จากโค้ดจะเห็นได้ว่ามีการกำหนด Type ของค่าที่รับมาเป็นค่า Integer(int) ซึ่งค่า int คือค่าของตัวเลขนั่นเอง

ผู้เขียนกรอกข้อมูลด้วยคำสั่งแรก “<script>alert(“Hacked”)</script>” ผลลัพธ์คือได้เลข “0” ออกมา

จากนั้นผู้เขียนกรอกข้อมูลด้วยคำสั่งที่ 2 “<Script>alert(“Hacked”)</Script>” ผลลัพธ์คือได้เลข “0” เช่นเดียวกัน

  • **ไม่ใช่รูปเดียวกัน***

ทำไม่ถึงเป็นแบบนั้น เนื่องจากเราใส่ข้อมูลเข้าไปเป็นคำสั่ง “<Script>alert(“Hacked”)</Script>” เมื่อระบบหลังบ้านรับข้อมูลนี้มาแล้วทำให้ถูกเปลี่ยนค่าจาก String เป็น Integer ซึ่งจะถูกแก้ไขค่าให้เป็น 0 นั่นเองสามารถทดสอบได้จากเว็บ https://www.w3schools.com/php/php_casting.asp

จากขั้นตอนต่างๆที่ได้มาจะเริ่มเห็นความแตกต่างของ Denylist และ Allowlist กันแล้วในหัวข้อถัดไปเราจะไปดูกันในส่วนของการเลือกใช้ว่าเราควรจะเลือกใช้แบบไหนเพราะอะไร

*เพิ่มเติมการป้องกันด้วยวิธีต่างๆสามารถใช้ regular expression ช่วยในการกรองข้อมูลได้ แต่ต้องระวังช่องโหว่ ReDos ซึ่งสามารถตรวจสอบได้จากเว็บ https://devina.io/redos-checker

เราควรเลือกใช้ Input validation แบบไหนในการป้องกัน

จากหัวข้อก่อนหน้าจะเห็นว่าผู้เขียนยังคงสามารถหลีกเลี่ยงการป้องกันแบบ Denylist ได้ด้วยการเปลี่ยนพิมพ์เล็กพิมพ์ใหญ่โดยนอกจากวิธีนี้ยังมีอีกหลายวิธีในการหลีกเลี่ยงในส่วนของ Denylist แต่ในทางกลับกันการใช้งาน Allowlist โดยการเปลี่ยนแปลงค่าทั้งหมดเป็นตัวเลขที่ฝั่ง Server ทำให้ไม่ว่าจะใส่ข้อมูลอะไรเข้ามาจะกลายเป็นเลข 0 นั่นทำให้เป็นไปได้ยากที่จะโจมตีระบบ โดยปกติแล้วผู้เขียนแนะนำให้ใช้การป้องกันด้วย Allowlist ตามที่เห็นได้ในตัวอย่าง นอกจากตัวอย่างแล้วผู้เขียนใช้ข้อมูลจากเว็บไซต์ของ OWASP บอกเอาไว้ว่า “การใช้งาน Denylist เป็นข้อผิดพลาดพื้นฐานในการตรวจสอบข้อมูลที่ส่งเข้ามา เช่น <script> เนื่องจากผู้โจมตียังสามารถหลีกเลี่ยงการกรองข้อมูลเหล่านี้ได้ ถึงการใช้ Denylist จะมีประโยชน์ในการเป็นวิธีการเพิ่มเติมในการตรวจจับข้อมูล แต่ไม่ควรเป็นวิธีหลัก การใช้งาน Allowlist เป็นการที่ปลอดภัยกว่าในการป้องกันข้อมูล” จะเห็นได้ว่าเว็บไซต์หลักอย่าง OWASP ก็มีการบอกถึงการใช้งานของ Allowlist และ Denylist เอาไว้เช่นกันซึ่งตรงกับตัวอย่างที่ผู้เขียนได้ยกตัวอย่างให้เห็นด้วยเช่นกัน

References:

https://OWASP-top-10-proactive-controls-2018.readthedocs.io/en/latest/c5-validate-all-inputs.html?utm_source=chatgpt.com

https://www.nccgroup.com/media/ymqf1kwk/_ncc-group-whitepaper_the-disadvantages-of-a-blacklist-based-approach-to-input-validation.pdf?utm_source=chatgpt.com

https://www.acunetix.com/websitesecurity/sql-injection/

https://bolster.ai/glossary/allowlist

https://cheatsheetseries.OWASP.org/cheatsheets/Input_Validation_Cheat_Sheet.html#implementing-input-validation

https://www.sciencedirect.com/topics/computer-science/input-validation#:~:text=Input%20validation%20is%20the%20process%20of%20testing%20input%20received%20by,standard%20defined%20within%20the%20application.

https://devina.io/redos-checker

https://surveyjs.io/stay-updated/blog/client-server-data-validation

https://en.wikipedia.org/wiki/Client%E2%80%93server_model

--

--

No responses yet