วิธี Audit Content Security Policy (CSP) ของบริษัท SaaS พร้อม Evidence ที่ทีม Engineering และ Privacy ควรเก็บ
ขั้นตอน Audit CSP สำหรับทีม Engineering และ Privacy ใน SaaS ตั้งแต่ตรวจว่ามี Header อยู่แล้วหรือไม่ อ่านค่า Directive ปัจจุบัน จนถึงเก็บ Evidence จาก Violation Report

💬 สรุปสั้น ๆ
การ Audit CSP เริ่มจากตรวจ Response Header ของแต่ละ Environment ด้วย Developer Tools หรือ curl อ่านค่า Directive ที่มีอยู่ว่าหลวมหรือแน่น แล้วเก็บ Violation Report เป็น Evidence เทียบกับ Allow-list ที่ Privacy Team อนุมัติไว้
สารบัญ
ก่อนบอกว่าทีมจะ "ปรับปรุง CSP" ต้องรู้ก่อนว่าตอนนี้มี CSP อยู่แล้วหรือไม่ และถ้ามีมันหลวมแค่ไหน หลายทีมเข้าใจผิดว่าเคยตั้งค่าไว้ตั้งแต่ต้นปีแล้ว แต่พอตรวจจริงกลับพบว่า Header หายไปตั้งแต่ Deploy ครั้งที่เปลี่ยน Infrastructure หรือมีอยู่แต่เปิด unsafe-inline ทิ้งไว้จนนโยบายแทบไม่มีความหมาย
บทความนี้เป็นแนวทาง Audit สำหรับทีม Engineering และ Privacy ใช้ตรวจสถานะ CSP จริงของแอป พร้อมวิธีเก็บ Evidence ไว้ประกอบการตัดสินใจปรับปรุง อ้างอิงหลักการ Security Finding ที่ต้องมี Evidence และ Context ตามแนวทาง ศูนย์ความรู้ Website Security
วิธีตรวจว่าแอป SaaS มี Header CSP อยู่แล้วหรือไม่
เปิด Developer Tools แท็บ Network โหลดหน้าเว็บแล้วดู Response Header ของ Request แรกสุด หรือใช้คำสั่ง curl แบบ -I ยิงไปที่โดเมน Production เพื่อดู Header ที่ตอบกลับมาโดยไม่ผ่านการ Render ของเบราว์เซอร์ ตรวจทั้งสองแบบเพราะบางระบบ Cache หรือ CDN อาจส่ง Header ต่างจาก Origin Server จริง
ถ้าไม่พบ Header Content-Security-Policy หรือ Content-Security-Policy-Report-Only เลย แปลว่าแอปยังไม่มี CSP ใช้งานอยู่ ต้องเริ่มจากขั้นตอนออกแบบใหม่ทั้งหมด
วิธีอ่านค่า Header ปัจจุบันและประเมินความหลวมแน่น
ถ้าพบ Header อยู่แล้ว ให้แกะทีละ Directive แล้วประเมินจุดที่มักหลวมเกินไป
- มี unsafe-inline หรือ unsafe-eval อยู่ใน script-src หรือไม่ ถ้ามีแปลว่านโยบายแทบไม่ได้ป้องกัน Script Injection เลย
- มี Wildcard เช่น * หรือ https: แบบเปิดกว้างทั้งโปรโตคอลอยู่ใน Directive ใดหรือไม่
- Directive สำคัญอย่าง object-src หรือ base-uri ถูกกำหนดไว้หรือไม่ ถ้าไม่มีเลยแปลว่ายังไม่ได้ปิดช่องโหว่พื้นฐาน
- frame-ancestors ตรงกับรายชื่อโดเมนที่อนุญาตฝัง Embed Widget จริงหรือเปิดกว้างเกินจำเป็น
วิธีตรวจ Environment Drift ระหว่าง Dev, Staging และ Production
ตรวจ Header เดียวกันในทั้งสาม Environment แล้วเทียบกัน ปัญหาที่พบบ่อยคือ Staging ใช้ Report-Only แต่ Production ใช้ Enforce โดยไม่มีใครจำได้ว่าทำไมถึงต่างกัน หรือ Dev ไม่มี Header เลยทำให้ทีมพัฒนาไม่เคยเจอ Error จนกว่าจะ Deploy จริง
บันทึกผลการตรวจแต่ละ Environment พร้อมวันที่ตรวจ เพื่อใช้เทียบกับรอบ Audit ครั้งถัดไปว่ามีการเปลี่ยนแปลงหรือไม่
วิธีเก็บ Evidence จาก CSP Violation Report เพื่อวิเคราะห์ Coverage Gap
ถ้ามี Endpoint report-uri หรือ report-to อยู่แล้ว ให้ดึงรายงานย้อนหลังมาไล่ดูว่าโดเมนไหนถูก Block บ่อยที่สุด รายงานที่เกิดซ้ำจากโดเมนเดียวกันต่อเนื่องมักแปลว่า Allow-list ยังไม่ครบ ไม่ใช่การโจมตีจริง แต่ต้องแยกให้ออกจากรายงานที่มาจาก Browser Extension ของผู้ใช้ ซึ่งไม่เกี่ยวกับนโยบายของแอป
สรุปรายงานเป็นตารางที่ระบุ โดเมนที่ถูก Block, จำนวนครั้ง, Directive ที่เกี่ยวข้อง และข้อสรุปว่าควรเพิ่มเข้า Allow-list หรือปล่อยให้ถูกบล็อกต่อไป ใช้ตารางนี้เป็น Evidence เวลาคุยกับ Privacy Team
วิธีตรวจ Allow-list สคริปต์ Growth/Analytics ว่ายังตรงกับที่ Privacy Team อนุมัติหรือไม่
เทียบรายชื่อโดเมนใน script-src และ connect-src ปัจจุบัน กับบันทึกการอนุมัติของ Privacy Team ที่เก็บไว้ ถ้าพบโดเมนที่อยู่ใน Header จริงแต่ไม่มีบันทึกการอนุมัติ แปลว่ามีคนแก้ Policy โดยไม่ผ่านขั้นตอน ต้องสอบถามที่มาและตัดสินใจว่าจะเก็บหรือถอดออก ดูขั้นตอนการอนุมัติที่ควรใช้ต่อไปใน คู่มือวางระบบ CSP แบบเป็นขั้นตอน
ผลการตรวจ Allow-list ทุกรอบควรบันทึกไว้เป็นรอบต่อรอบ เพื่อใช้เทียบกับ รอบทบทวน CSP ประจำปี ในอนาคต
ตัวอย่างการอ่านรายงาน Violation แบบ JSON
รายงานที่เบราว์เซอร์ส่งกลับผ่าน report-to มักอยู่ในรูปแบบ JSON ที่ระบุ Directive ที่ถูกละเมิด โดเมนต้นทางของทรัพยากรที่ถูกบล็อก และ URL ของหน้าที่เกิดเหตุการณ์ ทีมตรวจสอบควรอ่านฟิลด์เหล่านี้อย่างเป็นระบบแทนการไล่ดูทีละบรรทัดในระบบ Log
- blocked-uri — โดเมนหรือทรัพยากรที่ถูกบล็อกจริง ใช้เทียบกับ Allow-list ว่าควรเพิ่มหรือไม่
- violated-directive — Directive ที่ทำให้เกิดการบล็อก บอกว่าเป็นปัญหาที่ script-src, style-src หรือ Directive อื่น
- document-uri — หน้าเว็บที่เกิด Violation ช่วยระบุว่าปัญหาเกิดกับ Flow ไหนของผลิตภัณฑ์
- disposition — ระบุว่ารายงานนี้มาจาก Enforce จริง (enforce) หรือมาจาก Report-Only (report) ซึ่งสำคัญมากเวลาวิเคราะห์ผลกระทบจริง
จัดกลุ่มรายงานตาม blocked-uri แล้วเรียงตามความถี่ จะเห็นชัดว่าโดเมนไหนเป็นปัญหาเชิงระบบที่ต้องแก้ Allow-list กับโดเมนไหนเป็นแค่ Noise จาก Browser Extension ของผู้ใช้บางราย ซึ่งมักมี URL รูปแบบแปลกที่ไม่ตรงกับ Vendor ใดในระบบเลย
วิธีจัดลำดับความสำคัญของสิ่งที่พบระหว่าง Audit
ผล Audit มักออกมาเป็นรายการยาวที่มีทั้งเรื่องเล็กและเรื่องใหญ่ปนกัน ทีมที่ไม่จัดลำดับความสำคัญก่อนมักหมดเวลาไปกับการแก้จุดที่ไม่กระทบอะไรมาก ในขณะที่ช่องโหว่จริงยังค้างอยู่ ให้แบ่งสิ่งที่พบเป็นสามระดับ
- ระดับสูง — ไม่มี Header CSP เลยในหน้าที่รับข้อมูล Login หรือ Payment, หรือมี unsafe-inline/unsafe-eval อยู่ใน script-src ของหน้าที่จัดการข้อมูลอ่อนไหว ควรแก้ภายในสัปดาห์เดียวกันที่พบ
- ระดับกลาง — Environment Drift ระหว่าง Staging กับ Production หรือ Allow-list ที่มีโดเมนไม่ตรงกับบันทึกอนุมัติ ควรมีแผนแก้ภายในหนึ่งเดือน
- ระดับต่ำ — Directive ที่หลวมกว่ามาตรฐานแนะนำแต่ยังไม่กระทบข้อมูลอ่อนไหวโดยตรง เช่น font-src เปิดกว้างเกินจำเป็น เก็บไว้ในแผนปรับปรุงรอบถัดไปได้
การให้ระดับความสำคัญแบบนี้ช่วยให้ทีม Engineering คุยกับผู้บริหารหรือ Privacy Team ได้ตรงประเด็นมากขึ้น แทนที่จะเสนอรายการยาวโดยไม่มีลำดับ ทำให้การจัดสรรเวลาทีมแก้ไขปัญหาที่กระทบจริงก่อนเสมอ
ตัวอย่างสถานการณ์ Audit จริงที่พบบ่อยในทีม SaaS
ทีม Engineering ทีมหนึ่งตรวจ Header บน Production แล้วพบว่า Policy เดิมเปิด unsafe-inline ไว้ในทั้ง script-src และ style-src มาตั้งแต่ตั้งค่าครั้งแรกเมื่อสองปีก่อน ไม่มีใครจำได้ว่าทำไมถึงเปิดไว้กว้างขนาดนั้น เมื่อไล่ดู Commit History จึงพบว่าเป็นการแก้ไขเร่งด่วนเพื่อให้ Feature หนึ่งใช้งานได้ทันกำหนดเปิดตัว แล้วไม่มีใครกลับมาปิดทีหลัง กรณีนี้สะท้อนว่าการ Audit ควรตรวจ Commit History ควบคู่กับ Header ปัจจุบัน เพื่อเข้าใจที่มาของการตั้งค่าที่หลวมก่อนตัดสินใจแก้ไข
อีกกรณีหนึ่งคือทีมที่พบว่า Staging ไม่มี Header CSP เลย ในขณะที่ Production มี Header ครบ เมื่อสอบถามจึงพบว่า Staging ถูกตั้งค่าให้ปิด Security Header ไว้เพื่อความสะดวกตอนพัฒนา แต่ไม่มีใครแจ้งทีมทดสอบ ทำให้ Test Suite ที่รันบน Staging ไม่เคยจับ Error ที่เกี่ยวกับ CSP ได้เลย จนกระทั่งเกิดปัญหาจริงหลัง Deploy ขึ้น Production กรณีนี้จึงต้องแก้ทั้งการตั้งค่า Staging ให้ตรงกับ Production และทบทวนว่า Test Suite ครอบคลุมพอหรือไม่
พร้อมตรวจสอบความน่าเชื่อถือของเว็บไซต์คุณหรือยัง?
ทดลองใช้งาน trusty ฟรี ไม่ต้องใช้บัตรเครดิต เริ่มสแกนได้ทันที
เครื่องมืออัตโนมัติที่ช่วยให้ Audit CSP เป็นรอบสม่ำเสมอ
การ Audit ด้วยมือทุกรอบใช้เวลานานและเสี่ยงพลาดจุดที่ไม่ได้ตรวจ ทีมที่มี Traffic สูงควรพิจารณาใช้เครื่องมืออัตโนมัติเสริม เช่น สคริปต์ที่ยิง curl ไปยังทุก Environment ตามตารางเวลาแล้วเทียบ Header กับค่าที่คาดหวังไว้ หรือ Job ที่ดึง Violation Report เข้าระบบสรุปผลอัตโนมัติแทนการดึงด้วยมือทุกครั้ง เครื่องมือเหล่านี้ไม่ได้แทนที่การ Audit เชิงลึกโดยคน แต่ช่วยจับความผิดปกติเบื้องต้นได้เร็วกว่า และทำให้รอบ Audit เต็มรูปแบบมีข้อมูลตั้งต้นที่พร้อมกว่าการเริ่มนับหนึ่งใหม่ทุกครั้ง
วิธีสื่อสารผล Audit ให้ทีมที่ไม่ใช่สาย Engineering เข้าใจ
ผล Audit ที่เขียนเป็นศัพท์เทคนิคล้วน เช่น รายชื่อ Directive และ Hash มักไม่มีประโยชน์เมื่อต้องคุยกับผู้บริหารหรือฝ่ายที่ไม่ได้ดูแลระบบโดยตรง ควรสรุปผลเป็นภาษาที่จับต้องได้ เช่น จำนวนโดเมนที่ยังไม่ได้รับการอนุมัติ ระดับความเสี่ยงของแต่ละจุดที่พบ และแผนแก้ไขพร้อมกำหนดเวลาที่ชัดเจน แทนที่จะส่งรายงานดิบที่มีแต่ Log และ Header ให้อ่านเอง การสรุปแบบนี้ยังช่วยให้ฝ่าย Privacy Team ตัดสินใจอนุมัติงบประมาณหรือเวลาที่ทีม Engineering ต้องใช้แก้ไขได้เร็วขึ้น เพราะเห็นภาพรวมความเสี่ยงชัดเจนตั้งแต่หน้าแรกของรายงาน
ความแตกต่างระหว่าง Audit ครั้งแรกกับ Audit รอบถัดไป
Audit ครั้งแรกมักใช้เวลานานเพราะต้องไล่ตรวจทุกจุดตั้งแต่ศูนย์ ไม่มีข้อมูลเก่าให้เทียบ ทีมจึงควรเผื่อเวลาให้มากกว่ารอบถัดไปอย่างน้อยสองเท่า ในขณะที่ Audit รอบถัดไปจะเร็วขึ้นมากถ้ามีบันทึกผลรอบก่อนหน้าไว้ครบ เพราะสามารถเทียบเฉพาะส่วนที่เปลี่ยนแปลงแทนการตรวจทุกจุดใหม่ทั้งหมด ความแตกต่างนี้เป็นเหตุผลสำคัญที่ต้องบันทึกผล Audit ทุกรอบอย่างละเอียด ไม่ใช่แค่สรุปว่า "ผ่าน" หรือ "ไม่ผ่าน" โดยไม่มีรายละเอียดประกอบ เพราะข้อมูลเหล่านี้คือสิ่งที่ทำให้ Audit รอบต่อไปเร็วและแม่นยำขึ้น
เช็กลิสต์ปฏิบัติ
- ตรวจ Response Header ด้วยทั้ง Developer Tools และ curl บนทุก Environment
- ไล่ดูทุก Directive ว่ามี unsafe-inline, unsafe-eval หรือ Wildcard ที่หลวมเกินไปหรือไม่
- เทียบ Header ระหว่าง Dev, Staging และ Production เพื่อหา Environment Drift
- ดึง Violation Report ย้อนหลังมาสรุปเป็นตาราง โดเมน จำนวนครั้ง และข้อสรุป
- เทียบ Allow-list ปัจจุบันกับบันทึกการอนุมัติของ Privacy Team ทุกโดเมน
- บันทึกผล Audit พร้อมวันที่ตรวจไว้เป็นหลักฐานสำหรับรอบถัดไป
- จัดลำดับความสำคัญของสิ่งที่พบเป็นสามระดับก่อนเสนอแผนแก้ไข
ข้อผิดพลาดที่พบบ่อย
- ตรวจ Header เฉพาะบน Local Development แล้วสรุปว่า Production มีค่าเดียวกัน ทั้งที่ไม่เคยตรวจจริง
- เห็นว่ามี Header CSP อยู่แล้วก็ถือว่าปลอดภัย โดยไม่ได้แกะดูว่า Directive แต่ละตัวหลวมแค่ไหน
- ไม่แยกรายงาน Violation ที่มาจาก Browser Extension ของผู้ใช้ ออกจากรายงานที่เกี่ยวกับ Policy ของแอปจริง
- ไม่มีบันทึกว่าใครอนุมัติโดเมนไหนเมื่อไร ทำให้ Audit ครั้งถัดไปต้องเริ่มนับหนึ่งใหม่ทุกครั้ง
- สรุปผล Audit ว่า CSP "ครบแล้ว" ทั้งที่ยังไม่ได้ตรวจ frame-ancestors หรือ object-src เลย
สรุป
การ Audit CSP ที่ได้ผลจริงต้องเริ่มจากตรวจ Header ที่มีอยู่จริงในทุก Environment ไม่ใช่เดาจากเอกสารเก่า ไล่ดูความหลวมแน่นของแต่ละ Directive เก็บ Evidence จาก Violation Report และเทียบ Allow-list กับบันทึกการอนุมัติของ Privacy Team ทุกครั้ง ผลลัพธ์ของ Audit ควรออกมาเป็นรายการที่ชัดเจนว่าจุดไหนต้องแก้ก่อนหลัง
แหล่งข้อมูลอ้างอิง
คำถามที่พบบ่อย
ตรวจ CSP Header ด้วยวิธีไหนเชื่อถือได้มากที่สุด ควรตรวจทั้งผ่าน Developer Tools บนเบราว์เซอร์จริงและผ่านคำสั่ง curl -I บน Production โดยตรง เพราะบาง CDN หรือ Cache Layer อาจส่ง Header ต่างจาก Origin Server
ถ้าพบ unsafe-inline อยู่ใน Header ปัจจุบันควรทำอย่างไร ให้บันทึกไว้เป็นจุดที่ต้องแก้ไข และวางแผนเปลี่ยนไปใช้ Nonce หรือ Hash แทน โดยทดสอบใน Staging ก่อนนำ Policy ที่รัดกุมขึ้นไปใช้ Production
Violation Report ที่เกิดซ้ำจากโดเมนเดียวกันแปลว่าอะไร ส่วนใหญ่แปลว่า Allow-list ยังไม่ครบ ไม่ใช่การโจมตี ให้ตรวจว่าโดเมนนั้นมาจาก SDK หรือ Widget ที่ผลิตภัณฑ์ใช้งานจริงหรือไม่ ก่อนตัดสินใจเพิ่มเข้า Allow-list
ทำไมต้องตรวจ Header ทั้ง Dev, Staging และ Production แยกกัน เพราะ Environment Drift เป็นปัญหาที่พบบ่อย บาง Environment อาจยังใช้ Report-Only ในขณะที่อีก Environment เปลี่ยนเป็น Enforce ไปแล้วโดยไม่มีการซิงก์ค่ากัน การตรวจแยกแต่ละ Environment ช่วยจับความต่างนี้ได้ตั้งแต่ก่อนเกิดปัญหาจริงกับผู้ใช้
คำถามที่พบบ่อย
ตรวจ CSP Header ด้วยวิธีไหนเชื่อถือได้มากที่สุด
ควรตรวจทั้งผ่าน Developer Tools บนเบราว์เซอร์จริงและผ่านคำสั่ง curl -I บน Production โดยตรง เพราะบาง CDN หรือ Cache Layer อาจส่ง Header ต่างจาก Origin Server
ถ้าพบ unsafe-inline อยู่ใน Header ปัจจุบันควรทำอย่างไร
ให้บันทึกไว้เป็นจุดที่ต้องแก้ไข และวางแผนเปลี่ยนไปใช้ Nonce หรือ Hash แทน โดยทดสอบใน Staging ก่อนนำ Policy ที่รัดกุมขึ้นไปใช้ Production
Violation Report ที่เกิดซ้ำจากโดเมนเดียวกันแปลว่าอะไร
ส่วนใหญ่แปลว่า Allow-list ยังไม่ครบ ไม่ใช่การโจมตี ให้ตรวจว่าโดเมนนั้นมาจาก SDK หรือ Widget ที่ผลิตภัณฑ์ใช้งานจริงหรือไม่ ก่อนตัดสินใจเพิ่มเข้า Allow-list
ทำไมต้องตรวจ Header ทั้ง Dev, Staging และ Production แยกกัน
เพราะ Environment Drift เป็นปัญหาที่พบบ่อย เช่น Staging ยังใช้ Report-Only แต่ Production เปลี่ยนเป็น Enforce ไปแล้วโดยไม่มีการซิงก์ค่ากัน การตรวจแยกช่วยจับความต่างนี้ได้ตั้งแต่ก่อนเกิดปัญหา
บทความที่เกี่ยวข้อง (Related Articles)
ดูบทความอื่นในหมวด Website Securityรวมคู่มือและเช็กลิสต์ที่เกี่ยวข้องกับหัวข้อนี้ใน Trusty Knowledge Centerอ่านต่อในหัวข้อเดียวกัน

อัปเดต Content Security Policy (CSP) ปี 2026: สิ่งที่ทีม Product, Engineering และ Privacy ใน SaaS ต้องทบทวนรอบใหม่
แนวทางทบทวน CSP รอบใหม่สำหรับทีม Product, Engineering และ Privacy ใน SaaS ปี 2026 เน้นสิ่งที่มักเปลี่ยนแล้วทำให้นโยบายเดิมล้าสมัยโดยไม่มีใครรู้ตัว

เช็กลิสต์ Content Security Policy (CSP) สำหรับทีม Product, Engineering และ Privacy ก่อนเปิดใช้งานจริงใน SaaS
รวมรายการตรวจที่ทีม Product, Engineering และ Privacy ใน SaaS ใช้ก่อนเปิดใช้งาน CSP จริง แยกตามขั้นก่อนเขียน ระหว่างทดสอบ และก่อน Enforce
เนื้อหานี้จัดทำขึ้นเพื่อให้ข้อมูลทั่วไปเท่านั้น ไม่ถือเป็นคำแนะนำทางกฎหมาย กรุณาปรึกษาผู้เชี่ยวชาญด้านกฎหมายหรือ Data Protection Officer ของหน่วยงานท่านก่อนนำไปปฏิบัติจริง
พร้อมตรวจสอบความน่าเชื่อถือของเว็บไซต์คุณหรือยัง?
ทดลองใช้งาน trusty ฟรี ไม่ต้องใช้บัตรเครดิต เริ่มสแกนได้ทันที