PlusMagi's Blog By Pitt Phunsanit Backend,Cybersecurity,Database PHP: การป้องกันการโจมตีแบบ Timing Attack ด้วย hash_equals()

PHP: การป้องกันการโจมตีแบบ Timing Attack ด้วย hash_equals()

ในฐานะ System Specialist และ Senior Architect การจัดการข้อมูลลับ (Secrets) เช่น รหัสผ่าน, โทเคน (Tokens), หรือค่า HMAC ถือเป็นหัวใจสำคัญของความมั่นคงปลอดภัยของระบบ เมื่อเราทำการตรวจสอบความถูกต้องของข้อมูลเหล่านี้ การเปรียบเทียบสตริง (String Comparison) จึงเป็นขั้นตอนพื้นฐานที่ขาดไม่ได้

อย่างไรก็ตาม การใช้ฟังก์ชันการเปรียบเทียบแบบมาตรฐานทั่วไป เช่น การใช้ตัวดำเนินการเท่ากับ (==) หรือฟังก์ชันเปรียบเทียบสตริงแบบดั้งเดิม อาจเปิดช่องโหว่ร้ายแรงที่เรียกว่า Timing Attack ได้

🔍 Timing Attack คืออะไร และทำไมถึงอันตราย?

Timing Attack คือรูปแบบการโจมตีทางด้านความปลอดภัยที่ไม่ได้พยายามเดาค่าลับโดยตรง แต่เป็นการวัดเวลา (Time Measurement) ที่ระบบใช้ในการประมวลผลการเปรียบเทียบข้อมูล

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

🛡️ หลักการป้องกัน: Constant-Time Comparison

เพื่อป้องกัน Timing Attack เราต้องใช้หลักการที่เรียกว่า Constant-Time Comparison (การเปรียบเทียบเวลาคงที่) ซึ่งหมายความว่า ไม่ว่าสตริงสองตัวจะแตกต่างกันแค่ไบต์แรก หรือแตกต่างกันแค่ไบต์สุดท้าย ฟังก์ชันการเปรียบเทียบจะต้องถูกออกแบบให้ใช้เวลาในการประมวลผลเท่ากันเสมอ โดยไม่ขึ้นอยู่กับตำแหน่งที่เกิดความผิดพลาด (Mismatch)

ในภาษา PHP มาตรฐาน การป้องกันนี้ทำได้โดยใช้ฟังก์ชัน hash_equals() ซึ่งเป็นฟังก์ชันที่รับประกันการทำงานแบบ Constant-Time เพื่อเปรียบเทียบค่าแฮชหรือโทเคน

💡 การประยุกต์ใช้แนวคิดใน PostgreSQL

แม้ว่า hash_equals() จะเป็นฟังก์ชันเฉพาะของ PHP แต่หลักการ Constant-Time Comparison นี้เป็นหลักการทางสถาปัตยกรรมที่สำคัญที่นักพัฒนาต้องทราบ เมื่อเราทำงานกับ PostgreSQL ในการตรวจสอบความถูกต้องของค่าแฮช (เช่น ค่าที่ได้จาก SHA-256) เราต้องมั่นใจว่ากระบวนการเปรียบเทียบค่าเหล่านี้ถูกจัดการอย่างปลอดภัยที่สุด

ในทางปฏิบัติของ PostgreSQL เราจะใช้ฟังก์ชันแฮชที่เหมาะสม และเมื่อมีการเปรียบเทียบค่าแฮชที่ได้มา ควรใช้กลไกที่ป้องกันการรั่วไหลของเวลา (Timing Leakage) ซึ่งโดยทั่วไปแล้ว การใช้ฟังก์ชันแฮชมาตรฐานของ PG ร่วมกับการเปรียบเทียบที่ถูกออกแบบมาอย่างระมัดระวังจะช่วยลดความเสี่ยงนี้ได้

SQL

-- ตัวอย่างการเปรียบเทียบค่าแฮชที่ควรทำอย่างระมัดระวัง (Concept) --
-- สมมติว่า 'hashed_token' คือค่าแฮชที่เก็บในฐานข้อมูล
-- และ 'input_token' คือค่าแฮชที่ได้จากการคำนวณในแอปพลิเคชัน

SELECT
    CASE
        WHEN input_token = hashed_token THEN 'Success: Tokens Match'
        ELSE 'Failure: Tokens Mismatch'
    END AS comparison_result
FROM
    user_credentials
WHERE
    user_id = 1
    AND input_token = hashed_token; -- การใช้ WHERE Clause เพื่อเปรียบเทียบค่าแฮชที่คำนวณแล้ว

✅ บทสรุปสำหรับสถาปนิกระบบ

การป้องกัน Timing Attack ไม่ใช่แค่การใช้ฟังก์ชันสำเร็จรูป แต่คือการทำความเข้าใจหลักการ Constant-Time Comparison และนำไปปรับใช้ในทุกส่วนที่เกี่ยวข้องกับการตรวจสอบข้อมูลลับ ไม่ว่าคุณจะใช้ PHP, Python, หรือ PostgreSQL สิ่งสำคัญคือการให้ความสำคัญกับความปลอดภัยในระดับการเปรียบเทียบข้อมูลเสมอ เพื่อให้มั่นใจว่าแอปพลิเคชันของคุณมีความแข็งแกร่งทางด้านความปลอดภัยในระดับ Senior Architect