ผลต่างระหว่างรุ่นของ "01204223/secrets"

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา
(แทนที่เนื้อหาด้วย ": ''หน้านี้เป็นส่วนของวิชา01204223'' เราจะฝึกจัดการกับข...")
Tag: ถูกแทน
แถว 1: แถว 1:
 +
: ''หน้านี้เป็นส่วนของวิชา[[01204223]]''
 +
 
เราจะฝึกจัดการกับข้อมูลที่เป็นความลับในการพัฒนาเว็บแอพ
 
เราจะฝึกจัดการกับข้อมูลที่เป็นความลับในการพัฒนาเว็บแอพ
  
−
ก่อนอื่นอ่านภาพรวมในการจัดการก่อน
+
ก่อนอื่นอ่านภาพรวมในการจัดการก่อน อ่านที่นี่: [[01204223/secrets overview]]
−
 
 
−
== แนวปฏิบัติทั่วไปในการจัดการ ''secrets'' (รหัสผ่าน / API keys) สำหรับเว็บแอป Flask + React ==
 
−
 
 
−
: ''เขียนโดย chatgpt''
 
−
 
 
−
=== หลักคิดพื้นฐาน ===
 
−
 
 
−
* '''ห้ามฝัง secret ลงในโค้ด''' (รวมถึง commit เข้า git, paste ลง issue, หรือส่งในแชต)
 
−
* '''ให้สิทธิ์เท่าที่จำเป็น (least privilege)''' เช่น key ที่ใช้เรียก API แค่ read ก็อย่าให้ write
 
−
* '''แยกสภาพแวดล้อม (dev / staging / prod)''' และใช้ secret คนละชุดเสมอ
 
−
* '''หมุนคีย์ได้ (rotation)''' ออกแบบให้เปลี่ยน key/รหัสผ่านแล้วระบบรันต่อได้ ไม่ต้อง deploy แบบเสี่ยง ๆ
 
−
* '''ทุกอย่างที่อยู่ฝั่ง client ถือว่า “เปิดเผยได้”''' เพราะ React build แล้วผู้ใช้สามารถดูไฟล์ JS ได้
 
−
 
 
−
=== ทำความเข้าใจ “อะไรเป็น secret” ในสถาปัตยกรรม Flask + React ===
 
−
==== อะไรที่ควรอยู่ฝั่ง Backend (Flask) เท่านั้น ====
 
−
 
 
−
* รหัสผ่าน DB, connection string
 
−
* API key ของบริการภายนอกที่มีสิทธิ์ “ทำอะไรได้จริง” (เช่น จ่ายเงิน, ส่งอีเมล, อ่านข้อมูลส่วนตัว)
 
−
* JWT signing key / session secret / Flask SECRET_KEY
 
−
* Private keys (เช่น OAuth client secret, service account key)
 
−
 
 
−
==== อะไรที่ “ไม่ใช่ secret” และอยู่ฝั่ง Frontend ได้ ====
 
−
 
 
−
* ค่า config ที่เป็น public เช่น base URL, feature flag บางชนิด, public analytics key (ที่ผู้ให้บริการออกแบบให้เปิดเผยได้)
 
−
* OAuth '''client id''' มักไม่ถือเป็น secret (แต่ '''client secret''' เป็น secret)
 
−
 
 
−
=== Git และการป้องกันการหลุดเข้าระบบควบคุมเวอร์ชัน ===
 
−
 
 
−
ใส่ไฟล์ secret ใน ''.gitignore'' เช่น
 
−
 
 
−
* ''.env''
 
−
* ''config.local.json''
 
−
* ''.pem'', ''.key''
 
−
 
 
−
ใช้ ''pre-commit hook'' หรือเครื่องมือสแกน secret เพื่อกันพลาด (เช่นตรวจพบ pattern ของ key ก่อน commit)
 
−
 
 
−
ถ้าเผลอ commit ไปแล้ว:
 
−
 
 
−
* ถือว่า secret “รั่ว” แล้ว (แม้จะ revert ก็ยังอยู่ใน history)
 
−
* รีบ '''revoke/rotate''' key
 
−
* พิจารณา rewrite history (แต่ต้องเข้าใจผลกระทบกับทีม)
 
−
 
 
−
=== การเก็บ secret ระหว่าง Development ===
 
−
==== ใช้ Environment Variables ====
 
−
แนวทางที่พบบ่อยสุดคือเก็บ secret ใน environment variables แล้วให้ Flask อ่านจาก env
 
−
 
 
−
ข้อดี: ไม่ต้องใส่ลงโค้ด, แยก env ได้ง่าย
 
−
 
 
−
ข้อควรระวัง: อย่า log ค่า env ออกมา, และอย่าให้ dump env ใน error page
 
−
 
 
−
==== ใช้ไฟล์ .env ในเครื่องตัวเอง (dev only) ====
 
−
 
 
−
ใช้ ''.env'' สำหรับ dev และใส่ลง ''.gitignore''
 
−
 
 
−
ทำไฟล์ตัวอย่าง ''(.env.example)'' ที่ไม่มี secret จริง เช่น
 
−
 
 
−
''DATABASE_URL=postgresql://USER:PASSWORD@HOST/DB'' (ใส่ placeholder)
 
−
''STRIPE_SECRET_KEY=...'' (placeholder)
 
−
 
 
−
=== การเก็บ secret ใน Production ===
 
−
==== ใช้ Secret Manager ของแพลตฟอร์ม ====
 
−
แนวปฏิบัติทั่วไป:
 
−
 
 
−
* Docker/Kubernetes: ใช้ ''Kubernetes Secrets'' + mount เป็น env หรือไฟล์
 
−
* Cloud: ใช้ secret manager (เช่น AWS/GCP/Azure) แล้วดึงตอนรัน
 
−
* PaaS: ตั้งค่า secret ผ่าน dashboard/CLI (เช่น environment config ของ platform)
 
−
 
 
−
หลักสำคัญ:
 
−
 
 
−
* จำกัดสิทธิ์การเข้าถึง secret manager ให้เฉพาะ service account ของแอป
 
−
* audit log ได้ว่าใคร/อะไรเข้าถึง secret
 
−
 
 
−
==== หลีกเลี่ยงการวาง secret ไว้ใน image/build artifact ====
 
−
 
 
−
อย่า bake secret เข้า Docker image
 
−
 
 
−
อย่าให้ขั้นตอน build ของ React รับ secret จริง (เพราะจะถูก bundle ลงไฟล์ JS)
 
−
 
 
−
=== Flask: จุดที่เกี่ยวกับ secret โดยตรง ===
 
−
==== Flask SECRET_KEY และ session security ====
 
−
 
 
−
ตั้งค่า ''SECRET_KEY'' จาก env
 
−
 
 
−
ห้ามใช้ค่าเดิมระหว่างหลาย environment
 
−
 
 
−
หมุนคีย์แล้วกระทบ session (ผู้ใช้อาจถูก logout) — ถือเป็นเรื่องปกติ
 
−
 
 
−
==== Database credentials / connection string ====
 
−
 
 
−
อ่านจาก env เช่น ''DATABASE_URL''
 
−
 
 
−
ให้ DB user มีสิทธิ์เท่าที่ต้องใช้ (แยก read/write ถ้าทำได้)
 
−
 
 
−
==== JWT / OAuth / API signing keys ====
 
−
 
 
−
เก็บ private/signing key ฝั่ง backend เท่านั้น
 
−
 
 
−
แยก key ต่อ environment
 
−
 
 
−
พิจารณาใช้ key id (kid) เพื่อรองรับ rotation หลายคีย์พร้อมกัน
 
−
 
 
−
=== React: สิ่งที่ต้องระวังเป็นพิเศษ ===
 
−
==== ทุกอย่างที่อยู่ใน React build “ไม่ลับ” ====
 
−
 
 
−
ค่าใน ''process.env'' ที่ถูก inject ตอน build จะไปอยู่ใน bundle
 
−
 
 
−
ต่อให้ obfuscate ก็ยังดึงได้
 
−
 
 
−
==== ถ้าต้องเรียกบริการภายนอก ให้ทำผ่าน Backend เป็น proxy ====
 
−
ตัวอย่างสถานการณ์:
 
−
 
 
−
React ต้องเรียก API ที่ต้องใช้ secret → ให้ React เรียก Flask ก่อน แล้ว Flask ใส่ secret เรียกต่อ
 
−
 
 
−
จะได้ควบคุม:
 
−
* rate limit
 
−
* validation
 
−
* logging/audit
 
−
* permission ตาม user
 
−
 
 
−
==== การตั้งค่าฝั่ง frontend แบบปลอดภัย ====
 
−
 
 
−
เก็บเฉพาะ public config เช่น ''REACT_APP_API_BASE_URL''
 
−
 
 
−
ถ้าต้องการ runtime config ให้เสิร์ฟไฟล์ config จาก backend (ที่ไม่มี secret) แทนการ bake ตอน build
 
−
 
 
−
=== การส่ง secret ระหว่างบริการ (backend ↔ external services) ===
 
−
 
 
−
* ใช้ HTTPS เสมอ
 
−
* ตั้ง timeout และ retry policy (ลดโอกาสหลุด log แปลก ๆ)
 
−
* อย่าใส่ secret ใน query string (URL) เพราะอาจหลุดใน:
 
−
** server access logs
 
−
** browser history
 
−
** referrer headers
 
−
 
 
−
=== Logging / Monitoring / Error handling ===
 
−
 
 
−
* '''อย่า log secret''' (รวมถึง request headers เช่น ''Authorization'')
 
−
 
 
−
* ทำ ''redaction'' ใน logger:
 
−
** mask token เหลือท้าย 4 ตัว
 
−
** remove fields เช่น ''password'', ''api_key'', ''secret''
 
−
 
 
−
* ระวัง error page / stack trace ใน production:
 
−
** ปิด debug mode
 
−
** จัดการ exception แล้วตอบ error แบบไม่เผยข้อมูลภายใน
 
−
 
 
−
=== การจัดการสิทธิ์และการหมุนคีย์ (Rotation) ===
 
−
 
 
−
* มีนโยบาย rotation เช่น ทุก 60–90 วัน (แล้วแต่ความเสี่ยง)
 
−
* รองรับ rollout แบบไม่ downtime:
 
−
** backend ยอมรับทั้ง “คีย์เก่าและคีย์ใหม่” ช่วงหนึ่ง (dual keys)
 
−
** แล้วค่อย revoke คีย์เก่า
 
−
 
 
−
เก็บประวัติการออกคีย์ / revoke / ผู้รับผิดชอบ
 
−
 
 
−
=== การทดสอบและ CI/CD ===
 
−
 
 
−
* ใน CI ให้ใช้ secret store ของระบบ CI (เช่น GitHub Actions Secrets / GitLab CI Variables)
 
−
* แยก secret สำหรับ test/staging โดยเฉพาะ
 
−
* ใน unit test หลีกเลี่ยงการใช้ secret จริง:
 
−
** mock external API
 
−
** ใช้ dummy key ที่ไม่มีสิทธิ์
 
−
 
 
−
=== Checklist แบบสั้น ===
 
−
 
 
−
* ไม่มี secret ใน repo (รวม history)
 
−
* ใช้ env vars / secret manager แทน hardcode
 
−
* React ไม่มี secret ใด ๆ ใน bundle
 
−
* Flask ปิด debug ใน production
 
−
* logger มีการ redaction (Authorization/password/api_key)
 
−
* แยก secret ต่อ environment + least privilege
 
−
* มีแผน rotation/revoke และทำได้จริง
 
−
 
 
−
=== ตัวอย่างโครงสร้างไฟล์ที่พบบ่อย ===
 
−
 
 
−
* ''backend/''
 
−
** ''.env'' (ignored)
 
−
** ''.env.example'' (commit ได้)
 
−
** ''app/config.py'' (อ่านค่าจาก env)
 
−
 
 
−
* ''frontend/''
 
−
** ''.env'' (มักไม่ใส่ secret; ถ้ามีให้เป็นแค่ public config)
 
−
** ''.env.production'' (ระวัง: ยังถือว่า public หลัง build)
 
−
** ''src/config.ts'' (อ่าน public config)
 
−
 
 
−
ถ้าคุณอยากได้ “ตัวอย่าง template” สำหรับ Flask config + วิธีเสิร์ฟ runtime config ให้ React (แบบไม่ bake ตอน build) บอกสแต็กที่ใช้ deploy (เช่น Docker/K8s/Render/Fly/EC2) เดี๋ยวผมเขียนให้เป็นแพตเทิร์นครบชุดได้เลย.
 
−
 
 
−
== ทดลองกับบัญชีผู้ใช้ฐานข้อมูล mysql ==
 
  
 
เราได้ส่งบัญชีและรหัสผ่านผู้ใช้ mysql บนเครื่อง p1.secondtrain.org แล้ว  เราจะเริ่มโดยย้ายฐานข้อมูลของ Todo app ของเราไปใช้ mysql บนเซิร์ฟเวอร์  จากนั้นเราจะจัดการกับความลับนี้
 
เราได้ส่งบัญชีและรหัสผ่านผู้ใช้ mysql บนเครื่อง p1.secondtrain.org แล้ว  เราจะเริ่มโดยย้ายฐานข้อมูลของ Todo app ของเราไปใช้ mysql บนเซิร์ฟเวอร์  จากนั้นเราจะจัดการกับความลับนี้

รุ่นแก้ไขเมื่อ 16:08, 26 กุมภาพันธ์ 2569

หน้านี้เป็นส่วนของวิชา01204223

เราจะฝึกจัดการกับข้อมูลที่เป็นความลับในการพัฒนาเว็บแอพ

ก่อนอื่นอ่านภาพรวมในการจัดการก่อน อ่านที่นี่: 01204223/secrets overview

เราได้ส่งบัญชีและรหัสผ่านผู้ใช้ mysql บนเครื่อง p1.secondtrain.org แล้ว เราจะเริ่มโดยย้ายฐานข้อมูลของ Todo app ของเราไปใช้ mysql บนเซิร์ฟเวอร์ จากนั้นเราจะจัดการกับความลับนี้

เปลี่ยนฐานข้อมูล

จัดการกับรหัสผ่าน