Rearchitecturing TipMe for Anti-DDoS

ช่วงหลังๆ มา TipMe โดน DDoS บ่อยขึ้น ซึ่งโดนไปแต่ละครั้งก็ต้อง rearchitect แก้ไปเรื่อยๆ เพราะเราไม่อยากบอกว่าโดนยิง ปิดบริการจนกว่าคนยิงจะเลิก

Gen 1 – Cloud Armor

Architecture ของ TipMe มันคือ Client > Google Cloud Load Balancer > ingress-nginx > gunicorn ซึ่งไม่มีกัน DDoS อะไรตรงไหนเลย นอกจากพวก Layer 4 attack ที่ Google LB absorb ให้แค่นั้น เหลือแค่ L7 ที่ต้องจัดการ

พอโดน DDoS เข้ามาแรกๆ ก็เอา Cloud Armor มาปิด แต่ Cloud Armor รุ่นแรกๆ ในมุมการป้องกัน DDoS คือแย่มาก เรียกว่ามันเป็น IP Firewall เลยก็ว่าได้ (Google Cloud LB ไม่มี IP firewall ให้แบบ AWS ALB) แถมคิดเงินตาม rule change ด้วย เลยเปิดเฉพาะระหว่างมี attack เท่านั้น

ครั้งแรกๆ ที่โดนยิง มันเป็น DoS ไม่ใช่ DDoS คือเหมือนคนกด F5 รัวๆ นี่แหละ ระบบก็ล่ม ก็ ban IP กันไปเป็นอันใช้ได้ เพราะ IP มันโผล่ชัดเจนใน Load balancer log แต่พอโดน DDoS ของจริงแล้ว request มันมาหลากหลายมาก แล้ว log ไม่ค่อยมีข้อมูลอื่น ก็จนปัญญาไม่รู้จะจับอย่างไร…

(เข้าใจว่าปัจจุบัน Cloud Armor ดีขึ้นมาหน่อย แต่คิดว่าคงไม่ใช้แล้ว)

Gen 2 – Cloudflare

มีช่วงถัดมาโดนยิงบ่อยขึ้นบ้าง ก็เลยตัดสินใจย้ายเว็บมาใช้ Cloudflare Free เต็มตัว ที่เดิมไม่ได้ใช้เพราะเว็บใช้ WebSocket ค่อนข้างเยอะกลัวจะโดนคิดเงิน แต่พอโดนยิงบ่อยๆ ก็คิดว่าช่างมันย้ายๆ แล้วกัน

สิ่งที่พบกับ Cloudflare Free คือเอาจริงๆ มันไม่ได้กันอะไรเลย คนชอบบอกว่าใช้ Cloudflare กันโดนยิง จริงๆ ไม่ใช่ ผมเปิด ticket ไปถามก็รู้ว่ามันมี threshold เลขนึงถ้าคุณยิงเข้ามาเกินเลขนี้มันจะ block ให้ แต่ถ้ายิงมาไม่ถึงมันไม่ block เพราะไม่รู้ว่ามันเป็น traffic จริงๆ หรือคุณจัด flash sale อยู่ ซึ่งเลขนี้ผมมีโซนที่เป็น Enterprise อยู่ เขาก็บอกเลขให้ (แพลนอื่นๆ เขาไม่บอก) พอเห็นเลขแล้วก็รู้เลยว่าถ้ายิงแบบ DoS มาน่าจะโดนบล็อก แต่ถ้า botnet ใหญ่ๆ แล้วยิงเบาๆ แบบนี้หลุดแน่นอน จะเอาให้อยู่สงสัยต้องใช้ e2-medium 4-5 เครื่องถึงจะรับโหลดที่เขาไม่ block เข้ามาไหว ซึ่งเปิด server เข้าสู้มันไม่ได้ทำให้เกิดรายได้ผมก็ไม่อยากจะไปใช้วิธีนี้

ทีนี้ฟีเจอร์จริงๆ ของ Cloudflare คือ firewall rule ซึ่งเราต้องเขียน rule เอง (อีกแล้ว) หลักๆ ที่มีคนแจกกันในเน็ตก็คือ ISP ไม่พึงประสงค์ พวกนี้แบนไปเลย แต่ที่จะไม่มีแจกก็คือเอา pattern ที่มีคนยิงจริงมาตั้ง block แบบนี้จะไม่หลุดเข้ามาเลย (ผมว่ามันเป็น security by obscurity หน่อยๆ ถ้าแกะได้ว่า rule ผมเขียนยังไงก็ bypass ได้ง่ายๆ)

Gen 2.5 – Cloudflare Pro

ปีนี้มี Streamer รายใหญ่เข้ามาซึ่งคนดูน่าจะเป็นสาย tech เยอะ เลยมีพวกลองของพอสมควร botnet ที่ยิงเข้ามาก็จะเป็นอีก pattern นึงไม่เหมือนสมัยก่อน

พอ pattern มันเปลี่ยน rule ที่ block อยู่เดิมมันเอาไม่อยู่ แต่ก็ไม่รู้จะเขียน rule มากันยังไง พอดีผมมี zone enterprise อยู่ก็จะเห็น firewall log มันมีกราฟให้ดู ซึ่ง free ไม่มี ก็เลยยอมซื้อ Cloudflare Pro เพื่อให้มี dashboard แบบเดียวกัน ทีนี้พอมันมี attack เข้ามาเราก็เห็น pattern ไปตั้ง block ได้ง่ายขึ้นมาก

ปัญหาของ Pro ที่ต่างกับ Enterprise คือมัน Match by Regex ไม่ได้ แล้ว TipMe URL มันเป็น vanity URL คือ https://tipme.in.th/username ทำให้ใช้ string contains อย่างเดียวมา match หน้าโดเนทไม่ได้เลย ก่อนจะยอมไปซื้อฟีเจอร์นี้ใน Business plan ก็เริ่มคิดว่าเราน่าจะถึงเวลา rearchitect กันก่อน

Gen 3 – Caching

รบร้อยครั้งชนะร้อยครั้งก็ไม่สู้ชนะได้โดยไม่ต้องรบ

เอาจริงๆ ชนะโดยไม่ต้องรบคือไม่สร้างศัตรู แต่ผมว่าเป็นไปไม่ได้ ก็ต้องรับมืออีกทางหนึ่งคือ Caching หรือการให้ Cloudflare รับหน้าแทนให้

จริงๆ การทำ Cache ก็มีความเสี่ยงสูงเพราะใน Cloudflare ถ้าจะ cache HTML ต้องตั้ง cache level = cache everything เท่านั้น แล้ว behavior มันจะเปลี่ยนไป คือถ้าไม่บอกมันว่าห้าม cache มันจะ cache by default ก็ไม่รู้ทำไมเขาออกแบบระบบให้มันงงๆ แบบนี้ ผมเคย config เว็บอื่นผิดแล้วมัน cache อันที่ไม่ควร cache ทำให้ personal info หลุดมาแล้ว (login แล้วเห็นเป็น user คนอื่น) ก็เลยรู้สึกว่าเสี่ยงสูงมากที่จะไปทางนี้ แต่ก็จำเป็นต้องทำ

ครั้งนี้ทดลองโดยการ install middleware ไว้ใน origin ที่จะส่ง Cache-Control: private, max-age=0 ทุกหน้าเลยเหมือนที่ PHP ทำให้ by default อยู่แล้ว ทดลอง test ดูก็พบว่า Cloudflare ไม่ cache จริง ก็คิดว่าทางนี้ไปได้ถูกทาง เลยไปเพิ่มให้หน้าโดเนทมี cache ได้สัก 1 นาที แล้วก็เพิ่มระบบว่าเวลา reconfig หน้าโดเนทแล้วมันจะยิงไป purge cache ของหน้านั้นให้ ซึ่งก็เป็นข้อดีของ Cloudflare ที่ purge ฟรีและไม่จำกัด ไม่เหมือน Google CDN หรือ Cloudfront ที่คิดเงินค่า invalidation ด้วย

ผลของวิธีนี้ก็ effective พอสมควร มีบาง DDoS ที่ไม่ได้รับผลกระทบเลย (โดนจับที่ Firewall rule หรือ cache ไปหมด) แต่ก็มี botnet ใหม่โผล่เข้ามาที่ยิง random path เลยเพื่อ bust cache ก็เลยเพิ่ม rule ดักจับ cache busting เข้าไปอีก

แต่ว่าหน้าที่โดนยิงเยอะที่สุดคือหน้าแรกซึ่งเดาว่าเป็น random internet traffic เลยแหละไม่ได้รู้จักอะไรกัน แล้วหน้านี้มันแสดงผลต่างกันระหว่างเวลาที่ login กับไม่ได้ login ซึ่งต้องใช้ฟีเจอร์ bypass cache on cookie แต่ว่ามันเป็น enterprise feature เลยไม่สามารถทำได้ ก็ต้องมองเป้าถัดไปว่าถ้าจะแก้ปัญหาที่ใหญ่ที่สุดนี้เราต้อง rearchitect แล้วในระหว่างนี้ก็ใช้วิธีคือเขียน firewall rule ปิดที่หน้าเสี่ยงสูงไว้ก่อน จะยอม false positive ก็ได้ขอให้อย่าให้ยิงหลุดเข้ามา

Gen 4 – Go Static!

วันก่อนไปลองเล่น Astro มา ตอนแรกก็อ่านไม่เข้าใจว่ามันทำอะไร แต่ก็พบว่าไอเดียมันตรงกับที่อยากได้มากๆ คือเว็บเป็น static generate แบบ Gatsby แต่ว่าเวลา rehydrate ไม่ได้ทำทั้งหน้า ทำเฉพาะส่วนที่จำเป็นต้องทำเท่านั้นทำให้ bundle size เล็กลง ก็เลยคิดว่างั้นเราจะ port เว็บเดิมแบบ 1-1 เลยจาก Django Template มาเป็น Astro + React

ข้อดีของการ port 1-1 เลยคือมัน rollback ง่ายเพราะหน้าเหมือนเดิม ไม่ต้องกลัวว่า ship feature ใหม่ไปแล้วลูกค้างง ใช้ๆ อยู่หายไป และไม่เกิด scope creep เท่าไรนักซึ่งเป็นปัญหาใน project redesign ที่ผ่านๆ มาแล้วไม่ได้ออกสักที

ปัญหาก็คือหน้าเว็บหลักมันเป็น Django ไปแล้ว ถ้าเราเอา frontend ไปไว้บน static hosting ก็ต้องย้ายไปเปิด subdomain ใหม่ซึ่งลำบากแน่นอนและทำให้เกิด CORS request เยอะ จะใช้ท่า strangler pattern ที่ proxy path เก่าเข้า API, path ใหม่เข้า frontend ก็จะติดปัญหาว่าถ้าโดนยิง DDoS origin ก็รับไม่ไหวอยู่ดี

ก็มองๆ ไปเห็น Cloudflare Workers ซึ่งมันรันที่ edge และ scale ได้ไม่จำกัด เลยตัดสินใจไปทางนั้น โดยที่หน้าเว็บ Astro จะทำงานบน Cloudflare Pages แล้วบน domain หลักมี Cloudflare Worker route ระหว่างเข้า origin กับเข้า pages แถมมันยังช่วยทำลายข้อจำกัด Astro อีกอย่างหนึ่งด้วยคือ URL ต้องเป็น static เท่านั้น โดยเราให้ Workers map URL หลายๆ อันเข้าที่ static URL อันเดียวได้

ในส่วนของหน้าเว็บก็จะช่วยให้ cache บางอย่างได้ดีขึ้นด้วย เช่นเว็บมีระบบประกาศทั้งเว็บ (site-wide announcement) เดิมทีเวลาแก้ไขประกาศต้อง purge cache ทั้งเว็บ แต่เนื่องจากเว็บเป็น static แล้วเลยต้อง rearchitect ให้ระบบประกาศเป็น API และ fetch จาก client side แทนทำให้ประกาศมีระยะเวลา cache ต่างจากของหน้าเว็บหลักได้

Client side is still the future

หลังๆ มาผมเริ่มเห็นกลุ่ม frontend กลับไปมองว่า web application มันไม่ควรจะ split frontend-backend แล้วเพราะ single page application มันโหลดช้า แล้วกลับไปสู่ยุคคลาสสิกว่าใช้ JavaScript ให้น้อยลงและเว็บทำงานต่อไปได้

ผมมองว่าเว็บ TipMe มัน hold out ผ่านยุค SPA มาได้นะ ถ้าแกะดูส่วน overlay ก็จะเห็นว่ามันเป็น island architecture มาตั้งแต่ launch ฟีเจอร์นี้หลายปีก่อนแล้ว แต่วันนี้ผมกลับมาพูดว่าทำเว็บแบบโบราณมันไม่ใช่อนาคตที่เราอยากได้ หนึ่งคือ interactivity ต่างๆ มันทำยาก เสียเวลากว่าทำใน client side เยอะเพราะต้องเก็บ intermediate state และสองคือมันยังเป็นท่าที่ cost effective มากกว่าโดยเฉพาะถ้าเว็บจะโดนยิงบ่อยๆ แบบ TipMe

ซึ่ง Island architecture ยุคใหม่กำลังมา และผมคิดว่าเราทำเว็บกึ่ง SPA ยุคใหม่มันทำให้เราได้ข้อดีทั้งสองข้อ โดยที่ฝั่ง user ไม่ได้ต้องรอโหลดเว็บนานๆ เหมือนสมัย SPA อีกแล้ว

Wall of Text #14: Information security for dev

อยากเขียนเรื่อง security บ้าง หลังๆ ทำงานกับ security team เยอะขึ้น แล้วรู้สึกว่าจริงๆ มันไม่ยากอย่างที่คิด

Threat

ตอนที่เรียน information security ชอบรูปนี้มาก รู้สึกว่าอธิบายได้ดี เคยเจอรูปต้นฉบับในเน็ต แต่เข้าใจว่าหนังสือมีลิขสิทธิ์เลยหายาก ก็เลยวาดให้ใหม่ใน Paint

Security มีองค์ประกอบอยู่ 3 อย่าง

  1. Threat (ภัยอันตราย) ในรูปก็คือน้ำจะท่วมแล้ว
  2. Vulnerability (จุดอ่อน) ในรูปก็คือ กำแพงกันน้ำมีรอยรั่ว
  3. Control (การควบคุม) ในรูปก็คือเอามือปิดรอยรั่วไว้

ถ้ากำแพงรั่วแล้วเอามือปิดไว้ ผลคือน้ำไม่ท่วม เท่ากับว่าบรรลุเป้าหมาย แปลว่ามี security แต่ถ้าเกิดน้ำสูงกว่ากำแพงก็สร้างปัญหาได้อยู่ดี

CIA Triad

Security จริงๆ แล้วมีสมบัติ 3 อย่างหลักๆ ซึ่งอาจจะซอยข้อย่อยได้อีก 3 อย่างหลักๆ นี้คือ

  1. Confidentiality (ลับ) คือคนที่จะเห็นข้อมูลได้ต้องเป็นคนที่ตั้งใจจะให้เห็นเท่านั้น
  2. Integrity (สมบูรณ์) คือข้อมูลถูกต้องครบถ้วน เช่น ถ้ามี hacker เข้ามาเปลี่ยนหน้าเว็บเป็น rickroll ถือว่าเสีย Integrity
  3. Availability (ใช้งานได้) เช่น โดนยิง DDoS คนเข้าใช้งานไม่ได้เลย ถึงจะไม่ทำให้ข้อมูลหลุดหรือโดนแก้ไขข้อมูลก็เป็นปัญหา security เหมือนกัน

ซึ่งก็มีมาตรการต่างๆ ที่ช่วยรักษาสมบัติพวกนี้ เช่น

  1. Confidentiality
    • Access control ไม่ให้คนที่ไม่อนุญาตเข้าถึงได้ เช่นระบบ user account, firewall
    • Encryption เข้าถึงได้แต่เปิดอ่านไม่ได้
    • Contract เซ็นสัญญาไม่เปิดเผยความลับ ก็ใช้ควบคุมได้ถ้าไม่ได้อยู่ในระบบคอมพิวเตอร์
    • Monitoring ตรวจจับว่ามีผู้บุกรุก
  2. Integrity
    • Checksum คือสามารถยืนยันได้ว่าข้อมูลถูกต้องครบถ้วน
    • Signing คือจำกัดให้ checksum สร้างได้จำกัดคน ป้องกัน hacker สร้าง checksum ใหม่
    • Backup
    • Access control จำกัดคนที่แก้ไขข้อมูลได้ก็ช่วยได้เช่นกัน
    • Monitoring ก็ช่วยได้อีกเช่นกัน
  3. Availability
    • Spare มีระบบสำรองกรณีระบบหลักมีปัญหา
    • Scale out มีหลายๆ ระบบทำงานพร้อมกันเพื่อลดคอขวดจากจุดเดียว
    • Monitoring ว่าระบบยังทำงานได้ปกติ ไม่มีการใช้งานผิดปกติ

Security assessment

ไม่แน่ใจว่าตำรา security จะเขียนแตกต่างจากนี้ไหม แต่โดยทั่วๆ ไปแล้วเวลาผมประเมินความเสี่ยงจาก security จะทำตามขั้นตอนนี้ ซึ่งจริงๆ ผมว่ามันจะคล้ายๆ กับการทำ Persona ของ UX

  1. Threat modeling พูดง่ายๆ คือ กลัวอะไรอยู่ หลักๆ ก็อาจจะเป็น
    • กลัวคนนอก (hacker)
    • กลัวคนใน (insider attack, data loss)
    • กลัว user อื่น (spammer)
    • กลัวแอพพลิเคชั่นอื่น (lateral movement)
    • กลัวโปรแกรมเมอร์คนอื่น (defensive coding)
    • ซึ่งเราอาจจะไม่ต้องกลัวทุกอย่างก็ได้ เช่นเว็บเล็กๆ มีทีมงานเห็นๆ กันอยู่ 2-3 คน โอกาสที่คนในจะเป็นหนอนอาจจะน้อยก็ไม่จำเป็นต้องทำเรื่อง insider attack
  2. Vulnerability – ลอง list ออกมาว่าเขาจะทำอะไรมิดีมิร้ายได้บ้าง ผมคิดว่า list ทั้งหมดน่าจะยาวมากไม่สามารถเขียนมาได้ ต้องใช้ประสบการณ์ที่จะเห็นแล้วพอนึกออกว่ามีข้อไหนบ้างที่ apply เช่น
    • คนนอกอาจจะ port scan, เอาช่องโหว่มา scan, ทำ SQL injection หรือ XSS, เดารหัสผ่าน หรือ credential stuffing
    • คนในที่มี admin อาจจะใช้อำนาจในทางที่ผิด เช่น โกรธแฟนเลยแอบดูข้อมูลการใช้งานของแฟน (insider attack) โดนหลอกให้ทำ (phishing) หรือขโมยข้อมูลไปให้คู่แข่ง (data loss)
    • user อาจจะส่ง spam หากันเอง
    • คนใน หรือ application ใน network โดนฝัง shell แล้ว scan หา application ภายในเพื่อ hack ต่อ (lateral movement)
    • โปรแกรมเมอร์คนอื่นที่มาเรียกฟังค์ชั่นนี้อาจจะส่ง parameter มาผิดวิธีแล้วทำให้เกิดช่องโหว่ เช่นเรียก sql query แต่ไม่ได้ escape quote
  3. Control เป็นส่วนสำคัญที่สุด ถ้าเรามี control เพียงพอจะ run Ubuntu 8.04 ใน production ก็ได้ ตัวอย่างของ control เช่น
    • ทำ input validation ถ้าเป็นค่าที่ไม่ถูกต้องไม่ให้ประมวลผล
    • อัพเดต Application ให้ล่าสุดเพื่อไม่ให้โดน hack จาก library ที่ไม่อัพเดต เช่น Log4shell, Apache Struts
    • แต่บางที vendor อาจจะยังออก patch ไม่ทัน ก็ต้องกันจากด้านนอกเช่นใช้ WAF SaaS เพื่อตรวจจับการยิง
    • แต่ WAF ก็ bypass ได้ อาจจะเพิ่ม firewall ไปอีกเพื่อจำกัด IP ที่เข้าใช้งานได้กรณีที่เป็นระบบปิด
    • เพิ่ม firewall ขาออกด้านในด้วยเพื่อที่ว่ายิงเข้ามาได้ก็อาจจะส่งข้อมูลออกไป internet ยาก และเข้าไปโจมตี application อื่นๆ ยาก
    • สุดท้ายเพิ่ม access log เพื่อที่ว่าถ้ามีคนทะลุทุกอย่างมาได้จริงยังสามารถจับมือคนดมได้

“Control ที่เพียงพอ” เป็นคำถามที่ตอบยากมากๆ เพราะระบบที่ปลอดภัย 100% ไม่มีจริง ยิ่งทำมากยิ่งเสียเวลา (diminishing return) และทำให้ใช้งานลำบากด้วย อีกส่วนหนึ่งคือมูลค่าของระบบที่จะปกป้องกับระบบรักษาความปลอดภัยควรจะเหมาะสมกัน เช่นถ้าเป็นเว็บ company profile ธรรมดาๆ การซื้อ WAF, L7 firewall มาติดตั้งอาจจะมูลค่าหลักแสนหรือหลักล้าน แต่ความเสียหายคือแค่ restore จาก backup ก็กลับมาใช้งานได้แล้ว แบบนี้ก็ถือว่า backup เป็น control ที่เพียงพอแล้ว

เวลาเขียนโค้ด โค้ดทุกบรรทัดต้องทำ security assessment แบบนี้เสมอ ซึ่งคนส่วนมากน่าจะคิดว่าโอเวอร์เกินไปแล้วไม่ทำเลย แต่ผมคิดว่าถ้ามีประสบการณ์ security มาบ้างจะเริ่มจับทางได้เหมือนเป็น code smell ประเภทหนึ่งว่าในจุดนี้ต้องเริ่มวิเคราะห์ threat modeling อย่างละเอียดแล้ว ทำให้ทำงานได้เร็วขึ้น เช่น

  • ทุกจุดที่ใช้ตัวแปรที่ user ป้อนเข้ามา (โดนแฮคได้หลายแบบ ตามด้านล่างนี้)
  • โค้ดเกี่ยวกับ password (ตรวจดูว่า hash รหัสด้วยอัลกอริธึมและพารามิเตอร์ที่เหมาะสม และเปรียบเทียบรหัสผ่านโดยใช้เวลาคงที่ (constant time comparison))
  • โค้ดที่เกี่ยวกับวิทยาการรหัสลับ (ไม่แนะนำให้ใช้ algorithm โดยตรง ควรจะใช้ use case based library)
  • โค้ดที่ยิง URL แล้ว user กำหนดค่าเองได้ (อาจสุ่มเสี่ยง SSRF หรือ logic ในการ parse กับ validate ไม่ตรงกัน)
  • โค้ดที่รันสคริปต์ที่ user ส่งเข้ามา (ควรจะทำ sandbox ให้เหมาะสม)
  • โค้ดที่ใช้ตรวจสอบข้อมูล (data validation)
  • โค้ดที่จัดการข้อมูลขนาดใหญ่ในครั้งเดียว (ระวังไม่ให้ user ใช้งาน memory หรือ disk ใหญ่เกินไป)

Defense in Depth

ในอุตสาหกรรมการบินจะมีการใช้ Swiss cheese model

By BenAveling – Own work, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=91881875

โมเดลนี้ใช้แนวคิดว่าเราไม่สามารถป้องกันความเสี่ยงได้ 100% ถ้าไม่อยากให้ชีสมีรูทะลุไปอีกฝั่ง การมีชีสเรียงกันหลายๆ ชั้นก็ลดโอกาสที่ชีสทุกแผ่นจะมีรูเดียวกันหมดได้ ในฝั่ง security มักจะเรียกว่า defense in depth

Not security

บางอย่างไม่ทำให้เกิด security

Security theater

เล่นละครไม่ทำให้เกิด security

เช่น นโยบายบอกว่าต้องตรวจสัมภาระก่อนเข้าสู่สถานที่ แต่คนตรวจเปิดอยู่ช่องเดียวแล้วส่องไฟผ่านๆ แบบนี้ไม่เกิดความปลอดภัย

Security is not a product

คนที่ไม่เข้าใจ security มักจะโดนเซลเป่าหูให้ซื้อ security product แต่ไม่ทำให้เกิด security จริง เปรียบเสมือนเช่ายันต์และห้อยพระเครื่องไว้ที่ server ให้อึด ถึก ทน ยิงไม่เข้า (ถ้า product มันเหนียวจริง ซื้อมาแล้วโดนแฮคควรจะฟ้องร้อง vendor ให้ใช้ค่าเสียหายได้)

การซื้อ product อาจจะช่วยเพิ่ม security ได้จริง แต่ก็ต้องกลับไปมองที่ security assessment ว่าสิ่งที่ซื้อมา ซื้อเพราะกลัวอะไร ซื้อแล้วมันได้ผลจริงกี่ % ซึ่งมันไม่ใช่ 100% แน่ๆ ต้องมีแผนให้ชัดเจนว่า control ต้องเพิ่มอะไรอีกบ้างจึงจะเพียงพอ

Security is not a feature

Project manager ที่ไม่เข้าใจ security อาจคิดว่า security เป็น feature หนึ่งแล้วก็แยกเป็น ticket low priority ทำทีหลัง

ผ่านไป 1 ปีก็ยังไม่ได้ทำจนกระทั่งโดน hack แล้วบอกว่าลูกค้าด่าต้องทำให้เสร็จภายใน 1 สัปดาห์

ในความเป็นจริงแล้ว security เป็นส่วนหนึ่งของทุกๆ feature การ “เติม” security เข้าไปภายหลังสร้าง technical debt ได้รวดเร็วมากเพราะมันมักจะส่งผลต่อ design และการแก้ design flaw เป็นเรื่องยาก ใช้เวลานาน

Security by obscurity

Security ที่แท้จริงถ้าเฉลยกลให้ทั้งหมดแต่ไม่บอกรหัสลับก็ไม่สามารถผ่านเข้ามาได้ เช่นวิธีเข้ารหัส AES นั้นเป็นข้อมูลเปิดเผยหาอ่านได้ทั่วไป ถึงอย่างนั้นถ้าไม่บอกกุญแจเข้ารหัสปัจจุบันยังไม่มีใครถอดรหัสข้อความใดๆ ได้

โบราณว่า ทองแท้ไม่แพ้ไฟ

มีบางคนคิดว่า AES เป็นข้อมูลเปิดเผย มี paper มากมายที่ลดความปลอดภัยของ AES ถ้าอย่างนั้นเราออกแบบ algorithm ขึ้นมาเองเฉพาะภายในบริษัทแล้วก็เป็น algorithm ที่มีความปลอดภัยสูงสุด ไม่เคยมีผู้ใดในโลกถอดรหัสได้โดยไม่ต้องรู้กุญแจ

ผ่านไป 6 เดือน hacker reverse engineer โปรแกรมมาดูแล้วพบว่าเป็น XOR กับ hardcode key ธรรมดาๆ แล้วก็เอา key ไปแจกในเน็ต

People is the weakest link

xkcd 538

Cargo cult security

“อาจารย์บอกมา” ไม่ใช่ security ที่ดีเสมอไป เช่น

  • อาจารย์ให้ config มา ตั้งตามแบบนี้แล้วเหนียว ยิงไม่เข้า แต่พอใช้แล้ว CEO โดนบล็อกทำงานไม่ได้
  • อาจารย์สอนให้ต้องมี CSP header แล้วจะป้องกันการแฮคได้ แต่เปิด unsafe-eval ไว้เพราะ marketing จะใช้ Google Tag Manager
  • อาจารย์สอนวิธี encrypt รหัสผ่านด้วย MD5 แล้วทำให้รหัสผ่านปลอดภัย แฮคไม่ได้
  • ซื้อ Tool scan มา scan เจอ 500 ข้อ พอแก้ตามที่ tool แนะนำแล้ว application ใช้งานไม่ได้
  • ซื้อ Tool scan มา scan ก่อน release application ปรากฏว่าจะแก้ให้ผ่านเป็น breaking change ส่งมอบงานไม่ทันเวลา
  • ซื้อ Tool scan ช่องโหว่ 10 อันดับยอดนิยมมา scan แล้วไม่เจอสักรายการที่ต้องแก้ไขแสดงว่าปลอดภัย แต่โดน hack ด้วยช่องโหว่ยอดนิยมอันดับที่ 11

เขาว่ายอด consult จะบอกว่า It depends ซึ่ง security ก็เช่นกัน “อาจารย์บอกมา” อาจจะไม่ได้ผิด แต่ไม่สามารถคำนึงถึง It depends ได้ ต้องมีความเข้าใจที่ถูกต้องว่าทำไมอาจารย์ถึงบอกมา