OWASP TOP 10 สิบช่องโหว่สุดอันตรายที่ developer ทุกคนต้องพึงระวัง!
ในปัจจุบันเราคงปฏิเสธกันไม่ได้นะครับว่าชีวิตของเราและอินเตอร์เน็ตมีส่วนเกี่ยวข้องจนแทบจะเป็นส่วนเดียวกันกับชีวิตประจำวันของเราแล้ว ตั้งแต่การสื่อสารส่วนตัว ซื้อขายสินค้าจนรวมไปถึงการลงทุนและการเคลื่อนย้ายข้อมูลหรือใช้จ่ายทางธนาคารผ่านระบบออนไลน์ ดังนั้นการออกแบบระบบและเฝ้าระวังความเสี่ยงที่จะถูกโจมตีต่อระบบเหล่านี้จึงเป็นสิ่งสำคัญอันดับต้นๆที่ ผู้ออกแบบระบบหรือผู้พัฒนาเวปไซต์และ application จะต้องให้ความสำคัญ
ทีนี้ในฐานะผู้ออกแบบระบบ เราจะเริ่มที่ไหนดีเนื่องจากสิ่งที่เราจะต้องป้องกันมีเยอะแยะไปหมดทำทั้งหมดคงจะไม่ไหว?
ข่าวดีก็คือมีองค์กรอิสระที่ชื่อว่า โอวาป (OWASP - Open Web Application Security Project) แปลเป็นไทยก็คือ “โปรเจคสาธารณะด้านความปลอดภัยของเวปไซต์” ซึ่งจะช่วยเป็นศูนย์กลางในการรวบรวมข้อมูลและจัดอันดับช่องโหว่ความปลอดภัยและจัดอันดับเพื่อให้นักพัฒนาโฟกัสในส่วนที่สำคัญๆก่อน โดยการจัดอันดับนี้่จะทำใหม่ในทุกๆ 3-4 ปี ซึ่งเวอร์ชั่นล่าในขณะที่ผมเขียนบทความนี้(สิงหาคม 2023) จะเป็น version ของปี 2021 ซึ่งปรับอันดับใหม่จากปี 2017
โอเคครับ ถึงตรงนี้เรามาดูกันว่า 10 อันดับล่าสุดมีอะไรบ้าง
อันดับที่ 1 - ช่องโหว่ในการจำกัดสิทธิการเข้าถึง (A01:2021-Broken Access Control)
ช่องโหว่หรือความผิดพลาดนี้ขยับมาจากอันดับ 5 ในปี 2017 ขึ้นมาเป็นอันดับ 1 หรือเป็นอันดับที่มีความเสี่ยงและพบได้มากที่สุดในปี 2021 เลยทีเดียว
Broken Access Control คืออะไร
การตรวจสอบก่อนการเข้าถึงระบบต่างๆส่วนใหญ่จะแบ่งเป็นสองขั้นตอนคือการ authentication (การยืนยันตัวตน) และ authorization (การระบุสิทธิการเข้าถึง)
ยกตัวอย่างง่ายๆเช่น นายสมชาย ใส่ username/password เพื่อเข้าใช้เวปไซต์ของธนาคาร ถ้าใส่ถูกอันนี้คือการยืนยันตัวตนผู้ที่เข้ามานั้นเป็น user ของคุณสมชายจริงๆ ขั้นตอนนี้ก็คือ Authentication
หลังจากนายสมชายเข้าไปยังเวปไซต์ได้แล้ว ขั้นตอนต่อไปก็คือการตรวจสอบว่าบัญชีไหนที่นายสมชายสามารถเข้าไปดูหรือเปลี่ยนแปลงข้อมูลได้ ขั้นตอนนี้เรียกว่า Authorization ซึ่งช่องโหว่เรื่อง Broken Access Control อยู่ในขั้นตอนนี้ครับ ถ้า user ของคุณสมชายสามารถเข้าถึงข้อมูลของคนอื่นได้ไม่ว่าจะโดยใช้ช่องทางพลิกแพลงอย่างไรก็ตาม ถือว่าเกิดการ broken access control ขึ้นแล้วครับ!
ตัวอย่าง source code ที่มีช่องโหว่ของ Broken Access Control
1const express = require('express');
5 alice: { username: "alice", role: "user" },
6 bob: { username: "bob", role: "user" }
9app.get('/user/:userId', (req, res) => {
10 const requestedUserId = req.params.userId;
11 const user = userDatabase[requestedUserId];
14 res.send(`Welcome, ${user.username}! Your role is ${user.role}.`);
16 res.status(404).send("User not found.");
21app.listen(PORT, () => {
22 console.log(`Server is running on port ${PORT}`);
จากตัวอย่างโค้ด NodeJs ข้างบนจะเห็นได้ว่ามี endpoint คอยครับค่า userId เข้ามา แล้วนำไปค้นข้อมูลจาก database เพื่อนำข้อมูลของ user นั้นๆมาแสดง จะเห็นได้ว่าค่า userId จะถูกส่งมาจากฝั้ง client ทำให้สามารถแก้ id ให้เป็น user อื่นๆเพื่อดูข้อมูลได้
แม้ว่า endpoint นี้จะไม่สามารถเห็นได้โดย user ทั่วไป ตัวอย่างเช่น Bob login ด้วย username/password ของตัวเองเข้าไปยังเวปไซต์ และ click ไปยังหน้า profile page, หลังจากนั้นฝั่ง frontend ก็จะ request ไปยัง API /user/bob เพื่อจะนำข้อมูลมาแสดง
ถ้า Bob มีความรู้ด้าน frontend นิดหน่อยก็จะสามารถเปลี่ยน request ใน console ให้เป็น /user/alice เพื่อแอบดูข้อมูลของ Alice ได้ครับ
วิธีป้องกัน
ตอบแบบกำปั้นทุบดินเลยก็คือการใส่ Access Control เข้าไปครับ ในทุกๆ function ที่มีการดึงข้อมูลของ user เราไม่ควรรับค่าผ่านทาง parameters โดยตรง แต่ควรจะเป็นการ decode token ที่ได้รับจากการ Authenticate (ยืนยันตัวบุคคล) ของ user นั้นๆ หลังจากนั้นเราควรมีการประเมิณสิทธิในการเข้าถึงด้วย Role Base Access Control (RBAC)
ว่า user นั้นๆมีสิทธิทำอะไรได้บ้างเทียบกับ role ของตนเอง
อีกหลักการหนึ่งที่นิยมใช้กันในการจัดทำสิทธิการเข้าถึงก็คือ Least Privliege
หรือก็คือการจำกัดให้มีสิทธิน้อยที่สุด ตัวอย่างเช่นหากเรามี backend service ที่จะทำการอ่านข้อมูลจาก database ไปแสดงผลเป็น report บน frontend permission ที่เราให้ backend service นี้ควรจะเป็น read-only ในหลายๆครั้งที่เราอาจเกิดความมักง่ายโดยการ grant full access ให้ application แม้มี operation ที่ไม่จำเป็นต้องใช้ ซึ่งเป็นสิ่งที่ developer ทุกคนควรปรับปรุง mindset ตรงนี้
อันดับที่ 2 - ช่องโหว่ในการเข้ารหัส (A02:2021-Cryptographic Failures)
ช่องโหว่นี้เลื่อนอันดับจากความสำคัญอันดับที่ 3 ในปี 2017 ขึ้นมาเป็นความสำคัญมากขึ้นเป็นอันดับที่ 2 ในปี 2021 จะเห็นได้ว่าการตั้งชื่อของช่องโหว่จะเปลี่ยนไปเล็กน้อย จาก “การรั่วไหลของข้อมูลสำคัญ (A03-Sensitive Data Exposure) มาเป็น “ช่องโหว่ในการเข้ารหัส” เนื่องจากทางโอวาปอยากเน้นความสำคัญไปที่ต้นตอของปัญหา มากกว่าการเจาะจงไปที่ปลายเหตุ
ตัวอย่างเหตุการณ์ในชีวิตประจำวันเกี่ยวกับความผิดพลาดในการเข้ารหัส
- Man in the middle (ผู้ดักขโมยข้อมูลตรงกลาง) คุณไปนั่งทำงานใน internet cafe และมีการ login เข้าเวปไซต์ของที่ทำงาน แต่ทางเวปไซต์ไม่ได้ใช้ SSL protocol (https) ในการรับส่งข้อมูล. ข้อมูลที่คุณพิมพ์ส่งไปไม่ได้ถูกเข้ารหัส นักเจาะระบบสามารถดักข้อมูลคุณได้ที่ router และสามารถนำข้อมูลเหล่านั้นไปใช้ได้ทันที หากมีการเข้ารหัสข้อมูล แม้นักเจาะระบบจะสามารถดักข้อมูลได้แต่ข้อมูลเหล่านั้นจะไม่ได้สามารถนำไปใช้ได้อยู่ดี
- การไม่ได้เข้ารหัสข้อมูลใน database: ด้วยเหตุผลบางอย่างนักเจาะระบบสามารถทำการขโมยข้อมูลของลูกค้าคุณจาก database ไปได้ทั้งหมด ซึ่งรวมไปถึงข้อมูลบัตรเครดิตของลูกค้าแต่ละคนด้วย ลองจินตนาการดูนะครับ ว่าเหตุการณ์จะเลวร้ายขนาดไหนถ้าคุณไม่ได้เข้ารหัสข้อมูลของบัตรเครดิตใน database
- การถอดรหัสใช้วิธีที่ง่ายเกินไป ลองนึกถึงกรณีการเก็บข้อมูลบัตรตัวอย่างที่แล้ว แม้ว่าคุณจะทำการเข้ารหัสข้อมูลสำคัญๆก่อนเก็บลงยัง database แต่ก็ยังอาจจะมีปัญหากับความเสี่ยงทางด้านความปลอดภัยอยู่ดีหากว่าคุณใช้วิธีการถอดรหัสที่คาดเดาได้
ตัวอย่างเช่น นักเจาะระบบอาจจะปลอมตัวเป็น user รายนึงของระบบ เค้าอาจเจาะระบบเพื่อได้ข้อมูลที่เข้ารหัสอยู่ใน database ได้ เนื่องจากนักเจาะระบบผู้นี้มีข้อมูลที่ถูกเข้ารหัสและรู้ค่าจริงหลังจากถอดรหัสแล้ว ทำให้เข้าสามารถรู้ว่า key ที่ใช้เข้ารหัสคืออะไร ถ้าหาก user ทุกคนใช้ key ในการเข้ารหัสตัวเดียวกัน นักเจาะระบบผู้นี้สามารถถอดรหัสเพื่อให้ได้ข้อมูลของ user คนอื่นๆได้อย่างง่ายดายครับ
วิธีป้องกัน
ถ้าสังเกตดีๆจะเห็นได้ว่าปัญหาในการเข้ารหัสจะเกิดที่สองส่วนใหญ่คือ
- ระหว่างการส่งข้อมูล (data at transit)
- เมื่อมีการเก็บข้อมูลลงฐานข้อมูล (data at rest)
ดังนั้นทุกครั้งที่มีการจัดการกับข้อมูลในสองส่วนนี้ ให้เราจำให้ขึ้นใจนะครับว่าอย่าลืมเข้ารหัสเด็ดขาดและต้องคำนึงถึงการเข้ารหัสที่มีประสิทธิภาพด้วยนะครับ
นอกจากนี้ทุกครั้งที่เราทำการออกแบบฐานข้อมูล เราควรจะจัดแบ่งชนิดของข้อมูลให้ชัดเจนว่าข้อมูลชุดไหนที่มีความอ่อนไหวหรือสามารถก่อให้เกิดความเสียหายหากมีการรั่วไหล การแจกแจงข้อมูลเหล่านี้จะทำให้เราลดปริมาณความเสี่ยงที่จะเกิดขึ้นได้ ในการเก็บข้อมูลเราก็ควรจะเก็บแต่ข้อมูลที่จำเป็นและทำการลบทิ้งทันทีที่ไม่ต้องการ
อันดับที่ 3 - การแทรกซึมคำสั่ง (A03-2021-Injection)
การแทรกซึมคำสั่งหรือ injection นี้ลดลงมาจากอันดับที่ 1 เมื่อปี 2017 (A01-2017-Injection) มาเป็นอันดับที่ 3 ในปี 2017 ตัวอย่าง injection ที่เกิดขึ้นบ่อยเช่น SQL injection การโจมตีนี้จะเกิดขึ้นในลักษณะที่ผู้เจาะระบบจะแฝงคำสั่งผ่านช่องโหว่ต่างๆเพื่อให้เข้ามารันในระบบและก่อให้เกิดผลลัพธ์อันไม่พึงประสงค์ต่อตัวระบบเอง ตัวอย่างของ injection ที่รู้จักกันดีอย่างเช่น SQL injection ที่ผู้เจาะระบบจะทำการใส่แฝงคำสั่งมากับค่า parameter ที่จะนำมาเป็นตัวแปลใน database statement
ตัวอย่างการโจมตีด้วย injection
ลองดูตัวอย่างสคริปข้างล่างนี้นะครับ
1SELECT * FROM user_profile WHERE user_id = ${id};
จุดประสงค์ของ script ข้างบนมีเพื่อการร้องขอข้อมูล user จาก database โดยการใส่ id ของ user ผ่านทางตัวแปร ${id}
โดยปกติทั่วไปถ้าค่าตัวแปรเป็นข้อมูลปกติ ยกตัวอย่างเช่น id=111
เราก็ได้ script ประมาณนี้
1SELECT * FROM user_profile WHERE user_id = 111;
ซึ่งตรงกับจุดประสงค์ของ script ใช่ไหมครับ? ทีนี้ลองคิดดูว่าหากนักเจาะระบบส่งค่าดังนี้ id=111; DROP TABLE user_profile
script SQL ก็จะเป็นดังนี้
1SELECT * FROM user_profiles WHERE user_id = 111; DROP TABLE user_profile;
เห็นความน่ากลัวไหมครับ ข้อมูล user ทั้ง database จะสามารถถูกลบออกไปได้เลย
วิธีป้องกัน injection
หลักแนวคิดในการป้องกันการโจมตีพวกนี้ก็คือ เราต้องป้องกันการแอบส่งคำสั่งเข้ามาทาง input ใดๆจะทำให้ function หรือ application รัน command ที่ไมได้เป็นจุดประสงค์ของ application นั้นๆของเรา การป้องกันสิ่งเหล่านี้จะต้องคิดในหลายๆมิติหลายๆส่วน ข้างล่างเป็นเพียงตัวอย่างส่วนนึงเท่านั้นนะครับ
- Validate และแปลงข้อมูลที่ user ใส่เข้ามาก่อนที่จะนำไปใช้กับ script จริง ยกตัวอย่างเช่น หากเรารู้ว่า user_id ควรจะเป็นตัวเลขเท่าน้้น ระบบก็ไม่ควรจะยินยอมให้รับค่าชนิดอื่นๆเช่น String เข้ามา
- Parameterized query: หรือใช้การค้นข้อมูลด้วยตัวแปลแทนการสร้าง SQL statement เช่น
3SELECT * FROM users WHERE id = @userId;
ในตัวอย่างข้ างบน เราจะใช้ตัวแปลของ SQL เลยดังนั้นเมื่อไหร่ที่ค่าตัวแปรไม่เป็นไปตามปกติ อย่างเช่นไม่ใช่ตัวเลข ระบบก็ตรวจจับและปฏิเสธการรันคำสั่งได้ทันที
- ใช้ Stored Procedures ตัวอย่างเช่น
2CREATE PROCEDURE GetUser(IN userId INT)
4 SELECT * FROM users WHERE id = userId;
จากตัวอย่างข้างบนจะเห็นได้ว่าแทนที่ backend application จะต้องสร้าง query string เองทั้งหมด backend แค่ส่งค่าผ่านคำสั่ง GetUser($id)
ก็จะสามารถหาค่าที่ต้องการได้แล้ว อีกทั้ง database ก็จะทำการ validate ตัวแปล userId ให้โดยอัตโนมัติ
- ใช้ WAP (Web Application Firewall) ซึ่งจะช่วยเป็นอีกหนึ่ง layer ที่ช่วยเราป้องกันปัญหาเหล่านี้ได้ในเบื้องต้น
อันดับที่ 4 - การออกแบบที่ไม่ปลอดภัย (A04-2021-Insecure Design)
การออกแบบที่ไม่ปลอดภัยนี้เป็นหมวดหมู่ใหม่ที่ OWASP จัดทำขึ้นมาในปี 2021 และติดโผอันดับช่องโหว่สุดอันตรายในทันที ซึ่งแนวคิดของการประเมิณหมวดหมู่นี้ขึ้นมาก็คือ เราควรจะใส่ใจความปลอดภัยในการพัฒนา application ก่อนที่เราจะเริ่มการเขียนโปรแกรมด้วยซ้ำ ซึ่งขั้นตอนอันนี้ก็คือขั้นตอนการออกแบบ หรือ design นั่นเอง ต่อให้ implement application ดีแค่ไหน ถ้าออกแบบไม่ดีก็จะทำให้เกิดช่องโหว่ในด้านความปลอดภัยได้
ตัวอย่างการออกแบบผิดพลาดที่พบได้ทั่วไปอาทิเช่น
- การส่งข้อมูลที่สำคัญๆออกมากับ error หรือ response
- การไม่ปกป้องที่ที่เอาไว้เก็บข้อมูลสำคัญ (credential) ตัวอย่างเช่นการ hardcode password เข้าไปใน source code หรือการไม่เข้ารหัสข้อมูล)
- การกำหนดความเชื่อใจระหว่าง application ที่น้อยเกินไป ตัวอย่างเช่น เชื่อใจว่า input ที่ส่งมาจาก frontend จะเป็นชนิดที่ต้องการและไม่ทำการ validate ก่อนที่จะนำมาประมวลผลใน backend
- ฯลฯ
วิธีการป้องกัน
- ใช้ library ในการพัฒนา application ที่ใช้ pattern การออกแบบที่ปลอดภัยและได้รับการรับรองมาตรฐาน
- วิเคราะห์และใช้การจำลองภัยคุกคาม (Threat modeling) เพื่อที่จะได้ออกแบบวิธีและการป้องกันที่เหมาะสม
- เขียน unit test และ integration test เพื่อให้มั่นใจได้ว่า application มีความพร้อมในการรับมือกับภัยคุกคามแบบต่างๆ (ตัวอย่างเช่น การ validate input ก่อนที่จะนำได้เข้าการคำนวน)
- จำกัดสิทธิการเข้าถึงส่วนต่างๆของ application โดยแบ่งตามผู้ใช้หรือว่าการให้บริการ
อันดับที่ 5 - การกำหนดค่าความปลอดภัยที่ผิดพลาด (A05-2021-Security Misconfiguration)
ช่องโหว่ประเภทนี้ขยับขึ้นมาจาก อันดับ 6 ในปี 2017 มาเป็นอันดับ 5 ในปี 2021 นั่นหมายความความผิดพลาดชนิดนี้มีปริมาณมากขึ้นเทียบกับ 3-4 ปีที่ผ่านมา
การกำหนดค่าความปลอดภัยที่ผิดพลาดเกิดขึ้นเมื่อมีการโจมตีที่เกิดขึ้นจากการ application, network หรือระบบมีการกำหนดค่าการติดตั้งที่ไม่ดี สิ่งเหล่านี้อาจจะสาเหตุมาจาก
- การใช้ค่าเริ่มตัน (default) ในการตั้งค่าโดยปราศจากการศึกษาข้อมูลที่ดี
- การตั้งค่าที่ไม่เสร็จสมบูรณ์ ตัวอย่างเช่น ไม่ได้เอา development mode ออกก่อนจะ deploy ขึ้น production
- ไม่เอา service หรือ feature ที่ไม่จำเป็นออก ตัวอย่างเช่น endpoint ที่เอาไว้ดูข้อมูลของ server
ตัวอย่าง
ลองจินตการว่าเรามีการ deploy database ขึ้นไปในระบบ production เพื่อใช้ใรการเก็บข้อมูลจริงของลูกค้า แต่ว่าเราลืมที่จะเปลี่ยน user/password admin/admin ออก อีกทั้งเรายังไม่ได้เปลี่ยน port หลักจาก 3306 เป็น port อื่นๆที่คาดเดาได้ยาก ผู้โจมตีระบบจะสามารถใช้ช่องโหว่นี้ในการหาทาง connect เพื่อขโมยข้อมูลลองเราจาก database นี้อย่างง่ายดาย
วิธีป้องกัน
- เปลี่ยน default password ทุกครั้งและใช้ password ที่ยากต่อการคาดเดา
- กำหนด whitelist ของ user/service ที่จะสามารถต่อเข้าระบบเราได้ด้วย firewall
- คอย update security patch อย่างสม่ำเสมอ
- พัฒนา access controls และการเข้ารหัส
อันดับที่ 6 - การใช้ส่วนประกอบที่มีช่องโหว่หรือล้าสมัย (A06-2021-Valnerable or outdated components)
OWASP ได้เพิ่มอันดับช่องโหว่ตัวนี้จากอันดับ 9 ในปี 2017 มาเป็นอันดับ 6 ในปี 2021
ช่องโหว่นี้เกิดการที่เรานำ library หรือ module ภายนอกมาใช้และปล่อยทิ้งไว้โดยไม่มีการอัปเดทเลย ซึ่งเป็นสิ่งที่อันตรายมาก โดยเฉพาะกับ open source library เนื่องจากผู้โจมตีสามารถเห็น source code ของ component พวกนี้และหาช่องโหว่ได้ และส่วนใหญ่พวก library หรือ component เหล่านี้จะมีการพัฒนาและค้นพบช่องโหว่เป็นระยะๆ และจะทำการประกาศช่องโหว่ที่ค้นพบ พร้อมแนะนำให้ upgrade ไปยังเวอร์ชั่นใหม่ที่มีความปลอดภัยสูงกว่า ซึ่งการประกาศอย่างนี้ถือเป็นดาบสองคม อาจจะทำให้เราตื่นตัวและ ติดตั้งเวอร์ชั่นใหม่ได้ทันเวลา แต่ว่าขณะเดียวกันเป็นการเปิดเผยช่องว่างให้ผู้โจมตีทราบอีกด้วย
วิธีการป้องกัน
- ใช้ library / component เฉพาะที่สำคัญและจำเป้นเท่านั้น
- ใช้คำสั่งของ package managerในการตรวจเวอร์ชั่นที่ปลอดภัย ตัวอย่างเช่นใช้ npm audit ใน NodeJS/javascript application
- โหลด library จากเวปทางการของ library หรือ framework นั้นๆเท่านั้น
- ใช้โปรแกรมที่ช่วยในการค้นหาช่องโหว่ เช่น Sonarqube เป็นประจำ
อันดับที่ 7 - การยืนยันหรือตรวจสอบผู้ใช้งานมีความผิดพลาด (A07-2021-Identification and Authentication failure)
ช่องโหว่นี้ใช้่ชื่อ่ว่า Broken Authentication และอยู่ที่อันดับ 2 ในปี 2017 ซึ่งตกมาอยู่ในอันดับที่ 7 ในปี 2021 นั่นแสดงว่าเรามีการป้องกันช่องโหว่ในการยืนยันตัวตนที่ดีขึ้นมาก
ตัวอย่างสาเหตุของข้อผิดพลาดในการยืนยันตัวตน
- ใช้ password ที่ง่ายต่อการคาดเดา
- ระบบอนุญาตให้มีการ brute force ตัวอย่างเช่น ระบบอนุญาตให้มีการยิง password โดยไม่มีการจำกัดจำนวนครั้ง
- ไม่มีการเข้ารหัสที่ปลอดภัยเพียงพอในการเก็บ password
- ไม่มีการใช้ multi factor authentication ในการยืนยันตัวตน เช่น ไม่ใช้ password + otp
- การบริหารจัดการ authentication token ที่ไม่ดี ตัวอย่างเช่นใช้่ token ที่ไม่มีวันหมดอายุ
อันดับที่ 8 - ความผิดพลาดในการตรวจสอบความปลอดภัยของข้อมูล (A08-2021-Data Integrity)
ความผิดพลาดในการควบคุมตรวจสอบความผิดพลาดของข้อมูลนี้เป็นหมวดหมู่ใหม่ที่ OWASP กำหนดขึ้นมาและตกอยู่ในอันดับที่ 8 ของการจัดอันดับในปี 2021 ซึ่งในหมวดหมู่นี้จะมีการควบรวมหมวดหมู่การถอดรหัสที่ไม่ปลอดภัย (Insecure Deserialization) ของปี 2017 เอาไว้ด้วย
การตรวจสอบข้อมูลก็คือการ validate ข้อมูลนั่นเอง ตัวอย่างเช่น ค่า ID ต้องมี 5 หลักและต้องเป็นตัวเลขเท่านั้น เพศต้องเป็นหญิงหรือชายเท่านั้น ในที่นี้รวมไปถึงการไม่ตรวจสอบแหล่งที่มาของข้อมูลด้วย ตัวอย่างเช่นการ update software version ที่ไม่ได้เช็คให้ดีก่อนว่าเป็นการ update ที่ปลอดภัยและมาจากแหล่งที่เป็น official ของผู้พัฒนาหรือไม่
การตรวจสอบข้อมูลที่ผิดพลาดนี้เกิดขึ้นได้ในหลายๆที่ ตัวอย่างเช่น ในตัวระบบเอง ในการอัปเดทซอร์ฟแวร์ รวมไปถึงใน CI/CD (Continuous Integration and continuous development)
ตัวอย่างวิธีป้องกัน
- ใช้ digital signature ในการตรวจสอบแหล่งที่มาของ software ว่าข้อมูลนั้นมาจากแหล่งที่เราต้องการหรือไม่
- ตรวจสอบให้แน่ใจว่า โมดูล ต่างๆเป็นแหล่งที่น่าเชื่อถือและได้รับการรับรองหรือไม่
- ใช้เครื่องมือเช่น OWASP Dependency check ในการตรวจสอบเพื่อให้แน่ใจว่าไม่มี โมดูลหรือ library ที่มีช่องโหว่ที่ถูก report ไว้แล้ว
- มีกระบวนการรีวิว code ทุกครั้งที่มีการเปลี่ยนแปลง เพื่อให้แน่ใจว่าไม่มีสิ่งที่เสี่ยงต่อความปลอดภัยปะปนอยู่ใน code
อันดับที่ 9 - การ log และ monitor ข้อมูลที่ผิดพลาด (A09-Security Logging and Monitoring Failures)
หมวดหมู่นี้ขยับขึ้นมาจากอันดับที่ 10 ในปี 2017 ซึ่งเดิมทีเป็นหมวดหมู่ชื่อ การ log และการ monitor ที่ไม่เพียงพอ (A10-2017-Insufficient Logging and Monitoring)
การ log และการ monitor มีความสำคัญอย่างมากที่จะช่วยให้เราค้นเจอและตอบสนองต่อภัยคุกคามได้อย่างทันท่วงที ลักษณะการ log และ monitor ที่ไม่สมบูรณ์และก่อให้เกิดช่องโหว่ทางความปลอดภัยมีดังนี้
- ข้อมูลที่ไว้ใช้ตรวจสอบ เช่น ปริมาณการ login การ login ที่ไม่สำเร็จ การส่งข้อมูลที่มีความสำคัญ ไม่ได้ถูก log ไว้ทำให้ไม่สามารถกลับมาตรวจสอบได้
- การ log ข้อมูลที่ไม่เพียงพอ ตัวอย่างเช่น มีการพยายาม login ติดต่อกันหลายครั้งแต่ไม่ได้เก็บข้อมูลไว้ว่าเป็น user คนไหน ช่วงเวลาอะไร
- เก็บ log ไว้ใน local เท่านั้น ในบางครั้งข้อมูล log อาจถูกทำลายโดยผู้เจาะระบบได้ ดังนั้นจึงควรแยกสถานที่เก็บ log ไว้ต่างหาก
- ไม่มีการตั้งการแจ้งเตือนเมื่อมีสิ่งผิดปกติเกิดขึ้นในระบบ ตัวอย่างเช่น แม้จะ log ว่ามีการพยายามโจมตีแต่ไม่มีการตั้งค่าการแจ้งเตือนไว้ เราอาจตอบสนองต่อการคุกคามไม่ได้ทันท่วงที
ตัวอย่างการป้องกัน
- log ข้อมูลสำคัญๆอย่างเช่น การ login การ fail validation, error ฯลฯ
- log ข้อมูลด้วย standard format เพื่อให้เราสามารถนำ log ไป feed เข้าโปรแกรมการวิเคราะห์อื่นๆได้ง่าย
- จ้างหรือปรึกษาผู้เชี่ยวชาญทางด้าน DevSecOps
อันดับที่ 10 - การปลอมแปลง request ผ่านทาง server (A10-2021-Server-Side Request Forgery)
หมวดหมู่นี่เป็นหมวดหมู่ใหม่ที่ได้รับการโหวตจาก community นะครับ ซึ่งจริงๆแล้ว Server-Side Request Forgery (SSRF) นี้เคยติดอันดับ OWASP ในปี 2013 และตกอันดับไปในปี 2017
ตัวอย่างลักษณะของช่องโหว่นี้เช่นการที่คุณมี application ตัวนึงที่อนุญาตให้ user submit url ของรูปภาพ หลังจากนั้น application ของคุณจะทำการดาวโหลดรูปภาพจาก url เพื่อมาทำการ resize และส่งผลมาแสดงให้กับ user
ผู้โจมตีสามารถใช้ช่องโหว่นี้ในการ submit url ที่เป็น server ของตนเองและทำการปลอมแปลงรูปภาพ หลังจากดาวโหลดและ process รูปภาพบน server ของคุณ รูปที่ถูกปลอมแปลงอาจถูกฝัง script ที่ทำการดูดข้อมูลบน server ของคุณได้ นอกจากนี้ผู้โจมตียังสามารถทราบได้ว่า server backend ของคุณที่ทำการดาวโหลดรูปภาพมีข้อมูลอะไรบ้างและอาจนำไปประกอบการโจมตีที่ใหญ่ขึ้นมาได้
ตัวอย่างการป้องกัน
- whitelist หรือ blacklist url จากส่วนของ network
- ใช้ web application firewall
- validate ข้อมูลที่ input มาทาง url
- ฯลฯ
เป็นอย่างไรบ้างครับหลังจากได้ศึกษาช่องโหว่ 10 อันดับของ OWASP หวังว่าข้อมูลของบทความนี้จะเป็นประโยชน์ของผู้อ่านได้ไม่มากก็น้อย การนำไปปฏิบัติจริงอาจจะต้องใช้เวลา แต่ก็อย่าเพิ่งท้อนะครับ ทบทวน ค้นคว้า และประยุกต์ใช้เรื่อยๆ วันนึงมันจะกลายเป็นของง่ายของเราครับ
สอบถาม ติชม เสนอแนะ ได้ที่ช่อง comment ด้านล่างเลยครับ