Database Security

ความปลอดภัยของ database ต้องครบ stack: encryption in-transit, at-rest, password hashing, SQL injection prevention, least privilege, audit logging

1. Encrypt Database Connection (TLS/SSL)

ความเข้าใจผิดเก่า: “DB กับ web server อยู่ data center เดียว — ไม่ต้อง encrypt”

ความจริง: ในยุค Cloud/K8s network ระหว่าง app กับ DB อาจผ่าน public network, K8s CNI overlay sniff ได้, compliance (PCI-DSS, HIPAA) บังคับ encryption in-transit

กฎใหม่: encrypt ทุก connection เสมอ ไม่ว่า DB จะอยู่ใกล้แค่ไหน

SSL Modes ใน Postgres Client

Modeความหมาย
disableไม่ใช้ SSL
allowลองไม่ใช้ก่อน ถ้า fail ใช้
prefer (default)ลองใช้ก่อน fail ถึงจะไม่ใช้
requireต้องใช้ แต่ไม่ verify cert
verify-caต้องใช้ + verify cert จาก trusted CA
verify-fullverify-ca + check hostname (ปลอดภัยที่สุด)

Pitfall: require อย่างเดียวไม่พอ — man-in-the-middle ส่ง self-signed cert ได้ → Production ต้อง verify-full เสมอ

2. Password Storage — Salt + Hash

salt = random_bytes(16)
password_hash = bcrypt(password + salt)
store(username, salt, password_hash)
  • ห้าม store plain text password
  • ห้าม store แค่ hash (MD5, SHA-1) — แตกง่ายด้วย rainbow table
  • Salt ทำให้ password เดียวกัน hash ต่างกัน (salt ไม่ต้อง secret)
  • PostgreSQL 14+: SCRAM-SHA-256 เป็น default — server ไม่เห็น plain password เลย

3. SQL Injection

# NEVER do this
query = f"SELECT * FROM users WHERE name = '{username}'"
# username = "'; DROP TABLE users; --"  → table หาย!
 
# ALWAYS use parameterized queries
cursor.execute("SELECT * FROM users WHERE name = %s", (username,))

กฎทอง: ห้ามต่อ string เพื่อสร้าง SQL เด็ดขาด — ใช้ placeholder/binding เสมอ

ORM (SQLAlchemy, Prisma, Hibernate) ใช้ parameterized queries by default → ปลอดภัย

4. Best Practices อื่น ๆ

Least Privilege

CREATE ROLE app_user LOGIN PASSWORD '...';
GRANT SELECT, INSERT, UPDATE ON orders TO app_user;
-- ไม่ให้ DROP, ALTER, GRANT

Network Isolation

DB อยู่ใน private subnet เท่านั้น — ไม่เปิด public IP

Audit Logging

ALTER SYSTEM SET log_connections = on;
ALTER SYSTEM SET log_statement = 'mod';  -- log INSERT/UPDATE/DELETE

Encryption at Rest

  • Disk-level encryption (LUKS, AWS EBS encryption)
  • Backup files ต้อง encrypted ด้วย

อื่น ๆ

  • MFA สำหรับ admin access
  • Regular patching — อัปเดต DB version แก้ CVE

Key Points

  • Encrypt ทุก connection — ใช้ TLS verify-full ใน production
  • Salt + Hash สำหรับ password — ห้าม plain text หรือ hash เปล่า
  • Parameterized queries เสมอ — ห้ามต่อ string สร้าง SQL
  • Least privilege — app ใช้ role ที่มี permission น้อยที่สุด
  • Encrypt at rest — ทั้ง live data และ backups