สารบัญ
Series: Database 101 — เข้าใจห้องสมุดของเมืองดิจิทัล (ภาษาคน)
Part 0 — WHY: ทำไมต้องมีห้องสมุด
Part 1 — ประวัติ: 4 ยุคของ Database
- EP.02 — ยุค 1960s-70s: Hierarchical → Relational Revolution
- EP.03 — ยุค 1980s-90s: ACID + Enterprise Backbone
- EP.04 — ยุค 2000s-2010s: NoSQL Movement + Big Data
- EP.05 — ยุค 2020s: Cloud-Native + Serverless Database
Part 2 — How: ภายใน Database ทำงานยังไง
- EP.06 — Schema, Normalization, Keys
- EP.07 — Index + Query Optimization
- EP.08 — Transaction + Concurrency Control
Part 3 — เลือก Storage ตามขนาด
- EP.09 — มุมเว็บส่วนตัว: Database-less Architecture
- EP.10 — มุม Personal Data: SQLite + Local-first
- EP.11 — มุม Startup: Serverless DB Stack
- EP.12 — มุม Enterprise: Polyglot Persistence
Part 4 — Operations
- EP.13 — DBA Role + Privileged Access
- EP.14 — Database Security + Encryption ← คุณอยู่ตรงนี้
Part 5 — Future
- EP.15 — Vector Database + AI Era
- EP.16 — Wrap: Decision Tree + 5 Trends
ฉากเปิด: junior คนหนึ่งเสียบ external drive แล้ว copy backup ออก “เพื่อทดสอบ”
ลองนึกภาพ scenario นี้ครับ เป็น pattern ที่เห็นในข่าว data breach ของไทยซ้ำๆ จนเกือบเป็น template
วันธรรมดาวันหนึ่งของบริษัท e-commerce ขนาดกลาง ลูกค้าประมาณ 2 ล้าน account มี order history, เบอร์โทร, เลขบัตรประชาชน (ที่เก็บไว้ตอนยืนยันตัวตนสมัยทำ KYC), เลขบัตรเครดิตที่ tokenize แล้ว แต่ส่วนข้อมูลอื่นยังเป็นตัวจริงทั้งนั้น
junior sysadmin คนหนึ่งได้รับมอบหมายให้ “ลองเอา production backup ไปทดสอบ restore บน staging” เขาทำตามที่หัวหน้าบอก เปิด server หา backup file ล่าสุด copy ใส่ external SSD ที่ตัวเองพกประจำ เดินกลับโต๊ะ
ไฟล์ backup ตัวนั้น ไม่ได้ encrypt เพราะตอนตั้งระบบไว้เมื่อ 4 ปีก่อน “encryption ทำให้ restore ช้า” และ “อยู่ใน internal network อยู่แล้ว ไม่มีคนเข้าถึง” จริงไหม
วันรุ่งขึ้น junior คนนั้นลืม external SSD ไว้ที่ร้านกาแฟใต้ออฟฟิศ กลับไปหา ไม่เจอแล้ว
นี่ไม่ใช่ hack ไม่ใช่ ransomware ไม่ใช่ APT จากรัฐต่างชาติ แต่คือ single file ที่ไม่ encrypt + ความประมาทของมนุษย์คนเดียว = data breach ขนาด 2 ล้าน record ที่ต้อง report ตาม PDPA ภายใน 72 ชั่วโมง
EP.13 เราคุยเรื่อง DBA + privileged access ไปแล้ว มุม “ใครมีกุญแจ” แต่ EP.14 จะคุยมุมที่ครบกว่านั้น — ต่อให้คุมกุญแจดีแค่ไหน ถ้าตู้เซฟที่เก็บข้อมูลมันไม่ได้ล็อก หรือเก็บสำเนาไว้ในกล่องกระดาษวางหน้าร้าน ก็จบเหมือนกัน
เปรียบกับห้องสมุดก็คือ ไม่ใช่แค่จ้างยามดี แต่ตู้เซฟต้องมี ล็อก alarm กล้อง audit trail ครบทุกชั้น
3 ชั้นของ Database Security — เหมือนป้อมปราการ ไม่ใช่ประตูเดียว
Security ที่ดีไม่ใช่ “หาเครื่องมือเทพหนึ่งตัวมาตอบโจทย์ทุกอย่าง” แต่คือการ stack หลายชั้นทับกัน จนแม้ชั้นใดชั้นหนึ่งพัง ชั้นอื่นยังกั้นไว้อยู่ แนวคิดนี้ในวงการเรียก defense in depth
สำหรับ database ชั้นที่ต้องมีครบมี 3 ชั้น
Layer 1: Network — DB ไม่ควรมี IP สาธารณะ จุดจบ
ปัญหาคลาสสิกของบริษัทไทยขนาดกลางที่ผมเห็นในข่าวบ่อย เปิด port 3306 (MySQL) หรือ 5432 (Postgres) ออก public internet “เพื่อให้ developer เข้าถึงได้จากบ้าน” แล้วไม่กี่สัปดาห์ต่อมาเจอ ransomware
DB ไม่ควรอยู่บน public internet เด็ดขาด ไม่มีข้อยกเว้น แม้แต่ตอน dev ตอน demo
วิธีถูกต้อง:
- VPC / private subnet — เอา DB ใส่ network ที่ไม่ route ออก internet
- No public IP — DB instance มีแค่ private IP ภายใน
- Bastion host หรือ VPN-only access — ถ้า dev ต้องเข้า ต้อง VPN เข้ามาก่อน หรือ SSH ผ่าน bastion (jump server) ที่มี audit log
- Cloud security group — กำหนดว่า “เฉพาะ application server IP X.X.X.X เท่านั้นที่คุยกับ DB ได้” คนอื่นแม้อยู่ใน VPC เดียวกันก็ไม่เห็น
ภาพง่ายๆ คือ DB ควรเป็นห้อง ในสุดของตึก ที่จะเข้าถึงได้ต้องผ่านประตูหลายชั้น ไม่ใช่ตั้งโต๊ะทำงานอยู่หน้าร้าน
(ถ้าอยากเข้าใจเรื่อง network segmentation ลึกขึ้น ลองย้อนไปอ่าน CyberSec Foundation EP.28 — Network Segmentation + DMZ มันอธิบาย pattern เดียวกันในมุม network architect)
Layer 2: Authentication — เลิกใช้ shared password
ปัญหาเก่าแก่อีกอย่างของบริษัทไทยขนาดกลาง คือมี password ของ DB admin ที่ “ทุกคนใน dev team รู้” เก็บไว้ใน Slack channel ชื่อ #dev-secrets เมื่อ junior ลาออกก็ไม่ได้เปลี่ยน password เพราะ “เปลี่ยนทีพังทั้งระบบ”
วิธีที่ควรทำในปี 2026:
- IAM Database Authentication — บริการอย่าง AWS RDS / Aurora รองรับการ login DB ผ่าน IAM token แทน password ความหมายคือ login ผ่านตัวตน IAM ของบุคคลคนนั้น ไม่ใช่ password ของ DB ที่ใครก็ใช้ได้
- Service account แยกจาก human account — application ใช้ service account คนใช้ human account ใครทำอะไรเห็นใน log ได้ชัด
- No shared admin password — ถ้าจำเป็นต้องมี admin password เก็บใน secret manager (AWS Secrets Manager / HashiCorp Vault) แล้ว rotate ทุก 90 วัน
- MFA สำหรับ admin access — ทุก human account ที่เข้า DB ในระดับ admin ต้องผ่าน MFA
เปรียบกับห้องสมุดก็คือ ไม่ใช่ “กุญแจที่ใครก็ copy ได้” แต่เป็น บัตรพนักงานที่มีรูป มีเลข มีระบบ swipe เข้าออกที่ไหนเมื่อไหร่บันทึกไว้หมด
Layer 3: Encryption — at rest + in transit
อันนี้เจาะลึกใน 2 sub-section ถัดไป
ก่อนจะข้าม สรุปสั้นๆ ก่อนว่า 3 ชั้นนี้ต้องมีครบ ไม่ใช่ “เลือกอย่างใดอย่างหนึ่ง” เพราะแต่ละชั้นป้องกันการโจมตีคนละแบบ — network ชั้นเดียวพังเมื่อ insider attack, authentication ชั้นเดียวพังเมื่อ DB instance หลุดออกไป, encryption ชั้นเดียวพังเมื่อ application bypass ผ่าน SQL injection
Encryption at Rest — เก็บใน DB ในรูปที่อ่านไม่ออก
Encryption at rest หมายถึงข้อมูลที่ “นอนนิ่งอยู่บน disk” (ไม่ว่าจะใน DB file, backup file, snapshot) เก็บในรูป ciphertext ไม่ใช่ plain text ใครเอา hard drive ไป plug เข้าเครื่องอื่นจะอ่านไม่ออก
วิธีหลักที่ DB engine สมัยใหม่ใช้คือ TDE (Transparent Data Encryption) — Oracle, SQL Server, AWS RDS, Aurora รองรับหมด เปิดเป็น setting ตอน provision DB
คำว่า “Transparent” สำคัญมาก มันแปลว่า application ไม่รู้และไม่ต้องแก้ การ query เหมือนเดิมทุกอย่าง DB engine จัดการ encrypt/decrypt ที่ disk level เอง ตอนเขียนลง disk = encrypt, ตอนอ่านจาก disk = decrypt, application เห็นข้อมูลเป็น plain ตามปกติ
มัน protect อะไรได้:
- hard drive ที่หายหรือถูกขโมยไปจาก data center
- snapshot ที่ถูก export ออก
- backup file ที่ถูก copy ออก (อย่างที่ junior ใน scenario เปิดบทเล่าให้ฟัง)
มัน ไม่ protect อะไร:
- ถ้า attacker เข้าผ่าน application หรือ SQL injection encryption ก็ decrypt ให้เห็นข้อมูลตามปกติ เพราะมันทำงานที่ disk level ไม่ใช่ access level
- ถ้า DBA ที่มีสิทธิ์ login DB เข้าไปเอง ก็เห็น plain text ตามปกติ
คำที่ผู้บริหารควรจำ — “Encryption at rest = protection against physical theft, not against application breach” มันช่วยตอนของหายหรือ backup หลุด ไม่ช่วยตอนคนแฮก application
(ถ้าอยากเข้าใจเรื่อง symmetric / asymmetric / key management แบบรากฐาน ลองอ่าน CyberSec Foundation EP.19 — Cryptography 101 มันปูพื้นทุกอย่างที่ encryption สมัยใหม่ใช้)
Encryption in Transit — TLS connection จาก app ถึง DB
Encryption at rest ดูแลข้อมูลตอน “นอนนิ่ง” แต่ตอนข้อมูลวิ่งจาก application server ไป DB server ผ่าน network ล่ะ?
ถ้า DB connection ไม่ encrypt = traffic ใน network ถูก sniff ได้ ใครที่อยู่ใน network ระหว่างทาง (insider, network engineer, attacker ที่ pivot เข้ามาจากเครื่องอื่น) สามารถดักดูข้อมูลที่วิ่งไปวิ่งมา รวมถึง credential ที่ใช้ login DB ด้วย
มาตรฐานปี 2026:
- TLS 1.2+ บังคับใช้ ทุก connection แม้ app กับ DB อยู่ใน VPC เดียวกัน
- TLS 1.3 ถ้าทำได้ เร็วกว่าและ secure กว่า
- Certificate validation ที่ application side ไม่ใช่แค่ “เปิด TLS” แต่ต้องตรวจ cert ของ DB ด้วยว่าเป็น cert ที่ถูกต้องไม่ใช่ cert ของ man-in-the-middle
- Reject plaintext connection — DB config ตั้งให้ปฏิเสธ connection ที่ไม่ใช่ TLS เลย
(เรื่อง TLS / HTTPS / cert chain ลึกๆ ผมเขียนไว้แล้วใน CyberSec Foundation EP.24 — TLS / HTTPS — pattern เดียวกันกับที่ web ใช้ แค่ port กับ protocol เปลี่ยนเป็นของ DB)
มุมผู้บริหารง่ายๆ — ถ้า DB connection ของบริษัทคุณยังไม่ TLS ปี 2026 = หนึ่งใน finding แรกของ auditor ทุกตัวที่เดินเข้ามา
Field-level Encryption — encrypt เฉพาะ column ที่อ่อนไหวจริงๆ
TDE encrypt ทั้ง DB ที่ disk level เหมาะกับ “ถ้า hard drive หาย” แต่ถ้าอยากให้แม้ DBA ที่ login เข้า DB ตรงๆ ก็ไม่เห็นข้อมูล ต้องไปอีกชั้น — field-level encryption (หรือ column-level encryption)
หลักการ:
- application encrypt ข้อมูลก่อนเก็บลง DB → DB เห็นข้อมูล column นั้นเป็น ciphertext ทั้งหมด
- ตอน app ดึงข้อมูลกลับ → app decrypt ก่อนแสดงผลให้ user
- key อยู่ที่ application หรือ key management service (KMS) ไม่อยู่ใน DB
ผลคือ DBA ที่เปิด DB tool ขึ้นมา query SELECT * FROM users จะเห็น column national_id เป็น string มั่วๆ อ่านไม่ออก ต่อให้มี admin privilege
เหมาะกับ data ประเภท:
- เลขบัตรประชาชน / passport
- เลขบัตรเครดิตเต็ม (ถ้ายังไม่ tokenize)
- ข้อมูลทางการแพทย์ที่ sensitive
- ข้อมูลเงินเดือน / ข้อมูลรายได้บุคคล
Trade-off ที่ต้องรู้: การ search ที่ encrypted column ทำได้ยากมาก เพราะ DB เห็นแต่ ciphertext จะ WHERE national_id = '1234567890123' ตรงๆ ไม่ได้ ต้องใช้:
- Deterministic encryption — encrypt ค่าเดียวกันแล้วได้ ciphertext เดียวกันเสมอ → search ได้แต่ leak pattern (ถ้า value ซ้ำในหลาย row จะเห็น ciphertext ซ้ำ)
- Hash for indexing — เก็บ hash ของค่าไว้อีก column เพื่อ search
- Searchable encryption schemes — schema เฉพาะที่ออกแบบมาให้ search ได้ แต่ complex และยังเป็นพื้นที่ active research
Tokenization vs Encryption — token ที่ไม่ใช่ข้อมูลจริง
หลายคนคิดว่า tokenization กับ encryption คือเรื่องเดียวกัน จริงๆ ต่างกันชัด
Encryption ข้อมูลที่ encrypted ยังเก็บอยู่ใน DB เดิม ใช้ key decrypt กลับเป็น plain ได้ ถ้า key หลุด = ข้อมูลหลุด
Tokenization เอาข้อมูลจริงไปเก็บใน vault แยก (ระบบเฉพาะที่ harden มาเพื่อเก็บ sensitive data) แล้ว vault ส่ง token (ค่า random ที่ไม่มีความหมาย) กลับมาให้ DB หลักเก็บแทน DB หลักไม่มีข้อมูลจริงเลย ถ้า DB หลุด = หลุดแค่ token ที่ไม่มีค่า
ตัวอย่างที่คนไทยใช้กันทุกวันแต่ไม่รู้ว่าเป็น tokenization คือ Stripe / Omise เวลาคุณซื้อของจาก e-commerce ไทยที่ใช้ Omise เป็น payment gateway:
- คุณกรอกเลขบัตรเครดิตในหน้าชำระเงิน
- JavaScript ส่งเลขบัตรตรงไปที่ Omise ไม่ผ่าน server ของร้าน
- Omise เก็บเลขบัตรในระบบของเขาเอง แล้วส่ง token (เช่น
tokn_test_abc123xyz) กลับมาให้ร้าน - DB ของร้านเก็บแค่ token นั้น ไม่มีเลขบัตรเครดิตจริงเลยสักเลขเดียว
ผลคือ ร้านอยู่นอก PCI DSS scope เพราะ “ของที่ไม่มี = leak ไม่ได้” PCI DSS เป็นมาตรฐาน security สำหรับธุรกิจที่จัดการเลขบัตรเครดิต ปฏิบัติตามครบทุกข้อ = แพงและซับซ้อนมาก ร้านไหนที่ไม่ต้องจัดการเลขบัตรจริง = ลด scope ลงเหลือแค่ “อย่าให้ token หลุด” ซึ่งง่ายกว่ามาก
นี่คือเหตุผลที่ PCI DSS แนะนำ tokenization สำหรับ credit card อย่างชัดเจน ไม่ใช่แค่ “secure กว่า” แต่ “ลด liability ลงทั้ง stack”
SQL Injection — เคสคลาสสิคที่ application bypass DB security ทุกชั้น
จะ encrypt at rest ดีแค่ไหน จะ TLS แน่นแค่ไหน ถ้า application ส่ง query ที่ไม่ตั้งใจ เข้า DB DB ก็ทำตามครับ มันไม่รู้ว่า attack หรือไม่ attack
นี่คือ pattern ของ SQL injection — attacker ใส่ SQL syntax ปนเข้าไปใน input ที่ application ไม่ระวัง แล้ว application เอา input นั้นไปต่อท้าย SQL string ตรงๆ
ตัวอย่างคลาสสิกที่ทุกตำราใช้สอน — login form ที่เขียนแบบนี้:
SELECT * FROM usersWHERE username = '<input ของผู้ใช้>' AND password = '<password ของผู้ใช้>'ผู้ใช้ใส่ username = admin' OR '1'='1 → SQL ที่ส่งจริงกลายเป็น:
SELECT * FROM usersWHERE username = 'admin' OR '1'='1' AND password = '...'เงื่อนไข '1'='1' เป็นจริงเสมอ → ผ่าน authentication โดยไม่ต้องรู้ password ใครเลย
ที่หนักกว่านั้น — '; DROP TABLE users; -- ทำให้ table users หายทั้ง table ภายในวินาทีเดียว
วิธีป้องกัน 3 ชั้น (ต้องมีครบ ไม่ใช่เลือกอย่างใดอย่างหนึ่ง):
1. Parameterized query (prepared statement) — แทนที่จะเอา input ไปต่อ string ตรงๆ ใช้ ? placeholder แล้วส่ง input แยกเป็น parameter DB engine จัดการ escape เอง:
SELECT * FROM users WHERE username = ? AND password = ?ทุก ORM (Object-Relational Mapper) สมัยใหม่ — Prisma, TypeORM, SQLAlchemy, Eloquent, Hibernate — ใช้ parameterized query เป็น default อยู่แล้ว ปัญหาเกิดเมื่อ developer เขียน raw SQL เอง แล้วลืม
2. Input validation — whitelist character ที่อนุญาตในแต่ละ field เช่น username อนุญาตแค่ตัวอักษรกับตัวเลข ไม่อนุญาต quote หรือ semicolon
3. Least privilege — application user ใน DB ควรมีสิทธิ์เฉพาะที่ต้องใช้จริง ไม่ใช่ DBA สิทธิ์เต็ม ถ้าโดน inject สำเร็จ damage ก็จำกัด เช่น app user ที่ทำ SELECT ได้แต่ DROP ไม่ได้ ต่อให้ inject DROP TABLE เข้ามา DB ก็ปฏิเสธ
(SQL injection อยู่ใน OWASP Top 10 มา 20 กว่าปีแล้ว ยังเป็น attack ที่เห็นในข่าว breach ปี 2026 อยู่เรื่อยๆ ลึกกว่านี้ผมเขียนไว้ใน CyberSec Foundation EP.42 — OWASP Top 10 ว่ามีอีก 9 attack อะไรบ้างที่ web app ต้องระวัง)
Row-Level Security (RLS) — ผู้ใช้แต่ละคนเห็นแถวต่างกัน
ปัญหาคลาสสิกของ multi-tenant SaaS คือ app เดียว DB เดียว แต่ลูกค้าหลายบริษัทแยกกันเห็นข้อมูลของตัวเอง บริษัท A ต้องไม่เห็น order ของบริษัท B ต่อให้อยู่ table เดียวกัน
วิธีเก่าคือ ทุก query ของ application ต้องใส่ WHERE tenant_id = <tenant ของผู้ใช้คนนี้> เอง ลืมที่ใดที่หนึ่ง = data leak ข้าม tenant
วิธีใหม่คือ Row-Level Security (RLS) ย้าย logic นี้ลงมาที่ DB level
Postgres, SQL Server, Supabase, Oracle รองรับ RLS เต็มตัว หลักการคือ:
- กำหนด policy ที่ DB level ว่า “table นี้ row นี้ user ไหนเห็นได้บ้าง”
- application ต่อ DB ด้วย user identity ของ end-user (หรือ session variable)
- DB filter row ที่ user ไม่ควร เห็นออกอัตโนมัติ ก่อนส่งผลลัพธ์กลับ
ผลคือ แม้ application bug แม้ลืม WHERE tenant_id แม้ developer junior เผลอ query ผิด DB ก็ filter ให้เห็นแค่ของ tenant ตัวเอง เป็น safety net ชั้นที่ 2 ที่ไม่ต้องพึ่ง application logic อย่างเดียว
ตัวอย่างที่คนไทยน่าจะคุ้นคือ Supabase (BaaS ที่ใช้ Postgres ข้างใต้) ทั้ง product สร้างมาบน RLS เลย ทุก table ที่เก็บ user data จะมี policy แบบ “user เห็นได้แค่ row ที่ user_id = auth.uid()” เป็น default ใครเห็น row ของใครไม่ได้แม้ใช้ API ตรงๆ
Field-Level Access Control — receptionist ไม่ควรเห็น diagnosis
อีกชั้นที่ละเอียดกว่า RLS คือ field-level access control กำหนดว่า role ไหนเห็น column ไหนได้บ้าง
เคสคลาสสิกของโรงพยาบาลที่ตรงกับ pattern PDPA จริง — ทุก hospital staff (receptionist, ลูกจ้างหน้าบ้าน, แม่บ้าน, นักการ, พยาบาล, แพทย์) ใช้ role “hospital_user” เดียวกันใน DB → ทุกคนเห็น SELECT * FROM patients ได้เหมือนกัน → receptionist ที่หน้าเคาน์เตอร์เห็นข้อมูล diagnosis ของผู้ป่วยทุกคน
ตามหลัก PDPA receptionist มีหน้าที่แค่ identify ผู้ป่วยกับนัด ไม่ควรเห็น diagnosis เลย การเห็นโดยไม่จำเป็น = breach of necessity principle
วิธีแก้ที่ DB level:
1. Column-level GRANT (Postgres / Oracle):
GRANT SELECT (name, phone, appointment_time) ON patients TO receptionist;
GRANT SELECT (name, diagnosis, treatment_plan) ON patients TO doctor;receptionist SELECT * ก็ได้ผลแค่ column ที่อนุญาต — column อื่น DB ปฏิเสธ
2. View ที่ filter column — สร้าง view patients_for_receptionist ที่ select เฉพาะ column ที่อนุญาต แล้ว grant สิทธิ์ที่ view นั้นแทน table ตรง
3. Application-level role + DB-level enforcement ทั้งคู่ — application กรอง column ตาม role + DB ก็มี GRANT ทับอีกชั้น defense in depth
มุม PDPA สำคัญมาก กฎหมายระบุชัดว่าต้อง implement technical measures ที่จำกัด access ตาม necessity ไม่ใช่แค่ “เขียน policy” แล้วหวังให้พนักงานจำได้
Backup Encryption — กฎเหล็ก: production มี PII = backup ต้อง encrypt
กลับมาที่ scenario เปิดบท junior ที่เสียบ external SSD copy backup ออกไป
ความจริงที่บริษัทไทยขนาดกลางหลายแห่งยังไม่ยอมรับ — production DB อาจ secure แน่น ผ่าน audit ทุกข้อ แต่ backup file ที่ไม่ encrypt = single point of failure ของ security ทั้งระบบ
backup file ตามธรรมชาติคือ:
- copy ของ DB ทั้ง DB ในไฟล์เดียว
- ใหญ่ ส่งต่อง่าย พกพาง่าย
- มักเก็บไว้ที่ที่ “secure น้อยกว่า production” — external drive, S3 bucket ที่ permission หละหลวม, archive server ที่ตอน setup ไม่ได้คิดเรื่อง security
- มักมีอายุยาว backup 5 ปีก่อนยังอยู่ใน archive
ถ้า backup ไม่ encrypt = ใครก็ตามที่ touch backup file ได้ = touch DB ทั้ง DB ได้
กฎเหล็กปี 2026: ถ้า production มี PII → backup ต้อง encrypt ไม่มีข้อยกเว้น
วิธี encrypt backup ที่ทำได้:
- GPG / OpenSSL encrypt backup file ก่อน upload ไป archive
- AWS S3 encryption (SSE-S3 / SSE-KMS) S3 encrypt ให้อัตโนมัติเปิดเป็น default
- Native DB backup encryption — เกือบทุก DB engine สมัยใหม่ encrypt backup ได้ (
pg_dump+ GPG, MySQL--ssl-mode, SQL Server backup encryption)
สำคัญที่สุดคือ Key management — key ที่ใช้ encrypt backup ห้ามเก็บไว้ที่เดียวกับ backup เด็ดขาด ใช้ KMS (Key Management Service) หรือ HSM (Hardware Security Module) แยก ถ้า attacker ได้ทั้ง backup file และ key file = ไม่ต่างจากไม่ encrypt เลย
(พื้นฐาน symmetric / asymmetric / KMS / HSM ลึกกว่านี้ ผมเขียนไว้ใน CyberSec Foundation EP.19 — Cryptography 101 แล้ว เป็น series ที่ปูพื้นเรื่อง cryptography ทั้งหมดที่ database security สมัยใหม่ใช้)
Immutable Backup + Air-gap — ป้องกัน Ransomware ที่เก่งกว่ารุ่นก่อน
Ransomware รุ่นปี 2024-2026 ฉลาดกว่ายุค WannaCry ปี 2017 มาก มันรู้ว่าบริษัทมี backup และมันจะ encrypt backup ก่อน production เพื่อให้บริษัทไม่มีทางเลือกอื่นนอกจากจ่ายค่าไถ่
ถ้า backup ของคุณ:
- เก็บใน folder ที่ map drive จาก server เดียวกัน → ransomware encrypt ทับได้
- sync เข้า cloud ผ่าน Dropbox / Google Drive auto-sync → ถูก sync version encrypted ทับ version ดี
- เก็บใน S3 ที่ user มีสิทธิ์ DELETE → ransomware ลบทิ้งได้
วิธีป้องกัน 3 ชั้น (เรียกรวมว่า 3-2-1 backup rule ปรับใหม่ปี 2026):
1. Immutable backup — write-once-read-many (WORM)
backup ที่เขียนแล้ว ลบ/แก้ไม่ได้ จนกว่าจะถึง retention period
- AWS S3 Object Lock
- Azure Blob immutable storage
- Backup appliance ที่รองรับ immutability native
ransomware ต่อให้มีสิทธิ์ DELETE DB ก็ปฏิเสธเพราะ object ติด lock อยู่
2. Air-gapped backup — disconnect จาก network จริงๆ
backup ที่ไม่เชื่อมต่อกับ production network เลย
- Tape backup ที่เก็บใน vault กลับมาเป็นที่นิยมในยุค ransomware
- Cold storage ที่ต้องมี manual step เพื่อเข้าถึง (AWS Glacier Deep Archive)
- Offsite backup ที่อยู่คนละ region คนละ account คนละ cloud provider
ransomware ที่อยู่ใน production network ไม่มีทาง reach backup เพราะ network ไม่ติดกัน
3. Multi-version retention
เก็บ backup หลาย version ตามรอบเวลา
- รายวัน — เก็บ 30 วัน
- รายสัปดาห์ — เก็บ 12 สัปดาห์
- รายเดือน — เก็บ 12 เดือน
- รายปี — เก็บ 7 ปี (หรือตาม compliance)
เผื่อกรณีที่ ransomware แอบฝังตัวอยู่ใน production มาหลายสัปดาห์ก่อน detect ต้อง restore จาก backup ที่อยู่ก่อนหน้านั้น
scenario ที่เห็นในข่าว — บริษัทโดน ransomware ที่ฝังมา 4 วันก่อน fully encrypt บริษัทเลือก restore จาก backup 5 วันก่อน → เสีย customer data 5 วัน แต่ไม่ต้องจ่ายค่าไถ่ ดีกว่าตัวเลือก “จ่าย $5M แล้วยังไม่แน่ใจว่าได้ key หรือเปล่า”
Audit Logging — log ทุก query, log ทุก login
ชั้นสุดท้ายของ security ที่หลายบริษัทมองข้าม คือ audit log ที่ DBA ตัวเองแก้ไม่ได้
หลักคิดง่ายๆ ถ้าเกิด incident แล้วต้องสืบสวน คำถามแรกที่ทุกคนถามคือ “ใครเข้ามา ทำอะไร เมื่อไหร่” ถ้าตอบไม่ได้ = สืบไม่ออก = ไม่รู้ว่ารั่วจากที่ไหน = ปิดช่องโหว่ไม่ได้
3 layer ของ audit log ที่ DB ควรเก็บ:
1. DDL audit — Data Definition Language ใครเปลี่ยน schema เมื่อไร
CREATE TABLE,ALTER TABLE,DROP TABLE,CREATE USER,GRANT- เกือบทุกการเปลี่ยน schema = significant event ที่ควรมี approval workflow ไม่ใช่ DBA คนเดียวสั่งจบ
2. DML audit — Data Manipulation Language ใคร INSERT / UPDATE / DELETE บน table sensitive
- ไม่ต้อง log ทุก table เลือกเฉพาะ table ที่มี PII / financial / sensitive
- log ค่าก่อนและหลังการเปลี่ยน เพื่อให้ rollback ได้และตรวจสอบได้
3. Login audit — ใคร login เมื่อไหร่ จาก IP ไหน
- successful login + failed login ทั้งคู่
- failed login จำนวนมากต่อเนื่อง = brute-force attempt
สำคัญที่สุดคือ log ส่งออกไปที่ DBA ตัวเองแก้ไม่ได้ SIEM (Security Information and Event Management) เช่น Splunk, ELK Stack, AWS CloudTrail ที่:
- DBA ของ DB หลักไม่มีสิทธิ์ delete log
- log immutable + signed timestamp
- monitoring + alert อัตโนมัติเมื่อเจอ pattern ผิดปกติ
Retention ตาม compliance ที่บริษัทอยู่ภายใต้:
- SOX (สำหรับบริษัทจดทะเบียน US) = 7 ปี
- PDPA = ตามนโยบายของ organization (แต่ practice ทั่วไป 2-7 ปี)
- HIPAA (สำหรับ healthcare US) = 6 ปี
- PCI DSS = อย่างน้อย 1 ปี (3 เดือนต้อง online ทันที)
มุมผู้บริหาร — encryption ไม่ใช่ “feature เสริม” อีกต่อไปปี 2026
PDPA (พ.ร.บ.คุ้มครองข้อมูลส่วนบุคคล ของไทย) และ GDPR (กฎหมายของ EU) ระบุชัดเจนว่า encryption เป็น “default expected control” สำหรับ DB ที่เก็บ PII (Personally Identifiable Information)
ความหมายคือ ภาระการพิสูจน์เปลี่ยนทิศ จากเดิม “ทำไมต้องมี encryption” → ปัจจุบันเป็น “ทำไมไม่มี encryption”
ถ้าเกิด data breach แล้วต้องไป report กับ committee คำถามแรกที่ committee ถามคือ “DB ที่หลุดมี encryption ที่ rest มั้ย / ที่ transit มั้ย / backup encrypt มั้ย” ถ้าตอบ “ไม่มี” 1 ใน 3 ข้อ บริษัทมีปัญหาทั้ง compliance fine และ civil liability ทั้งคู่
ตัวเลขที่น่ากลัว — IBM Cost of a Data Breach Report 2025 (รายงานปีล่าสุดที่ public) ระบุค่าเสียหายเฉลี่ยของ data breach ระดับโลก = $4.88M (ประมาณ 170 ล้านบาท) ต่อเหตุการณ์ รวม downtime, regulatory fine, lawsuit, brand damage, customer churn
ค่าทำ encryption + key management setup สำหรับ DB ขนาดกลาง = หลักหมื่นถึงแสนบาท เป็น one-time cost บวกค่า KMS รายเดือนอีกไม่กี่ร้อย
ratio ของ “cost ของการป้องกัน” กับ “cost ของการไม่ป้องกัน” = ห่างกัน 4-5 order of magnitude
คำถามเดียวที่ผู้บริหารต้องตอบให้ได้ภายในไตรมาสนี้:
“บอกชื่อ DB ทุกตัวในบริษัทที่มี PII แล้วบอกผมว่า — at rest encrypt มั้ย / in transit encrypt มั้ย / backup encrypt มั้ย”
ถ้าทีม IT / DBA ตอบไม่ได้ทันที = ปัญหา ไม่ใช่ “ตอนนี้รอตอบ” แต่เป็น “ไม่มี inventory” ซึ่งเป็น finding ขั้นพื้นฐานของ audit ทุกตัว
ปิด Part 4 — ทั้ง DBA control และ Security คือ 2 ขาของ DB protection
EP.13 + EP.14 รวมกันคือ Part 4 — Operations ของ Database 101
EP.13 ดูแลฝั่ง คน — ใครมีกุญแจ ใครเห็นอะไรได้ separation of duties privileged access EP.14 ดูแลฝั่ง ข้อมูล — encryption ที่ rest / in transit / field, backup, audit, ransomware defense
ทั้งสอง EP มี theme เดียวกัน — ของที่ป้องกันไม่ได้ ห้ามเก็บไว้ ของที่ต้องเก็บ ต้องป้องกันสมเหตุสมผล
เปรียบกับห้องสมุด Part 4 จบที่ “ห้องสมุดของเมืองดิจิทัลตอนนี้มียามครบ มีตู้เซฟมีล็อก มี alarm มี audit trail” งานปกติของ DB ในยุค pre-AI ครบแล้ว
(ถ้าอยากเห็นมุม security framework เต็มสำหรับ DB management ในมุม CISA exam ลองอ่าน CISA Domain 4 EP.37 — Database Management Systems เป็น mapping แบบเป็นทางการของสิ่งที่ EP.13-14 พูดในมุมที่ ISACA ออกข้อสอบ)
แต่ปี 2026 มี DB ตัวใหม่เกิดขึ้น DB ที่ไม่เคยมีอยู่ใน Part 1-4 ของ series นี้เลย
ทุก ChatGPT, Notion AI, Perplexity, Claude, Cursor ที่คุณใช้กันอยู่ทุกวัน เบื้องหลังมี DB ตัวใหม่ที่เก็บข้อมูลคนละแบบกับ relational, NoSQL, document store ที่เราคุยกันมา 13 EP
มันชื่อว่า Vector Database และมันคือเหตุผลที่ AI app สมัยใหม่ “จำได้ว่าคุณคุยอะไรไว้” และ “ค้นเอกสารที่ความหมายใกล้กัน” ได้ เรื่องที่ relational DB ทำไม่ได้
Part 5 จะเปลี่ยน gear ไปดู future ของ database — เริ่มที่ EP.15
→ EP.15 — Vector Database + AI Era