PlusMagi's Blog By Pitt Phunsanit Backend,Cybersecurity CGI Security Best Practices (การป้องกัน Shell Injection, การตั้งสิทธิ์ File Permissions และ Suexec บน CGI)

CGI Security Best Practices (การป้องกัน Shell Injection, การตั้งสิทธิ์ File Permissions และ Suexec บน CGI)

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

บทความนี้จะเจาะลึกถึงหลักการป้องกันช่องโหว่หลัก 3 ส่วน ได้แก่ Shell Injection, การจัดการสิทธิ์ไฟล์ (File Permissions) และการจำกัดขอบเขตคำสั่ง (Least Privilege) โดยเน้นการประยุกต์ใช้หลักการเหล่านี้ในสภาพแวดล้อมของ PostgreSQL

🛡️ 1. การป้องกัน Shell Injection และ SQL Injection

ภัยคุกคามที่ร้ายแรงที่สุดอย่างหนึ่งคือ Shell Injection ซึ่งเกิดขึ้นเมื่อแอปพลิเคชันส่งข้อมูลที่มาจากผู้ใช้โดยตรงไปยังระบบปฏิบัติการ (OS) ผ่านคำสั่งเชลล์ โดยไม่ได้ทำการกรองหรือตรวจสอบอินพุตเหล่านั้น ผู้โจมตีสามารถแทรกโค้ดคำสั่งของ OS เข้าไปได้

ในบริบทของ PostgreSQL การป้องกันที่ใกล้เคียงและสำคัญที่สุดคือการป้องกัน SQL Injection ซึ่งต้องยึดหลักการสำคัญคือ ห้ามนำค่าอินพุตของผู้ใช้มาต่อสตริงคำสั่ง SQL โดยตรง แต่ต้องใช้กลไกที่เรียกว่า Parameterized Queries เสมอ

🔑 ตัวอย่างการป้องกันด้วย Parameterized Queries ใน PostgreSQL

แทนที่จะสร้างคำสั่ง SQL ด้วยการเชื่อมสตริง (String Concatenation) ซึ่งเสี่ยงต่อการถูกแทรกโค้ด เราควรใช้ตัวแปร Placeholder (เช่น $1, $2) เพื่อให้ PostgreSQL จัดการการแยกแยะระหว่างคำสั่ง SQL และข้อมูลที่ผู้ใช้ป้อนเข้ามาอย่างถูกต้อง

SQL

-- ❌ ตัวอย่างที่ไม่ปลอดภัย (Vulnerable Code - ห้ามใช้) --
-- SELECT * FROM users WHERE username = ' ' || user_input; 

-- ✅ ตัวอย่างที่ปลอดภัย (Secure Code - ใช้ Parameterized Queries) --
SELECT * FROM products WHERE product_id = $1;

-- การเรียกใช้คำสั่ง (ในโค้ดแอปพลิเคชัน): 
-- SELECT * FROM products WHERE product_id = $1 USING '1,2,3';

🔒 2. หลักการ Least Privilege (การให้สิทธิ์น้อยที่สุด)

ไม่ว่าจะเป็นการตั้งสิทธิ์ไฟล์ (File Permissions) หรือสิทธิ์การเข้าถึงฐานข้อมูล เราต้องยึดหลักการ Least Privilege เสมอ นั่นคือการให้สิทธิ์แก่ไฟล์ ผู้ใช้งาน หรือสคริปต์เฉพาะเท่าที่จำเป็นต่อการทำงานเท่านั้น

⚙️ การจำกัดสิทธิ์ใน PostgreSQL

  • User Roles: สร้าง User Role ที่มีสิทธิ์เฉพาะในการอ่าน/เขียนข้อมูลที่จำเป็นเท่านั้น ห้ามใช้ Superuser สำหรับการเชื่อมต่อจาก CGI โดยเด็ดขาด
  • Schema Separation: แยกข้อมูลและฟังก์ชันที่เกี่ยวข้องออกจากกันใน Schema ต่างๆ และกำหนดสิทธิ์การเข้าถึงในระดับ Schema
  • Function Restriction: หากจำเป็นต้องรันคำสั่งที่ซับซ้อน ควรจำกัดการใช้ภาษา Procedural Language ที่สามารถเชื่อมต่อกับ OS ได้ (เช่น PL/Python) ให้เฉพาะผู้ใช้ที่เชื่อถือได้เท่านั้น

💡 3. การจำกัดขอบเขตคำสั่ง (Analogous to Suexec)

ในระดับระบบปฏิบัติการ มีการใช้กลไกอย่าง Suexec เพื่อจำกัดขอบเขตคำสั่งที่รันได้ ในระดับ PostgreSQL เราสามารถจำลองหลักการนี้ได้โดยการจำกัดความสามารถของ Database Role ไม่ให้เข้าถึงฟังก์ชันหรือตารางที่อยู่นอกขอบเขตการทำงานของแอปพลิเคชันนั้นๆ

การจำกัดสิทธิ์นี้ช่วยลดความเสียหาย (Damage Scope) หากเกิดการโจมตีสำเร็จ ทำให้แม้ผู้โจมตีจะแฮ็กเข้าสู่ระบบได้ ก็ไม่สามารถขยับขยายการโจมตีไปยังส่วนอื่นๆ ขององค์กรได้

✅ บทสรุป

ความมั่นคงปลอดภัยของ CGI ไม่ใช่การแก้ไขช่องโหว่เพียงจุดเดียว แต่คือการสร้างแนวป้องกันหลายชั้น (Defense in Depth) ตั้งแต่การใช้ Parameterized Queries ในระดับโค้ด, การจำกัดสิทธิ์ผู้ใช้งานในระดับฐานข้อมูล, ไปจนถึงการกำหนดสิทธิ์การเข้าถึงไฟล์และทรัพยากรภายนอก การทำความเข้าใจและปฏิบัติตามหลักการเหล่านี้อย่างเคร่งครัด จะช่วยยกระดับความปลอดภัยของเว็บแอปพลิเคชันของคุณได้อย่างยั่งยืน

Exit mobile version