บทที่ 5 · Part 2 — Identity & Web Security
Identity & Authentication
Identity lifecycle, password policy, credential stuffing, account enumeration, rate limiting และ authentication telemetry ตามแนวทางปัจจุบัน
หน้า login อาจไม่มี SQL injection และเก็บ password ด้วย Argon2id อย่างถูกต้อง แต่ attacker ยังยึดบัญชีจำนวนมากได้ด้วย email/password ที่รั่วจากบริการอื่น ปัญหานี้ไม่ใช่การถอด hash แต่เป็นการที่ระบบยอมรับ credential ที่ถูกต้องโดยไม่รู้ว่าผู้ใช้ตัวจริงเป็นผู้ส่งหรือไม่
Authentication จึงต้องออกแบบเป็น lifecycle ตั้งแต่สร้าง identity, ผูก authenticator, ตรวจความเสี่ยง, เปลี่ยน credential ไปจนถึง disable account ไม่ใช่ตรวจ password เพียงครั้งเดียว
Learning Outcomes
- แยก identity proofing, identification, authentication และ authorization ได้
- ออกแบบ identity lifecycle และ identifier โดยไม่ผูกกับข้อมูลที่เปลี่ยนง่าย
- กำหนด password policy ตามแนวทางปัจจุบันและเก็บ password อย่างปลอดภัย
- ลด brute force, credential stuffing และ account enumeration ได้
- ออกแบบ authentication event, reauthentication และ credential-change flow ได้
แยกคำที่มักถูกใช้ปนกัน
| Concept | คำถาม | ตัวอย่าง |
|---|---|---|
| Identity proofing | บุคคลนี้เป็นใครในโลกจริง | ตรวจหลักฐานตาม KYC process |
| Identification | identity ใดกำลังขอเข้าใช้ | username หรือ internal subject ID |
| Authentication | พิสูจน์การควบคุม authenticator ได้หรือไม่ | password + passkey |
| Federation | เชื่อ assertion จาก identity provider ใด | workforce login ผ่าน enterprise IdP |
| Authorization | identity นี้ทำ action นี้กับ resource นี้ได้หรือไม่ | อ่าน statement ของ wallet ที่เป็นเจ้าของ |
| Session management | รักษาผล authentication ระหว่าง request อย่างไร | opaque session cookie |
KYC ที่ยืนยันตัวบุคคลตอนเปิดบัญชีไม่พิสูจน์ว่าคนที่กำลัง login วันนี้คือคนเดิม และ login สำเร็จ ไม่อนุญาตให้ทำทุก operation Authorization ต้องตรวจทุก request แยกจาก Authentication
ออกแบบ Identity Lifecycle
แต่ละ transition เป็น sensitive event:
- ใครเริ่มและใช้ assurance ระดับใด
- ต้อง reauthenticate หรือใช้ช่องทางอิสระหรือไม่
- session/credential เก่าถูก revoke แบบใด
- แจ้งเจ้าของบัญชีผ่านช่องทางใด
- มี cooling period หรือ manual review สำหรับ high-risk change หรือไม่
- audit ระบุ actor, event, outcome และเหตุผลได้หรือไม่
ใช้ Stable Internal Subject ID
email, เบอร์โทร, เลขเอกสาร และ username อาจเปลี่ยน, recycle หรือมี privacy impact ระบบควรมี opaque internal subject ID ที่ไม่เปลี่ยนตาม login identifier และเก็บ mapping ภายใต้ authorization ที่เหมาะสม
ข้อควรระวัง:
- อย่าใช้ email เป็น tenant key หรือ ownership boundary
- normalize identifier อย่างสม่ำเสมอก่อนตรวจ uniqueness
- กำหนด policy เมื่อ email/phone ถูกเปลี่ยนหรือถูก provider recycle
- อย่าเปิดเผยว่ามี account ใดผ่าน public response โดยไม่จำเป็น
- Workflow ID, URL และ log ไม่ควรฝังข้อมูลส่วนบุคคลโดยไม่มีเหตุผล
Password Policy ที่ไม่ผลักให้เกิดพฤติกรรมแย่
แนวทาง NIST SP 800-63B-4 ปัจจุบันเปลี่ยนจากกฎเก่าแบบ “ตัวพิมพ์ใหญ่ 1 ตัว เลข 1 ตัว และเปลี่ยนทุก 90 วัน”:
- password ที่เป็น single factor ต้องยาวอย่างน้อย 15 characters
- password ที่เป็นส่วนหนึ่งของ MFA อาจใช้ขั้นต่ำ 8 characters
- ต้องรองรับความยาวอย่างน้อย 64 characters
- ไม่ควรบังคับ composition rule แบบหลายชนิดอักขระ
- ไม่บังคับเปลี่ยนตามรอบโดยไม่มีหลักฐาน compromise
- ตรวจ blocklist ของค่าที่พบบ่อย, คาดเดาง่าย หรือรั่วแล้ว
- รองรับ password manager, autofill และ paste
- จำกัด failed attempts ด้วย rate limiting
Baseline ไม่ใช่ข้อสรุปด้าน Assurance หรือ Compliance
ตัวเลขเหล่านี้เป็น baseline ของ NIST ไม่ใช่คำตอบสากลสำหรับทุกระบบ การเลือกระดับ assurance, ข้อกำกับ และ authenticator ต้องผ่าน threat/risk decision ของระบบจริง
[!TIP] Strength meter ช่วยได้มากกว่า Composition Error
การบอกว่า password เดาง่ายเพราะอยู่ใน breached/common list มีประโยชน์กว่าบังคับเติม !1A
ซึ่งมักสร้างรูปแบบคาดเดาได้ เช่น Password!1
เก็บ Password แบบ Verifier
ตามบท Cryptography ระบบต้องเก็บ salted password hash ด้วย password hashing function ที่เหมาะสม พร้อม algorithm/version/parameters เพื่อ upgrade ภายหลัง
credential_record =
subject_id
algorithm
cost_parameters
unique_salt
password_hash
created_at
last_rehash_at
ห้ามเก็บ plaintext, reversible encrypted password หรือ password hint ที่เปิดเผยรูปแบบ และห้าม log password แม้ authentication ล้มเหลว
Online Attacks มีหลายรูปแบบ
| Attack | วิธี | Control สำคัญ |
|---|---|---|
| Brute force | ลองหลาย password กับ account เดียว | per-account throttling, MFA, detection |
| Password spraying | ลอง password ยอดนิยมกับหลาย account | global/device/IP pattern, breached blocklist |
| Credential stuffing | ใช้คู่ credential ที่รั่วจากที่อื่น | compromised-password detection, MFA/passkey, anomaly detection |
| Username enumeration | เปรียบเทียบ response/timing | generic response, consistent code path, internal telemetry |
| Session theft | ขโมยผล login แทน password | session protection, reauth, revocation |
| Phishing | หลอกให้ส่ง authenticator | phishing-resistant authentication |
lock account แบบถาวรหลังผิดไม่กี่ครั้งทำให้ attacker ทำ denial of service ได้ Rate limiting ควรพิจารณาหลาย dimension เช่น subject, IP/network, device, credential, endpoint และ global load พร้อม progressive delay, bounded challenge และ alert ตามความเสี่ยง
อย่าเชื่อ IP เพียงมิติเดียว
ผู้ใช้จริงจำนวนมากอาจออกจาก NAT เดียว ส่วน botnet กระจายได้หลาย IP การ block IP อย่างเดียว จึงทั้งหลบง่ายและสร้าง false positive ควรรวม account velocity, device signal, ASN/location change, failed-to-success pattern และ known compromised credential โดยมี privacy/retention policy
ลด Account Enumeration
public response ของ login, signup และ recovery ควรไม่ยืนยันตรง ๆ ว่า identifier มีอยู่หรือไม่:
{
"message": "หากข้อมูลตรงกับบัญชีที่ใช้งาน ระบบจะดำเนินการขั้นตอนถัดไป"
}
จุดที่ต้องทำให้สอดคล้อง:
- HTTP status และ response body
- เวลาตอบโดยรวม โดยไม่ใช้ sleep แบบคงที่ที่ทำให้ DoS ง่าย
- recovery email/SMS behavior
- rate-limit response
- support/API error และ GraphQL field error
ภายในยังต้อง log outcome ที่ละเอียดพอให้ตรวจจับได้ แต่ไม่เก็บ password, OTP, token หรือ raw malicious payload
Generic error ไม่แทน Rate Limiting
attacker อาจตรวจผลจากช่องทางอื่นหรือใช้ credential ที่รู้ว่ามี account อยู่แล้ว enumeration defense จึงเป็นเพียงชั้นหนึ่ง
Authentication Flow ต้องผูก Transaction
ต้องป้องกัน flow confusion เช่น proof ที่เริ่มสำหรับ login หนึ่งถูกนำไปผูกกับอีก session ด้วย transaction ID, expiry, single-use state และ server-side binding ตาม protocol
Reauthentication สำหรับ Sensitive Events
session ที่ยังไม่หมดอายุไม่ได้แปลว่าผู้ใช้ยังอยู่หน้าอุปกรณ์ Sensitive events มักต้องประเมิน current assurance ใหม่ เช่น:
- เปลี่ยน password, passkey, email หรือเบอร์โทร
- เพิ่ม beneficiary หรือ device
- ดู recovery code หรือข้อมูลละเอียดสูง
- โอนเงินที่เกิน policy/risk threshold
- ปิด MFA หรือ revoke authenticator
- export ข้อมูลหรือเปลี่ยน privileged role
reauthentication ควรใช้ authenticator ที่เหมาะกับ risk และผูกกับ action/context ไม่ใช่แค่ เปิด modal ให้กรอก password เดิมบนหน้าที่อาจถูก phishing
Credential Change และ Compromise Response
เมื่อ password/authenticator เปลี่ยน ต้องกำหนดอย่างชัดเจนว่า:
- ต้องใช้ current authenticator หรือ recovery assurance ใด
- session ใดถูก revoke และ session ใดคงไว้ชั่วคราว
- refresh token/API token ใดต้อง invalidate
- ส่ง notification ผ่านช่องทางเดิมและช่องทางใหม่อย่างไร
- ตรวจการเปลี่ยนพร้อมกับ payout/beneficiary change หรือไม่
- rollback หรือ freeze เมื่อเจ้าของบัญชีรายงานว่าไม่ได้ทำอย่างไร
การลบ credential ที่รั่วจาก Git หรือ database ไม่พอ ต้อง revoke ที่ verifier/provider และค้นหา การใช้งานย้อนหลังภายในช่วงที่ credential อาจถูกขโมย
Authentication Telemetry
event ที่มีประโยชน์ควรระบุโดยไม่เก็บ secret:
| Field | ตัวอย่าง |
|---|---|
| Event | authentication.succeeded, credential.changed |
| Subject | opaque subject ID |
| Authenticator | password, passkey, TOTP โดยไม่เก็บ proof |
| Assurance | policy/AAL ที่ระบบกำหนด |
| Context | device/session/network risk references |
| Outcome/reason | success, bad proof, blocked, step-up |
| Correlation | request/transaction ID |
| Time/source | trusted timestamp และ service identity |
ตรวจจับ failed attempts, impossible/abnormal change, credential stuffing pattern, recovery-followed-by- payout และ disable-MFA-followed-by-transfer พร้อม runbook และ owner ไม่ใช่เก็บ log โดยไม่มีผู้ใช้
Testing Checklist
- identification, proofing, authentication, authorization และ session ถูกแยกชัด
- internal subject ID ไม่ผูกกับ email/phone ที่เปลี่ยนหรือ recycle ได้
- password policy รองรับความยาว, password manager และ breached blocklist
- password เก็บด้วย salted password hashing และ upgrade parameters ได้
- brute force/spraying/stuffing ถูกทดสอบหลาย dimension
- login/signup/recovery ลด enumeration ทั้ง body, status, timing และ side channel
- authentication transaction มี expiry, single-use และ context binding
- sensitive event กำหนด reauthentication/step-up ตาม risk
- credential change มี notification, revocation และ compromise response
- telemetry ไม่เก็บ password, OTP, token หรือ sensitive raw payload
สรุป
Authentication ที่แข็งแรงเริ่มจาก identity lifecycle และ threat model ไม่ใช่หน้า login password policy ต้องช่วยให้ใช้ password manager และต้านการเดา ขณะที่ rate limiting, phishing-resistant option, session protection, reauthentication และ detection ทำงานเป็นหลายชั้น