• auth

PKCE คืออะไร: จากแนวคิดพื้นฐานถึงการเข้าใจอย่างลึกซึ้ง

บทความนี้อธิบายว่า PKCE (Proof Key for Code Exchange) ช่วยป้องกันการไหลของโค้ดการอนุญาต OAuth 2.0 โดยการป้องกันแอปพลิเคชันที่ประสงค์ร้ายนำโค้ดการอนุญาตไปได้อย่างไร พาคุณจากแนวคิดพื้นฐานไปสู่การเข้าใจอย่างถ่องแท้

Yijun
Yijun
Developer

Proof Key for Code Exchange (PKCE) เป็นส่วนขยายของ Authorization Code flow โดยเริ่มต้นออกแบบเพื่อความปลอดภัยในการไหลของโค้ดการอนุญาตในแอปมือถือ และตอนนี้แนะนำให้ใช้โดยแอปหน้าเดียวด้วย ตั้งแต่ OAuth 2.1 PKCE ถูกบังคับใช้สำหรับลูกค้าทุกประเภท รวมถึง ลูกค้าสาธารณะ และ ลูกค้าส่วนตัว (private).

ในบทความนี้ เราจะช่วยให้คุณเข้าใจว่าทำไม PKCE ถึงถูกสร้างขึ้นมาและมันปกป้องแอปพลิเคชันของคุณได้อย่างไร พร้อมกับทำให้คุณได้รับความเข้าใจอย่างลึกซึ้งเกี่ยวกับ PKCE.

ทำไมถึงต้องการ PKCE?

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

การไหลนี้มีความเสี่ยงด้านความปลอดภัยอย่างมาก: โค้ดการอนุญาตสามารถถูกแทรกแซงโดยโปรแกรมที่ประสงค์ร้ายได้ นี่เป็นข้อกังวลโดยเฉพาะบนอุปกรณ์มือถือ ที่แอปพลิเคชันอื่นๆ อาจลงทะเบียน URI การเปลี่ยนเส้นทางเดียวกันและขัดโค้ดการอนุญาตได้

กระบวนการดักจับจะแสดงในแผนภาพด้านล่าง:

ขั้นที่ (1): แอปทำคำขอการยืนยันผ่าน API ที่ปลอดภัยและไม่สามารถถูกจับได้ ในขั้นตอนนี้ ผู้ขอยังให้ URI การเปลี่ยนเส้นทางด้วย

ขั้นที่ (2): คำขอจะถูกส่งต่อไปยังเซิร์ฟเวอร์การอนุญาต OAuth 2.0 เนื่องจาก OAuth ต้องใช้ TLS การสื่อสารนี้จึงได้รับการปกป้องด้วย TLS และไม่สามารถถูกดักจับได้

ขั้นที่ (3): เซิร์ฟเวอร์การอนุญาตจะส่งคืนโค้ดการอนุญาต

ขั้น (4.a): โค้ดการอนุญาตจะถูกส่งคืนให้ผู้ขอผ่าน URI การเปลี่ยนเส้นทางที่ได้ให้ไว้ในขั้นที่ (1) ในขั้นตอนนี้หากแอปที่ประสงค์ร้ายได้ลงทะเบียนเป็นผู้จัดการสำหรับ URI การเปลี่ยนเส้นทางแล้ว แอปที่ประสงค์ร้ายสามารถขัดโค้ดการอนุญาตได้ ด้วยโค้ดการอนุญาตนี้ ผู้โจมตีสามารถร้องขอและรับโทเค็นการเข้าถึงในขั้นที่ (5.a) และ (6.a) ตามลำดับ

ดังที่แสดงด้านบน ในการไหลของโค้ดการอนุญาต OAuth 2.0 ถ้าโค้ดการอนุญาตถูกขัดขวาง ผู้โจมตีสามารถใช้มันเพื่อรับโทเค็นการเข้าถึงได้ ดังนั้นเราจำเป็นต้องมีกลไกเพื่อป้องกันการขัดขวางโค้ดการอนุญาต ซึ่งนำไปสู่การสร้าง PKCE.

PKCE ทำงานอย่างไร?

ตามที่กล่าวไว้ข้างต้นหากเราต้องการป้องกันการโจมตีเราจำเป็นต้องมั่นใจว่าแอปที่ทำคำร้องขอเท่านั้นสามารถร้องขอและรับโทเค็นการเข้าถึงได้ ตรงนี้คือที่ที่ PKCE เข้ามามีส่วนร่วม

PKCE แก้ปัญหานี้ด้วยการแนะนำแนวคิด "key key"

เมื่อล้างโค้ดการอนุญาต แอปจะสร้างการยืนยันลำดับแบบสุ่มและเก็บไว้ในเครื่องก่อน จากนั้นจะแปลงโค้ดยืนยันนี้เป็นการท้าทายโค้ดโดยใช้อัลกอริทึมที่เหมาะสม แอปจะส่งทั้งการท้าทายโค้ดและวิธีการท้าทายโค้ดไปยังเซิร์ฟเวอร์การยืนยันระหว่างที่ขอโค้ดการยืนยัน

โค้ดยืนยันคือลำดับที่สร้างขึ้นสุ่ม และการท้าทายโค้ดคือการได้จากการแปลงโค้ดยืนยันผ่านการแปลง มีสองวิธีการการแปลงที่สนับสนุน:

  • plain: ใช้โค้ดยืนยันโดยตรงเป็นการท้าทายโค้ด
  • S256: ใช้การแฮช SHA-256 กับโค้ดยืนยัน ตามด้วยการเข้ารหัส Base64URL เนื่องจากผลลัพธ์ของการแฮชไม่สามารถกลับกันเพื่อรับโค้ดยืนยันได้ และเนื่องจากวิธีการ plain อาจถูกโจมตีจากคนกลางในระหว่างการส่งเพื่อความปลอดภัย แนะนำให้ใช้ S256 เป็นอย่างยิ่ง

หลังการยืนยันของผู้ใช้ เซิร์ฟเวอร์การยืนยันจะส่งคืนโค้ดการยืนยันให้แอปพลิเคชัน เมื่อขอรับโทเค็นการเข้าถึง แอปพลิเคชันจะส่งทั้งโค้ดการยืนยันและโค้ดยืนยันไปยังเซิร์ฟเวอร์การยืนยัน เซิร์ฟเวอร์จะเปลี่ยน "โค้ดยืนยัน" โดยใช้ "วิธีการท้าทายโค้ด" ที่ได้รับมาก่อนหน้านี้และเปรียบเทียบผลลัพธ์กับ "การท้าทายโค้ด" ที่ได้รับมาก่อนหน้านี้เพื่อยืนยันว่าลูกค้ามี "โค้ดยืนยัน"

ขั้นตอนที่ (1-3): แอปสร้างและบันทึกลับที่ชื่อว่า "โค้ดยืนยัน" และได้เวอร์ชันแปลง "โค้ดการท้าทาย" ที่ส่งมาในคำขอการยืนยัน OAuth 2.0 พร้อมวิธีการแปลง "โค้ดการท้าทาย"

ขั้นตอนที่ (3-6): เซิร์ฟเวอร์การยืนยันตอบกลับตามปกติแต่บันทึก "การท้าทายโค้ด" และ "วิธีการท้าทายโค้ด"

ขั้นตอนที่ (7.a): แอปจะส่งโค้ดยืนยันไปยังจุดสิ้นสุดของโทเค็นตามปกติแต่รวม "โค้ดยืนยัน" ลับที่สร้างขึ้นในขั้นที่ (1)

ขั้นตอนที่ (8.a-9.a): เซิร์ฟเวอร์การยืนยันจะแปลง "โค้ดยืนยัน" เป็น "โค้ดการท้าทาย" และเปรียบเทียบกับ "โค้ดการท้าทาย" จากขั้นที่ (1-3) ข้อความการเข้าถึงจะถูกปฏิเสธหากไม่เท่ากัน

ในกรณีนี้แม้ว่าแอปประสงค์ร้ายจะขัดขวางโค้ดการอนุญาตที่ขั้นที่ (6.b) แต่ไม่สามารถแลกเป็นโทเค็นการเข้าถึงได้ เนื่องจากไม่ได้ถือครองลับ "โค้ดยืนยัน" และเนื่องจาก "โค้ดยืนยัน" ถูกส่งผ่าน TLS ไม่สามารถถูกขัดได้

สรุป

บทความนี้อธิบายว่า PKCE ทำงานอย่างไรและทำไมจึงจำเป็นสำหรับการปกป้องการไหลของโค้ดการอนุญาต โดยการเพิ่มกลไกการพิสูจน์ PKCE ป้องกันแอปพลิเคชันประสงค์ร้ายจากการขัดขวางและใช้โค้ดการอนุญาต หวังว่าการอธิบายนี้จะช่วยให้คุณเข้าใจ PKCE อย่างลึกซึ้ง