เขียนโค้ดให้ปลอดภัยตาม OWASP ASVS

24 กันยายน 2025

พิชญะ โมริโมโต
พิชญะ โมริโมโตหัวหน้าทีมทดสอบเจาะแฮกระบบ (lead penetration tester) ของบริษัท สยามถนัดแฮก, เป็นที่ปรึกษาด้านความปลอดภัยให้หน่วยงานเอกชน, เป็นที่รู้จักกันในฐานะ หนึ่งในแอดมินกลุ่ม 2600 Thailand และเป็นหนึ่งในคนเขียนบทความลงเพจ สอนแฮกเว็บแบบแมว ๆ

OWASP ASVS คืออะไร (และต่างจาก Top 10 ยังไง)

ASVS (Application Security Verification Standard) คือชุด “ข้อกำหนดเพื่อความปลอดภัยของแอปพลิเคชัน” พร้อมวิธีตรวจยืนยัน (Verification) ที่จัดหมวดหมู่ชัดเจน วัดผลได้ โดยจะนำมาใช้ในการอ้างอิงในการทำสิ่งเหล่านี้

  • การออกแบบและพัฒนาระบบ
  • การทดสอบระบบ
  • การสัญญาจัดซื้อ หรือเป็นมาตรฐานรับมอบงาน

จุดเด่นของ OWASP ASVS 5.0 (May 2025) รุ่นล่าสุด ณ วันที่เขียนบทความนี้ คือปรับโครงสร้างใหม่ เน้นผลลัพธ์ด้านความปลอดภัย (Security Goal) มากกว่าบังคับเทคนิคตายตัว และเพิ่มบทหมวดใหม่ ๆ เช่น OAuth/OIDC และ WebRTC รวม ๆ มีประมาณ 349 ข้อกำหนดใน 17 บท ชัดเจนกว่าเดิมเยอะครับ

URL: https://github.com/OWASP/ASVS/blob/v5.0.0/README.md

OWASP Application Security Verification Standard (ASVS) คือมาตรฐานการตรวจสอบความปลอดภัยของแอปพลิเคชันที่พัฒนาโดย Open Web Application Security Project (OWASP) โดยมีเป้าหมายเพื่อเป็นแนวทางที่ครอบคลุมและละเอียดในการประเมินและปรับปรุงมาตรการรักษาความปลอดภัยของแอปพลิเคชัน มาตรฐานนี้ช่วยให้ผู้พัฒนาและผู้ทดสอบด้านความปลอดภัย สามารถใช้เพื่อกำหนด สร้าง ทดสอบ และยืนยันความปลอดภัยของแอปพลิเคชันได้

ต่างจาก OWASP Top 10 ยังไง?

  • OWASP Top 10 = เอกสารสร้างการรับรู้ “ช่องโหว่พบบ่อย” เพื่อให้เห็นภาพรวมความเสี่ยง (มีแค่ 10 ข้อ)
  • OWASP ASVS = มาตรฐาน “ลงมือทำและตรวจรับ” ใช้วาง Requirement อย่างละเอียด (มีกว่า 350 ข้อ), ทำ Checklist, ตั้งเกณฑ์สอบผ่าน/ไม่ผ่าน

ระดับการตรวจ (Level) – เลือกให้เหมาะกับงาน

  • L1 (Minimum/Opportunistic): ระดับความปลอดภัย “ขั้นต่ำ” ที่ทุกระบบควรจะมี ครอบคลุม ~20% ของข้อกำหนด ASVS ตั้งใจทำให้เข้าถึงง่ายที่สุด ลดอุปสรรคในการเริ่มต้นนำไปใช้งานจริง เน้นตรวจสอบมาตรการป้องกันช่องโหว่พื้นฐานที่พบเจอได้ในแอปพลิเคชันทั่วไป อย่างเช่น SQL Injection และ OS Command Injection
  • L2 (Standard): ระดับความปลอดภัยพื้นฐานที่แอปพลิเคชันส่วนใหญ่ควรจะมี เมื่อรวม L1+L2 จะครอบคลุม ~70% ของข้อกำหนด ประกอบด้วยการตรวจสอบมาตรการป้องกันช่องโหว่ที่มีความซับซ้อนมากขึ้น และช่องโหว่ที่พบได้ยากกว่าหรือมีเงื่อนไขการโจมตีที่เยอะกว่าใน L1 เช่น LDAP Injection และ XPath Injection
  • L3 (Advanced): ระดับความปลอดภัยสูงสุด สำหรับระบบมูลค่าสูงหรือระบบที่มีผลกระทบสูง ถ้าถูกแฮก โดยจะเพิ่มข้อกำหนดที่เน้น Defense‑in‑Depth ในส่วนที่เหลือ ~30% ของ ASVS

สรุป: ถ้าเพิ่งเริ่มต้นเริ่มที่ L1 (20%) ให้ผ่านก่อน แล้วค่อยยกระดับเป็น L2 (70%) และ L3 (100%) ตามความเสี่ยงและบริบทธุรกิจและระบบที่นำไปปรับใช้

OWASP จะมีการปรับปรุงและพัฒนา OWASP ASVS อย่างต่อเนื่อง ซึ่งในปี 2025 นี้ OWASP ได้มีการเผยแพร่ OWASP ASVS รุ่น 5.0 ซึ่งมีความแตกต่างจากรุ่นก่อนหน้าที่ควรรู้ฉบับ 1 นาทีคือ

  • จัดเรียงกลุ่มใหม่ โดยเน้นไปที่จุดมุ่งหมายของฟังก์ชัน แทนที่จะเป็นกลไกการทำงานของฟังก์ชัน
  • ปรับลดมาตรการใน Level 1 ของรุ่น 5.0 ให้น้อยลง เหลือเพียง 20% (จากเดิมรุ่น 4.0.3 ที่ครอบคลุม เกือบ 50%) ของ OWASP ASVS เพื่อให้สามารถเข้าถึงได้ง่ายขึ้น
  • เพิ่มเนื้อหาใหม่ คือ OAuth and OIDC และ WebRTC

ยกตัวอย่าง หมวดหมู่การควบคุม ย่อย 3 บท ที่ใช้ได้ทันที

จะขอยกตัวอย่าง หมวดหมู่การควบคุม มาอธิบายโดยย่อเพื่อให้ทุกคนเห็นภาพมากขึ้นว่าลักษณะข้อกำหนดของ ASVS เป็นอย่างไรครับ (V1 Encoding and Sanitization, V13 Configuration , V15 Secure Coding and Architecture)

V1 Encoding and Sanitization

ในหมวดหมู่นี้ จะเกี่ยวข้องกับการประมวลผลข้อมูลอันตรายที่ได้รับจากฝั่งผู้ใช้งาน ปัญหาจะเกิดขึ้นเมื่อข้อมูลดังกล่าวถูกนำไปตีความตามกฎของ Interpreter อย่างมีความเสี่ยง ทำให้เกิดช่องโหว่ให้ผู้ไม่ประสงค์ดีสามารถเข้าถึงหรือแก้ไขข้อมูลในส่วนที่ไม่ควรทำได้ ซึ่งเป็นหนึ่งในวิธีการโจมตีที่พบได้ทั่วไปบนแอปพลิเคชันต่าง ๆ

เป้าหมาย: ระเบิดข้อมูลที่รับมาอย่างอันตรายทิ้งก่อนมันจะกลายเป็นภัยคุกคามในแอปพลิเคชัน

 

ตัวอย่างการระบุ Level กับแต่ละข้อกำหนด

ตัวอย่างหมวดหมู่ย่อย

V1.2 Injection Prevention

Level 1 ขั้นต่ำ ที่ต้องทำคือ

  • ตรวจสอบว่าแอปพลิเคชันมีการ Encode ข้อมูลก่อนที่จะนำมาแสดง
  • ตรวจสอบว่าในการสร้าง URL แบบ Dynamic ของแอปพลิเคชัน มีการ Encode ข้อมูลที่ไม่น่าเชื่อถืออย่างเหมาะสม และไม่ใช้งาน URL Protocol ที่อันตราย เช่น javascript: และ data:
  • ตรวจสอบว่ามีการทำ Encode หรือ Escape ข้อมูลที่จะนำไปสร้างเป็น JavaScript
  • ตรวจสอบว่ามีการป้องกัน SQL/NoSQL Injection และ OS Command Injection ด้วยเทคนิค Parameterized Query และอื่น ๆ

และ Level 2 ความปลอดภัยพื้นฐานที่ควรมีเพิ่มเติม ได้แก่

  • ตรวจสอบว่าแอปพลิเคชันมีมาตรการป้องกัน LDAP Injection และ XPath Injection
  • ตรวจสอบว่า LaTeX Processor มีการตั้งค่าอย่างปลอดภัย เช่น ไม่ใช้งาน Flag -shell‑escape และมีการตั้ง Allowlist คำสั่งที่ใช้งานได้

และสุดท้าย Level 3 สำหรับแอปพลิเคชัน ที่ต้องการความปลอดภัยระดับสูง

  • ตรวจสอบว่าแอปพลิเคชันมีการป้องกัน CSV/Formula Injection

V1.5 Safe Deserialization

Level 1 ขั้นต่ำ ที่ต้องทำคือ

  • ตรวจสอบว่า XML Parser ของแอปพลิเคชันมีการตั้งค่าอย่างรัดกุม และปิดการใช้ฟีเจอร์ที่มีความเสี่ยง เพื่อป้องกันการการโจมตีด้วย XML eXternal Entity (XXE)

และ Level 2 ความปลอดภัยพื้นฐานที่ควรมีเพิ่มเติม ได้แก่

  • ตรวจสอบว่าแอฟพลิเคชันมีการทำ Deserialize ข้อมูลที่ไม่น่าเชื่อถืออย่างปลอดภัย โดยการจำกัด Type ของข้อมูลที่สามารถกำหนดได้ เพื่อให้ไม่สามารถเรียกใช้งาน Type ที่ไม่ปลอดภัย

และสุดท้าย Level 3 สำหรับแอปพลิเคชัน ที่ต้องการความปลอดภัยระดับสูง

  • ตรวจสอบว่า Parser ในแอปพลิเคชันทุกชนิดมีพฤติกรรมการประมวลผลค่าที่ตรงกัน เพื่อให้ไม่เกิดการโจมตีที่ใช้ประโยชน์จากส่วนนี้

V13 Configuration

แอปพลิเคชันบนอินเตอร์เน็ตควรมีการตั้งค่าอย่างปลอดภัยเสมอ ซึ่งหมวดหมู่นี้จะเน้นไปที่การตั้งค่าหลากหลายรูปแบบในทุกขั้นตอน ตั้งแต่เริ่มพัฒนาจนถึงการติดตั้งระบบ เพื่อให้หลีกเลี่ยงการรั่วไหลของข้อมูล และเปิดช่องโหว่ไปสู่การโจมตีอื่น ๆ ได้

ตัวอย่างหมวดหมู่ย่อย

V13.3 Secret Management

ในหมวดหมู่ย่อยนี้จะไม่มีข้อกำหนด Level 1 แต่จะเริ่มต้นที่ Level 2 เลยได้แก่

  • ตรวจสอบว่าแอปพลิเคชันมีการใช้งานเทคโนโลยีในการเก็บข้อมูลอันเป็นความลับอบ่างเหมาะสม เช่น Key Vault และไม่ฝังไว้ใน Source Code และ Build Artifact (ถ้าเป็น L3 จะต้องยกระดับเทคโนโลยีที่ใช้เก็บความลับเป็นระดับฮาร์ดแวร์)
  • ตรวจสอบว่าข้อมูลที่เป็นความลับ มีการกำหนดสิทธิการเข้าถึงอย่างรัดกุมตามหลักการ Least Privilege

และ Level 3 สำหรับแอปพลิเคชัน ที่ต้องการความปลอดภัยระดับสูง

  • ตรวจสอบว่ากระบวนการที่เกี่ยวข้องกับการเข้ารหัสใด ๆ จะต้องกระทำบน Isolated Security Module เพื่อให้ข้อมูลที่เกี่ยวข้องกับการเข้ารหัสไม่รั่วไหลออกไปสู่ส่วนอื่นที่ไม่ปลอดภัย
  • ตรวจสอบว่ากุญแจการเข้ารหัสต่าง ๆ มีวันหมดอายุ และผลัดเปลี่ยนตามเอกสารของแอปพลิเคชัน

V15 Secure Coding and Architecture

บทนี้จะเน้นไปที่การเขียนโค้ดอย่างปลอดภัย โดยคำนึงถึงวิธีการพัฒนาแอปพลิเคชัน การออกแบบโค้ด การออกแบบสถาปัตยกรรมของแอปพลิเคชัน

เป้าหมาย: โค้ดอ่านง่าย ตรวจง่าย ปลอดภัยจริง

ตัวอย่างหมวดหมู่ย่อย

V15.1 Secure Coding and Architecture Documentation

Level 1 ขั้นต่ำ ที่ต้องทำคือ

  • ตรวจสอบว่ามีการกำหนดระยะเวลาในการแก้ไขช่องโหว่ตามระดับความเสี่ยงเมื่อพบ third-party component ที่มีช่องโหว่ และระยะเวลาโดยทั่วไปในการอัปเดต library ที่ใช้งานอยู่

และ Level 2 ความปลอดภัยพื้นฐานที่ควรมีเพิ่มเติม ได้แก่

  • ตรวจสอบว่าใน Inventory Catalog มีการติดตามสถานะและบำรุงรักษา third-party library ที่มีการใช้งานอยู่ รวมถึงตรวจสอบว่ามาจาก library เหล่านั้นมาจากแหล่งที่น่าเชื่อถือหรือไม่
  • ตรวจสอบว่าเอกสารกำกับแอปพลิเคชันมีการระบุว่าฟังก์ชันไหนใช้เวลาหรือทรัพยากรในการประมวลผลสูงเป็นพิเศษ เพื่อป้องกันผลกระทบกับระบบเมื่อมีการใช้งานฟังก์ชันเหล่านี้มากเกินไป

และ Level 3 สำหรับแอปพลิเคชัน ที่ต้องการความปลอดภัยระดับสูง

  • ตรวจสอบว่ามีการไฮไลต์ในเอกสารกำกับแอปพลิเคชันว่า third-party library ไหนเป็น library ที่มีความเสี่ยงสูง
  • ตรวจสอบว่ามีการไฮไลต์ในเอกสารกำกับแอปพลิเคชันว่า ส่วนไหนของแอปพลิเคชันมีความอันตรายต่อระบบสูง

 

จากที่ยกตัวอย่างมา จะสังเกตได้ว่าแต่ละหมวดหมู่จะมีการกำหนดหัวข้อการตรวจสอบชัดเจนและวัดผลได้ รวมถึงครอบคลุมพฤติกรรมที่อาจจะทำให้เกิดช่องโหว่ได้ในวงกว้าง ทำให้เราสามารถนำ OWASP ASVS ไปใช้งานเป็นเกณฑ์การประเมินโดยตรง

เอาไปทำเป็น Checklist ประจำทีม ได้ทันที

สามารถดาวน์โหลดเอกสาร OWASP ASVS ฉบับเต็มได้ที่ URL ด้านล่างนี้
https://github.com/OWASP/ASVS/releases

ในบทความนี้ เราจะมาลองใช้งาน OWASP ASVS ในการตรวจสอบจริงกัน แต่ก่อนหน้านั้น เราจำเป็นที่จะต้องเล่าถึงแอปพลิเคชันที่เราจะนำมาสาธิตก่อน นั่นก็คือ OWASP Juice Shop นั่นเอง

หากอยาก เห็นภาพ ว่าข้อกำหนด ASVS ใช้ตรวจอะไรบ้าง มาลองกับ OWASP Juice Shop เว็บแอปพลิเคชันขายน้ำผลไม้ที่ จงใจออกแบบมาให้มีช่องโหว่ สำหรับศึกษาความปลอดภัยแอปพลิเคชันกันได้

เริ่มต้นแบบเร็วสุดในการสร้าง Web Juice Shop ทดลอง ด้วย Docker คำสั่งต่อไปนี้

$ docker pull bkimminich/juice-shop
$ docker run –rm -p 127.0.0.1:3000:3000 bkimminich/juice-shop

จากนั้น เราสามารถไปที่ http://localhost:3000 เพื่อเข้าถึงเว็บแอปพลิเคชันได้เลยครับ

 

ผู้พัฒนา OWASP Juice Shop จงใจเขียนโค้ดให้มีช่องโหว่และทำเป็น แบบทดสอบ (Challenge) ให้ลองโจมตี ซึ่งแต่ละช่องโหว่ก็จะมีความยากง่ายในการโจมตีแตกต่างกันไปตามจำนวนดาวที่ผู้พัฒนาระบุไว้

หลังจากนี้ เราจะลองทำ Threat Modeling และทำ Secure Coding Checklist เพื่อจะลองนำไปรีวิวโค้ดของแอปพลิเคชัน OWASP Juice Shop กันครับ

 

ทำ Threat Modeling (STRIDE) ฟังก์ชัน “สมัครสมาชิก” ของ Juice Shop

Threat Modeling คือกระบวนการที่มุ่งเน้นการระบุ สื่อสาร และทำความเข้าใจภัยคุกคาม รวมถึงมาตรการลดความเสี่ยง เพื่อออกแบบแอปพลิเคชันที่ปลอดภัย

หากต้องการศึกษาเพิ่มเติมว่าจะสามารถทำ Threat Modeling ด้วยวิธีไหนได้บ้าง ทาง NT cCyfence ขอแนะนำให้ลองเข้าไปอ่านบทความด้านล่างนี้ครับ (โฆษณา)

URL: https://www.cyfence.com/article/12-way-to-build-threat-modeling/

สำหรับบทความนี้ เราจะลองใช้ STRIDE ซึ่งเป็นหนึ่งใน Framework สำหรับทำ Threat Modeling ที่ได้รับความนิยมมากที่สุด เพื่อทำ Threat Modeling แบบง่าย ๆ ของฟังก์ชันการสมัครบัญชีผู้ใช้งานของ OWASP Juice Shop

  • Spoofing (ปลอมตัวตน)
    แอบอ้างเป็นผู้ใช้หรือระบบอื่น เช่น ปลอม IP หรือ Credential เพื่อหลอกระบบ
  • Tampering (แก้ไขข้อมูล)
    เปลี่ยนแปลงข้อมูลโดยไม่ได้รับอนุญาต เช่น แก้ไฟล์ระบบหรือพารามิเตอร์
  • Repudiation (ปฏิเสธความรับผิด)
    ผู้ใช้ปฏิเสธการกระทำในระบบ เพราะไม่มีหลักฐานหรือ log ที่เชื่อถือได้
  • Information Disclosure (ข้อมูลรั่วไหล)
    ข้อมูลสำคัญถูกเข้าถึงหรือเปิดเผยต่อบุคคลที่ไม่ได้รับอนุญาต
  • Denial of Service (ขัดขวางบริการ)
    ทำให้ระบบหรือแอปใช้งานไม่ได้ เช่น ส่ง request จำนวนมากจนระบบล่ม
  • Elevation of Privilege (ยกระดับสิทธิ์)
    ผู้โจมตีเพิ่มสิทธิ์ตัวเองจากผู้ใช้ทั่วไปเป็นผู้ดูแลระบบ

ฟังก์ชันนี้ต้องการข้อมูล (Input) จากผู้ใช้งานต่อไปนี้

  • อีเมลของบัญชีผู้ใช้งาน
  • รหัสผ่าน (5 – 40 ตัวอักษร)
  • เลือก Security Question และกำหนดคำตอบ เพื่อใช้ตั้งรหัสผ่านใหม่ในอนาคต

สำหรับฟังก์ชันลักษณะนี้ จะสามารถทำ Threat Modeling ตาม STRIDE Framework เพื่อเรียบเรียงความเสี่ยง ได้คร่าว ๆ ดังนี้

  • Spoofing (-S-TRIDE)
    – ผู้โจมตีสมัครบัญชีผู้ใช้งานแล้วกลายเป็นบัญชีผู้ใช้งานอื่นในระบบได้
  • Tampering (S-T-RIDE)
    – ผู้โจมตีทำให้เซิฟเวอร์สั่งใช้งานคำสั่ง SQL ที่ต้องการได้ (SQL Injection)
    – ผู้โจมตีทำให้เซิฟเวอร์สั่งใช้งานคำสั่ง OS ที่ต้องการได้ (OS Command Injection)
    – ผู้โจมตีสามารถตั้งรหัสผ่านที่ไม่ปลอดภัยได้
  • Repudiation (ST-R-IDE)
    – ผู้โจมตีสามารถเปลี่ยน IP Address ที่จะถูกจัดเก็บบน Log ได้โดยอิสระ ในกรณีที่มีการเก็บ Log
  • Information disclosure (STR-I-DE)
    – ผู้โจมตีทำให้เซิฟเวอร์เปิดเผยข้อมูลเกี่ยวกับซอฟต์แวร์หรือฐานข้อมูลที่แอปพลิเคชันใช้งานอยู่
    – ผู้โจมตีทำให้เซิฟเวอร์เปิดเผยข้อมูลส่วนตัวของผู้ใช้งานอื่น ๆ ได้
  • Denial of service (STRI-D-E)
    – ผู้โจมตีสามารถเรียก API ซ้ำ ๆ จนเซิร์ฟเวอร์ทำงานหนักและล่ม
  • Elevation of privilege (STRID-E-)
    – ผู้โจมตีสามารถสมัครบัญชีผู้ใช้งานเป็นสิทธิผู้ดูแลระบบได้ โดยไม่ได้รับอนุญาต

เท่านี้ เราก็พอจะเห็นภาพได้คร่าว ๆ แล้ว ว่าฟังก์ชันนี้มีความเสี่ยงที่จะถูกโจมตีลักษณะไหนได้บ้าง แต่ทั้งนี้ เราอาจจะเพิ่มความละเอียดเข้าไปได้อีก เช่นการใช้ Threat Model Framework อื่น ๆ มาประกอบกัน หรือการเพิ่มระดับความเสี่ยงเพื่อจัดลำดับความสำคัญในการตรวจสอบในระยะเวลาที่จำกัดและกำหนดระยะเวลาในการแก้ไข เป็นต้น

เทคนิคหนึ่งที่นิยมสำหรับการทำ Threat Model ก็คือการทำ Data Flow Diagram กำหนด Trust Boundary แล้วไล่ STRIDE ทีละจุด จะได้รายชื่อ รายการของภัยคุกคาม ที่ตรงประเด็นที่สุด

ทำ Secure Coding Checklist สำหรับฟีเจอร์สมัครสมาชิก

ไม่ว่าจะในฐานะ Developer หรือ Tester หากต้องการตรวจสอบว่าโค้ดที่เขียนขึ้นมามีความปลอดภัยแค่ไหน มีความเสี่ยงที่จะถูกโจมตีตาม Threat Model ที่คิดไว้ขนาดไหน การตรวจสอบโดยไม่มี Framework ใด ๆ รองรับอาจจะทำให้มีการตรวจสอบที่ตกหล่นไปได้ ดังนั้น เราจึงควรทำ Checklist บางอย่าง เพื่อให้การเขียนโค้ดหรือการตรวจสอบโค้ดมีผลลัพธ์ที่ถูกต้องแม่นยำและสม่ำเสมอ หรือก็คือ Secure Coding Checklist ครับ

ซึ่ง Checklist นี้ เราสามารถสร้างได้หลายแบบ อาจจะอ้างอิงจาก Checklist ที่มีอยู่แล้วอย่างเช่น OWASP Secure Coding Checklist หรือจะพัฒนาต่อจาก Framework อื่น ๆ ที่เกี่ยวข้องก็ได้ ซึ่งหนึ่งในนั้นคือ ASVS ครับ

เพื่อให้เห็นภาพมากขึ้น ในบทความนี้จะใช้เป็น Checklist ด้านล่างนี้ ซึ่งอ้างอิงจาก ASVS V1.2 และ V15.3 ที่ระดับการตรวจสอบ Level 2 ครับ

V1.2 Injection Prevention

  • ฟังก์ชันควรทำ Encode หรือ Escape ข้อมูลที่มีที่มาจากผู้ใช้งานก่อนที่จะนำไปประมวลผลหรือแสดงบนแอปพลิเคชัน
  • ฟังก์ชันไม่ควรใช้งาน URL Protocol ที่อันตราย เช่น javascript: และ data:
  • ฟังก์ชันมีการทำ Parameterized Query, Prepared Statement หรือเทคนิคอื่น ๆ ที่เทียบเท่า เมื่อมีการใช้งานคำสั่งที่มีความเสี่ยงจะเกิด Injection
  • LaTeX Processor มีการตั้งค่าอย่างปลอดภัย เช่น ไม่ใช้งาน Flag -shell escape และมีการตั้ง Allowlist คำสั่งที่ใช้งานได้

V15.3 Defensive Coding

  • ฟังก์ชันควรจะคืนข้อมูลกลับมาแค่เท่าที่จำเป็นเท่านั้น
  • เซิร์ฟเวอร์ไม่ทำการ Follow Redirect เมื่อมีการเรียกใช้งาน API ภายนอก นอกจากว่าจะเป็นไปตามฟังก์ชันที่ออกแบบไว้
  • ฟังก์ชันควรจะรับข้อมูลจากผู้ใช้งานเท่าที่จำเป็นต้องใช้งานเท่านั้น
  • Proxy และ Middleware ควรจะส่งต่อ IP Address ของผู้ใช้งาน โดยที่ผู้ใช้งานไม่สามารถควบคุมค่าเอง
  • ตัวแปรต่าง ๆ ในโค้ดมีการกำหนด Type อย่างรัดกุมและเหมาะสมกับการใช้งาน
  • การเปรียบเทียบค่าระหว่างตัวแปรต่าง ๆ ในโค้ดควรจะมีความรัดกุมและถูกต้อง
  • โค้ดมีการสร้าง Object ปลอดภัย โดยรับเฉพาะข้อมูลจากผู้ใช้งานเฉพาะเท่าที่จำเป็นต้องใช้งานเท่านั้น

ทีนี้ เรามาดูโค้ดบางส่วนของฟังก์ชันสมัครสมาชิกต่อไปนี้

ไฟล์: user.ts
https://github.com/juice-shop/juice-shop/blob/master/models/user.ts

class User extends Model<
[...]
 
const UserModelInit = (sequelize: Sequelize) => {
  User.init(
[...]
  	role: {
    	type: DataTypes.STRING,
        defaultValue: 'customer',
    	validate: {
      	isIn: [['customer', 'deluxe', 'accounting', 'admin']]
    	},
    	set (role: string) {
      	const profileImage = this.getDataValue('profileImage')
[...]

ไฟล์: datacreator.ts
https://github.com/juice-shop/juice-shop/blob/master/data/datacreator.ts

async function createUsers () {
  const users = await loadStaticUserData()
 
  await Promise.all(
    users.map(async ({ username, email, password, customDomain, key, role, deletedFlag, profileImage, securityQuestion, feedback, address, card, totpSecret, lastLoginIp = '' }) => {
  	try {
    	const completeEmail = customDomain ? email : `${email}@${config.get<string>('application.domain')}`
    	const user = await UserModel.create({
          username,
      	email: completeEmail,
          password,
      	role,
          deluxeToken: role === security.roles.deluxe ? security.deluxeToken(completeEmail) : '',
          profileImage: `assets/public/images/uploads/${profileImage ?? (role === security.roles.admin ? 'defaultAdmin.png' : 'default.svg')}`,
          totpSecret,
      	lastLoginIp
    	})
[...]

จากโค้ดข้างบน จะพบข้อสังเกตที่ผิดไปจาก Secure Coding Checklist ที่เรากำหนดไว้ ดังนี้

  • ตัวแปรส่วนใหญ่ไม่มีการทำ Encode หรือ Escape ข้อมูลจากผู้ใช้งาน ซึ่งอาจจะนำไปสู่ช่องโหว่ในกลุ่ม Injection
  • ฟังก์ชันรับค่า role และ lastLoginIp จากผู้ใช้งานโดยตรง ซึ่งเกินกว่าที่ฟังก์ชันจำเป็นรับจากผู้ใช้งาน

เพื่อทดสอบว่าเป็นช่องโหว่จริง จึงลองสมัครสมาชิกด้วย HTTP Request ดังในภาพ และได้ผลลัพธ์ว่าสามารถสมัครสมาชิกเป็นผู้ดูแลระบบได้สำเร็จ รวมถึงแก้ไข IP Address ให้ไม่ตรงกับความเป็นจริงได้ ซึ่งตรงกับภัยคุกคามที่เราได้คิดไว้ใน Threat Modelling

นอกจากนั้น ยังพบว่าเซิร์ฟเวอร์ตอบกลับข้อมูลออกมาเกินความจำเป็นจำนวนมาก ซึ่งผิดไปจาก Secure Coding Checklist เช่นกัน

จาก Checklist เล็ก ๆ นี้ เราสามารถตรวจสอบได้แล้วว่าโค้ดของฟังก์ชันขาดความปลอดภัยในส่วนไหน และส่วนที่ขาดไปส่งผลกระทบให้เกิดภัยคุกคามอะไรบ้าง ทำให้เราสามารถแก้ไขปัญหาได้ทันก่อนที่ปัญหานี้จะไปถึงสภาพแวดล้อม Production

White box หรือ Black box ในมุมมองของ ASVS

สำหรับการตรวจสอบก่อนหน้านี้ เราสามารถเข้าถึงและตรวจสอบซอร์สโค้ดได้โดยตรง การทดสอบลักษณะนี้เรียกว่าการทดสอบเจาะระบบแบบ White Box ซึ่งเป็นการจำลองสถานการณ์ที่ผู้โจมตีสามารถเข้าถึงเอกสารและซอร์สโค้ดที่เกี่ยวข้อง

ในทางกลับกัน หากไม่ได้รับสิทธิ์ในการเข้าถึงข้อมูลเหล่านี้ การทดสอบประเภทนี้จะเรียกว่าแบบ Black Box ซึ่งเป็นการจำลองการโจมตีระบบจากผู้โจมตีภายนอกที่มีข้อมูลเกี่ยวกับระบบน้อยมาก

หากต้องทดสอบฟังก์ชันแบบ Black Box ผู้ทดสอบอาจต้องเก็บข้อมูลจาก API ต่าง ๆ ในระบบ สังเกตการณ์ และดำเนินการทดลองไปเรื่อย ๆ ภายในกรอบระยะเวลาที่กำหนด ซึ่งอาจส่งผลให้ผู้ทดสอบใช้เวลามากขึ้นและมีโอกาสพบช่องโหว่ไม่ครบถ้วนสูงกว่า

ตัวอย่างเช่น ช่องโหว่ที่พบก่อนหน้านี้ หากใช้งานตามปกติโดยไม่อ่านซอร์สโค้ด จะพบข้อมูลเพียงในภาพด้านล่าง ซึ่งอาจหลุดรอดการตรวจสอบไปได้

ถึงแม้ว่า White Box จะให้ผลลัพธ์ที่ดีกว่า Black Box อย่างชัดเจนในเชิงหลักการ แต่ในทางปฏิบัติ ซอร์สโค้ดถือเป็นทรัพย์สินทางปัญญาขององค์กร การเปิดเผยต่อบริษัทภายนอกจึงเป็นเรื่องละเอียดอ่อน และอาจเพิ่มความเสี่ยงที่ข้อมูลจะรั่วไหลได้ แม้ว่าองค์กรนั้นจะมีความน่าเชื่อถือสูงเพียงใด ประเด็นนี้ยังคงเป็นที่ถกเถียงกันเสมอ

สำหรับประเด็นนี้ OWASP ได้ระบุไว้ใน ASVS ว่าหลักเกณฑ์ของ ASVS ถูกออกแบบโดยใช้แนวคิดที่ว่าผู้ทดสอบสามารถเข้าถึงข้อมูลทั้งหมดที่เกี่ยวข้องกับแอปพลิเคชันได้รวมถึงโค้ด การทดสอบหลักเกณฑ์ ASVS แบบ Black Box ที่ขาดข้อมูลที่จำเป็นต่อการทดสอบ จึงถูกพิจารณาว่าไม่มีประสิทธิภาพและใช้เวลานานกว่า เมื่อเปรียบเทียบกับการทดสอบแบบ White Box

ด้วยเหตุผลดังกล่าว OWASP จึงแนะนำว่าในการทดสอบแอปพลิเคชันว่าตรงตามเกณฑ์ของ ASVS หรือไม่ ควรใช้การทดสอบแบบ Gray Box (เข้าถึงข้อมูลบางส่วน) เป็นอย่างน้อย หรือ White Box จะเหมาะสมมากที่สุด และไม่แนะนำให้ใช้ ASVS ประกอบกับทดสอบแบบ Black Box เพราะมีประสิทธิภาพน้อยที่สุด

มาตรฐานการรักษาความมั่นคงปลอดภัยสำหรับเว็บไซต์

เมื่อวันที่ 16 กันยายน พ.ศ. 2568 ที่ผ่านมา ทางสำนักงานคณะกรรมการรักษาความมั่นคงปลอดภัยไซเบอร์แห่งชาติ (สกมช.) ได้ออกประกาศราชกิจจานุเบกษาว่าด้วยเรื่อง มาตรฐานการรักษาความมั่นคงปลอดภัยสำหรับเว็บไซต์ (Website Security Standard) ซึ่งจะเริ่มใช้เป็นมาตรฐานในหน่วยงานรัฐตั้งแต่ปี พ.ศ. 2569 เป็นต้นไป

URL ประกาศฉบับเต็ม: https://ratchakitcha.soc.go.th/documents/86192.pdf

มาตรฐานฯ ของไทย มีขอบเขตที่กว้างกว่า OWASP ASVS 5.0 อย่างมาก เนื่องด้วย OWASP ASVS 5.0 มุ่งเน้นที่ความมั่นคงปลอดภัยของซอฟต์แวร์ โดยตรง ในขณะที่มาตรฐานไทยเป็นข้อกำหนดขั้นต่ำที่ครอบคลุมทั้งมิติการกำกับดูแล (Governance) โครงสร้างพื้นฐาน (Infrastructure) และการปฏิบัติการ (Operation)
หากได้ดำเนินการตามข้อกำหนดของ OWASP ASVS 5.0 (ซึ่งเน้นการตรวจสอบความปลอดภัยโค้ดของแอปพลิเคชันโดยละเอียด) แล้ว สิ่งที่จะต้องดำเนินการเพิ่มเติมเพื่อให้สอดคล้องกับมาตรฐานฯ ของไทย มีดังนี้

  • ต้องจัดทำ นโยบาย และ กลยุทธ์การจัดการความเสี่ยง โดยกำหนด ระดับความเสี่ยงที่ยอมรับได้ (Risk Appetite) และ ระดับความเสี่ยงที่ยอมให้เบี่ยงเบนได้ (Risk Tolerance) รวมถึงการจัดโครงสร้างองค์กรตามหลัก Three Lines of Defense
  • ต้องมีการ จัดการข้อมูลจราจรทางคอมพิวเตอร์ (Log Management) ให้เป็นไปตาม พระราชบัญญัติว่าด้วยการกระทำความผิดเกี่ยวกับคอมพิวเตอร์
  • ต้องทำ System Hardening สำหรับ ระบบปฏิบัติการ, Web Server, CMS, และ ฐานข้อมูล โดยแนะนำให้อ้างอิงตามมาตรฐานภายนอก เช่น NIST SP 800-123 และ CIS Benchmarks
    ขอบเขตมาตรฐานไทยครอบคลุมการจัดวางอุปกรณ์รักษาความปลอดภัย เช่น Firewall, WAF, IDS/IPS, SIEM/SOAR/XDR ร่วมกับ Web Server และ ฐานข้อมูล
  • ต้อง พิจารณา การพิสูจน์ตัวตนแบบ Multi-Factor Authentication (MFA) หรือ Digital ID นอกเหนือจากการควบคุมการเข้าถึงทั่วไป
  • ต้องจัดทำ แผนการรับมือภัยคุกคาม (Incident Response Plan) และมีการ ฝึกซ้อม ตามแผนอย่างสม่ำเสมอ และต้องจัดทำ แผนความต่อเนื่องทางธุรกิจ (BCP)

สรุปการทำ OWASP ASVS 5.0 ทำให้โค้ดปลอดภัยในระดับสากล แต่เพื่อให้ผ่านข้อกำหนดมาตรฐานฯ ของไทย ต้องเพิ่มเติมในส่วนของ ธรรมาภิบาล (Governance), การ Hardening ระบบปฏิบัติการ/ฐานข้อมูล, และ การบริหารจัดการ Log/เหตุการณ์ฉุกเฉิน ให้สอดคล้องกับกฎหมายของไทย

บทส่งท้าย

ลองทำ Mini‑Playbook ภายในทีมให้ใช้ ASVS กัน ! มี 5 ขั้นตอนดังนี้

  • การตั้งระดับ Level เริ่มที่ L1 เป็น Baseline ของทุกซอฟต์แวร์ที่พัฒนา แล้วค่อยกำหนดว่าอะไรต้องอัปเป็น L2/L3 ตามค่าความเสี่ยงและความคาดหวังของผู้ใช้งาน หรือข้อกำหนดตามนโยบายอื่น ๆ
  • นำข้อกำหนดที่เลือกทำเป็น Checklist แตกบทที่เกี่ยวข้อง (เช่น V1, V13, V15) เป็นข้อย่อย “ตรวจผ่าน/ไม่ผ่าน” รวมถึงใส่ เงื่อนไขที่จะบอกว่าผ่าน (Acceptance Criteria)
  • ถ้ามี CI Pipeline อยู่แล้ว ควรผูกเรื่อง ASVS กับ CI Pipeline เช่นการตรวจสอบตาม Checklist ที่เรากำหนดไว้อย่างอัตโนมัติเท่าที่ทำได้ อันไหนทำไม่ได้ใส่เป็น Aritifact ประกอบตามหลังเช่น Screenshot, ส่วนของโค้ดที่เกี่ยวข้อง หรือ Log
  • กำหนดสิ่งห้าม เช่น ห้ามรับ role/lastLoginIp จากผู้ใช้งาน ห้าม Follow Redirect อัตโนมัติ ฯลฯ
  • ระบุขอบเขตอื่น ๆ ให้ชัดเจน นอกจาก Level ที่ทดสอบ เช่น ข้อกำหนดที่ครอบคลุม, ข้อที่ไม่เกี่ยว/ไม่ใช่ สามารถเป็นไปได้ และ แนวทางแก้ไขเมื่อพบว่าไม่ผ่าน

โดยสรุปแล้ว OWASP ASVS เป็นมาตรฐานที่ช่วยให้องค์กรสามารถยกระดับการตรวจสอบความปลอดภัยของโค้ดได้อย่างมีประสิทธิภาพ ซึ่งสามารถนำไปประยุกต์ใช้ได้ตั้งแต่ขั้นตอนการพัฒนาโค้ด ทางผู้เขียน หวังเป็นอย่างยิ่งว่าบทความนี้จะเป็นประโยชน์ในการพัฒนาแอปพลิเคชันที่ปลอดภัยภายในองค์กร หรือสำหรับผู้ตรวจประเมิน เพื่อให้สามารถประเมินความปลอดภัยของแอปพลิเคชันได้อย่างครอบคลุมและครบถ้วนยิ่งขึ้น

 

บทความที่เกี่ยวข้อง