PlusMagi's Blog By Pitt Phunsanit Cybersecurity,Database Shellshock (หรือ Bashdoor)

Shellshock (หรือ Bashdoor)

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

แม้ว่า Shellshock จะเป็นช่องโหว่ที่โด่งดังใน Bash Shell แต่แก่นแท้ของปัญหาคือการที่ระบบอนุญาตให้มีการรับข้อมูลจากภายนอก (External Input) และนำไปรันผ่าน Command Line Interface (CLI) โดยไม่มีการตรวจสอบที่เหมาะสม ซึ่งหากข้อมูลเหล่านั้นถูกตีความว่าเป็นชุดคำสั่งแทนที่จะเป็นแค่ข้อความธรรมดา ผู้โจมตีก็สามารถแทรกคำสั่งอันตรายเข้าไปในระบบได้

กลไกของ Command Injection ในบริบทของ PostgreSQL

ใน PostgreSQL การโจมตีลักษณะนี้มักเกิดขึ้นเมื่อมีการใช้ฟังก์ชันที่อนุญาตให้เรียกใช้ OS commands เช่น การใช้ COPY FROM PROGRAM หรือการเขียน Stored Procedure ที่เรียกใช้ EXECUTE โดยที่พารามิเตอร์ที่ส่งเข้าไปไม่ได้ถูก Sanitization อย่างเคร่งครัด

หากผู้โจมตีสามารถป้อนค่าที่ประกอบด้วยคำสั่ง OS (เช่น '; rm -rf /; --) เข้าไปในพารามิเตอร์เหล่านี้ได้ ระบบจะตีความว่านี่คือคำสั่งที่ต้องรันจริง ๆ ทำให้เกิดการรันโค้ดที่ไม่ได้ตั้งใจให้ทำงานขึ้นมา ซึ่งเปรียบเสมือนการที่ผู้โจมตีฉีดคำสั่งเข้าไปในกระบวนการทำงานปกติของฐานข้อมูล

ตัวอย่างแนวคิดความเสี่ยง (Conceptual Risk Example)

สมมติว่าเรามีฟังก์ชันที่รับชื่อไฟล์จากภายนอกเพื่อทำการประมวลผล:

SQL

-- ฟังก์ชันที่รับ input ที่ไม่ปลอดภัย (Unsafe Function) --
CREATE OR REPLACE FUNCTION process_file(input_filename text) RETURNS text AS $$
BEGIN
    -- หาก input_filename มาจากผู้ใช้โดยตรง
    RETURN pg_catalog.pg_read_file(input_filename); 
END;$$ LANGUAGE plpgsql; 

-- ผู้โจมตีสามารถป้อน input ที่เป็นคำสั่ง OS ได้
SELECT process_file('dummy.txt; ls -la /etc/');

ในตัวอย่างนี้ หาก PostgreSQL อนุญาตให้มีการรันคำสั่ง OS ต่อท้าย (เช่น ls -la /etc/) โดยที่ไม่ได้ตรวจสอบขอบเขตของ input อย่างเข้มงวด นั่นคือช่องโหว่ที่ร้ายแรง

แนวทางแก้ไขและหลักการป้องกัน (Architectural Mitigation)

ในฐานะ Senior Architect การป้องกันช่องโหว่ Command Injection ต้องใช้แนวทางแบบ Defense-in-Depth:

  1. การใช้ Parameterized Queries เสมอ: ห้ามนำค่า Input ที่มาจากผู้ใช้ไปรวมเป็นส่วนหนึ่งของคำสั่ง SQL หรือคำสั่ง OS โดยตรง ต้องใช้ Parameterized Queries เสมอ เพื่อให้ระบบจัดการข้อมูลเหล่านั้นในฐานะ ‘ข้อมูล’ ไม่ใช่ ‘คำสั่ง’
  2. หลักการสิทธิ์น้อยที่สุด (Principle of Least Privilege): กำหนดสิทธิ์ให้ผู้ใช้งาน (User Role) หรือฟังก์ชันที่รันคำสั่ง OS มีสิทธิ์ในการเข้าถึงทรัพยากรภายนอก (เช่น ระบบไฟล์ หรือเครือข่าย) เท่าที่จำเป็นต่อการทำงานเท่านั้น ห้ามให้สิทธิ์ Root หรือ Superuser ในการรันฟังก์ชันเหล่านี้
  3. การตรวจสอบ Input (Input Validation): ต้องมีการตรวจสอบความยาว รูปแบบ และอักขระที่อนุญาต (Whitelist) ของทุก Input ที่มาจากภายนอกอย่างเคร่งครัด เพื่อป้องกันการแทรกอักขระพิเศษ (เช่น ;, &, |)

บทสรุป

ช่องโหว่ Command Injection ไม่ว่าจะอยู่ใน Bash Shell หรือในฟังก์ชันของ PostgreSQL ล้วนมีรากฐานมาจากปัญหาเดียวกันคือ ‘ความเชื่อใจ’ ในข้อมูลที่มาจากภายนอก การป้องกันที่ดีที่สุดคือการออกแบบระบบที่แยกขอบเขตระหว่าง ‘ข้อมูล’ และ ‘คำสั่ง’ อย่างชัดเจน ทำให้แม้ว่าจะมีช่องโหว่เกิดขึ้น ก็จะไม่สามารถนำไปสู่การควบคุมระบบทั้งหมดได้