ใช้เช็คลิสต์ความปลอดภัย Claude Code เพื่อรันการตรวจจุดเว็บแอปแบบด่วนที่ชัดเจนเกี่ยวกับ auth, การตรวจรับค่าเข้า, การจัดการความลับ และพื้นผิวการฉีด

การตรวจความปลอดภัยแบบสั้นเป็นการทบทวนอย่างรวดเร็ว (มัก 30–60 นาที) ที่ตั้งใจจับปัญหาเด่นชัดและมีผลกระทบสูงก่อนส่งขึ้นโปรดักชัน มันไม่ใช่การตรวจสอบเต็มรูปแบบ คิดว่ามันเหมือนการเดินตรวจความปลอดภัย: สแกนเส้นทางที่มักล้มเหลวในแอปจริงแล้วหาหลักฐาน ไม่ใช่การเดา
เช็คลิสต์ความปลอดภัยของ Claude Code ฉบับนี้โฟกัสที่ส่วนที่มักพังบ่อยในเว็บแอปทั่วไป:
มันไม่ได้พยายามพิสูจน์ว่าไม่มีบั๊ก, วิเคราะห์ผู้คุกคามเชิงซับซ้อน, หรือตัดสินใจแทนการทดสอบเชิงบุกรุก
"ข้อค้นพบเชิงรูปธรรม" หมายความว่าทุกปัญหาที่บันทึกมีหลักฐานที่นักพัฒนาสามารถทำงานต่อได้ทันที สำหรับแต่ละข้อค้นพบ จด:
AI เป็นผู้ช่วย ไม่ใช่ผู้เชี่ยวชาญ ใช้มันเพื่อค้นหา สรุป และเสนอการทดสอบ แล้วยืนยันโดยการอ่านโค้ดและถ้าเป็นไปได้ให้ทำซ้ำด้วยคำขอจริง ถ้ารุ่นไม่สามารถชี้ไปที่ตำแหน่งและขั้นตอนเฉพาะ ให้ถือว่าคำกล่าวนั้นยังไม่ได้รับการพิสูจน์
การตรวจแบบด่วนจะได้ผลถ้าคุณจำกัดเป้าหมาย ก่อนขอให้ Claude Code ดูอะไรก็ตาม ให้ตัดสินใจก่อนว่าคุณพยายามพิสูจน์อะไรวันนี้ และสิ่งใดคุณจะไม่ตรวจ
เริ่มจาก 1–3 เส้นทางผู้ใช้จริงที่ความผิดพลาดมีค่าเสียหาย เช่น เกิดค่าใช้จ่าย รั่วข้อมูล หรือให้สิทธิ์มากเกินไป ตัวอย่างที่ดีคือหน้าล็อกอิน การรีเซ็ตรหัสผ่าน ชำระเงิน และหน้าจอแก้ไขของแอดมิน
ถัดไป ระบุทรัพย์สินที่ต้องปกป้องให้ชัดเจน: บัญชีผู้ใช้ การกระทำที่เกี่ยวกับการชำระเงิน ข้อมูลส่วนบุคคล การดำเนินการเฉพาะแอดมิน
แล้วเขียนสมมติฐานภัยคุกคามด้วยคำง่าย ๆ คุณกำลังป้องกันผู้ใช้ที่แค่คลิกเล่น ผู้โจมตีภายนอกที่ใช้สคริปต์ หรือคนภายในที่มีสิทธิ์บ้าง? คำตอบเปลี่ยนว่า "พอรับได้" เป็นแบบไหน
สุดท้าย กำหนดเกณฑ์ผ่านและไม่ผ่านเพื่อให้การตรวจจบด้วยข้อค้นพบ ไม่ใช่ความรู้สึก กฎง่าย ๆ ใช้งานได้ดี:
ถ้าคุณบอกลักษณะความล้มเหลวไม่ได้ ขอบเขตยังไม่ชัดพอ
การตรวจจะได้ผลถ้ารุ่นดูตรงจุดที่ถูกต้อง รวบรวมชุดโค้ดและบันทึกเล็ก ๆ เพื่อให้การทบทวนออกมาเป็นหลักฐาน ไม่ใช่การเดา
เริ่มด้วยการแชร์เส้นทางที่สำคัญด้านความปลอดภัย: จุดเข้าคำขอและโค้ดที่ตัดสินว่าใครคือผู้ใช้และสามารถทำอะไรได้ รวมโค้ดรอบ ๆ พอให้เห็นการไหลของข้อมูล
ชุดที่ใช้งานได้จริงมักประกอบด้วย:
เพิ่มบันทึกสภาพแวดล้อมสั้น ๆ ให้สมมติฐานชัดเจน: session vs JWT, โทเค็นอยู่ที่ไหน (cookie หรือ header), พฤติกรรม reverse proxy หรือ API gateway, คิว/งาน cron, และจุดสิ้นสุดที่ "เฉพาะภายใน" ใด ๆ
ก่อนไล่หาบั๊ก ให้ขอ inventory: จุดเข้า, จุดสิ้นสุดกับสิทธิพิเศษ, และคลังข้อมูลที่ถูกแตะต้อง เพื่อป้องกันการพลาดพื้นผิว
ตกลงรูปแบบผลลัพธ์ด้วยว่าจะบังคับเป็นข้อค้นพบเชิงรูปธรรม ตารางง่าย ๆ ทำงานได้ดี: ข้อค้นพบ, ความรุนแรง, จุดสิ้นสุด/ไฟล์ที่ได้รับผลกระทบ, หลักฐาน (สเนปช็อตหรือช่วงบรรทัด), สถานการณ์โจมตี, ข้อเสนอการแก้ไข
กำหนดเวลา:
เป้าหมายไม่ใช่ครอบคลุมสมบูรณ์ แต่เป็นชุดข้อค้นพบที่ทดสอบได้เล็ก ๆ
เปิดแอปไว้ขณะอ่าน คลิกผ่าน UI และดูคำขอที่เกิดขึ้น บันทึกควรชี้ไปยังจุดสิ้นสุด พารามิเตอร์ และแหล่งข้อมูลเฉพาะ
เวิร์กโฟลว์ที่ทำได้ในครั้งเดียว:
นิสัยที่มีประโยชน์: สำหรับแต่ละข้อที่ "ดูเหมือนจะปกติ" ให้เขียนสิ่งที่คุณจะทำเพื่อทำลายมัน ถ้าคุณอธิบายการทำลายไม่ได้ แปลว่าคุณยังไม่ได้ตรวจจริง
Authentication คือจุดที่แอปตัดสินว่า "คำขอนี้เป็นของบุคคลนี้" การตรวจแบบด่วนไม่จำเป็นต้องอ่านทุกบรรทัด แต่มองหาจุดที่ระบุอัตลักษณ์แล้วตรวจทางลัดและเส้นทางล้มเหลว
หาตำแหน่งขอบเขตความเชื่อใจ: ที่ไหนอัตลักษณ์ถูกสร้างหรือยอมรับครั้งแรก อาจเป็น cookie session, token JWT, API key, หรือ mTLS ที่ขอบเครือข่าย ถาม Claude Code ให้ชี้ไฟล์และฟังก์ชันที่เปลี่ยน "anonymous" เป็น user id และแสดงทุกเส้นทางอื่นที่ทำได้เหมือนกัน
การตรวจ Authn ที่ควรสแกน:
ตัวอย่างปฏิบัติ: ถ้าอีเมลรีเซ็ตส่งกลับว่า "ไม่พบบัญชี" นั่นเป็นปัญหาการระบุผู้ใช้ แม้ข้อความจะทั่วไป ความต่างของเวลาในการตอบก็สามารถรั่วข้อมูลได้ ดังนั้นตรวจเวลาตอบด้วย
Authorization ทำความเสียหายมากที่สุดเมื่อผิด: "ผู้ใช้นี้ได้รับอนุญาตให้ทำการนี้บนทรัพยากรนี้หรือไม่?" การตรวจแบบด่วนควรพยายามทำลายสมมติฐานนั้นโดยตั้งใจ
เขียนบทบาทและสิทธิ์เป็นภาษาง่าย ๆ เช่น:
แล้วยืนยันว่าทุกการกระทำที่สำคัญบังคับใช้ authz ฝั่งเซิร์ฟเวอร์ ไม่ใช่แค่ใน UI ปุ่มถูกซ่อนได้ แต่ผู้โจมตียังสามารถเรียก API ได้โดยตรง
สแกนอันที่มักเจอปัญหาจริง:
กลิ่น IDOR คลาสสิกง่าย ๆ คือคำขออย่าง GET /projects/{id} ที่ {id} ควบคุมโดยผู้ใช้ และเซิร์ฟเวอร์โหลดโดยไม่ตรวจว่าเป็นของผู้ใช้หรือตัวตนใน tenant เดียวกันหรือไม่
พรอมต์ที่บังคับคำตอบจริง:
"สำหรับ endpoint นี้ แสดงโค้ดที่ตัดสินการเข้าถึงอย่างแม่นยำ และระบุเงื่อนไขเฉพาะที่จะทำให้ผู้ใช้จาก orgId อื่นเข้าถึงได้ หากไม่มี ให้ชี้แจงว่าทำไมโดยระบุไฟล์และชื่อฟังก์ชัน"
ปัญหาเว็บแอปส่วนใหญ่เริ่มจากช่องว่าง: แอปยอมรับอินพุตที่นักพัฒนาไม่ได้คาดคิด ถือว่า "อินพุต" เป็นทุกอย่างที่ผู้ใช้หรือระบบอื่นควบคุมได้ แม้มันจะดูไร้พิษภัย
เริ่มจากการตั้งชื่ออินพุตสำหรับ endpoint ที่กำลังตรวจ:
การตรวจควรเกิดใกล้จุดที่ข้อมูลเข้ามา ไม่ใช่ลึกในตรรกะธุรกิจ ตรวจพื้นฐาน: ประเภท (string vs number), ความยาวสูงสุด, จำเป็นหรือไม่, และรูปแบบ (email, UUID, date)
สำหรับค่าที่รู้จัก เช่น role, status, หรือทิศทางการจัดเรียง ให้ใช้ allowlist จะยากต่อการบายพาสกว่าการพยายามบล็อกค่าที่ไม่ดี
ตรวจการจัดการข้อผิดพลาดด้วย หากแอปปฏิเสธอินพุต อย่าส่งค่าดิบกลับในคำตอบ บันทึก หรือ UI นั่นเป็นสาเหตุที่บั๊กการตรวจรับค่าน้อย ๆ กลายเป็นการรั่วข้อมูลหรือช่วยการฉีดโค้ด
แผนมินิ "อินพุตไม่ดี" สำหรับ endpoint เสี่ยง (ล็อกอิน, ค้นหา, อัปโหลด, การกระทำแอดมิน):
ตัวอย่าง: พารามิเตอร์ sort ที่รับสตริงใด ๆ อาจกลายเป็นชิ้นส่วน SQL ได้ในภายหลัง การใช้ allowlist เช่น "date" หรือ "price" จะป้องกันชั้นของข้อผิดพลาดนี้ตั้งแต่ต้น
การตรวจด่วนมักเจอปัญหาในที่เดียวกัน: ทุกที่ที่อินพุตผู้ใช้ถูกตีความเป็นโค้ด คิวรี เส้นทาง หรือ URL ส่วนนี้เป็นที่ที่คุณล่าช่วงที่ "อินพุตข้ามขอบเขตความเชื่อใจ"
ติดตามข้อมูลจากจุดเข้า (คิวรีพารามิเตอร์, เฮดเดอร์, คุกกี้, การอัปโหลด, ฟอร์มแอดมิน) ไปยังที่มันไปจบ
มองหาแพทเทิร์นเหล่านี้และขอที่มาของการเรียกใช้และตัวอย่างเพย์โลดสำหรับแต่ละอัน:
ORDER BY ไดนามิก, ตัวบิลเดอร์ IN (...) ที่ join ค่าจากผู้ใช้ระวังการดีซีเรียไรซ์และการฉีดเทมเพลตด้วย อะไรก็ตามที่พาร์ส JSON, YAML, หรือสตริงเทมเพลตจากผู้ใช้ อาจซ่อนพฤติกรรมเสี่ยง โดยเฉพาะเมื่อรองรับชนิดที่กำหนดเอง, นิพจน์ หรือการเรนเดอร์ฝั่งเซิร์ฟเวอร์
ถ้าฟีเจอร์รับ URL, ชื่อไฟล์, หรือข้อความที่ฟอร์แมตได้ ให้ถือว่ามันสามารถถูกใช้ในทางที่ผิดได้ จนกว่าจะพิสูจน์ด้วยเส้นทางโค้ดและการทดสอบ
ปัญหาความลับมักดังเมื่อตรวจเจอ โฟกัสที่ที่ความลับอยู่อาศัยและที่มันอาจถูกคัดลอกโดยไม่ตั้งใจ
ที่ที่ความลับมักโผล่:
แล้วบังคับคำตอบเชิงรูปธรรม: ถ้าความลับรั่ววันนี้ จะเกิดอะไรขึ้นต่อ? ระบบที่ดีมีเส้นทางโรเตชั่น (ออกคีย์ใหม่), การเพิกถอน (ปิดคีย์เก่า), และวิธี redeploy อย่างรวดเร็ว หากคำตอบคือ "เราจะเปลี่ยนทีหลัง" ให้ถือเป็นข้อค้นพบ
การให้สิทธิ์น้อยที่สุดเป็นทางชนะที่เร็ว เหตุการณ์แย่ลงเพราะคีย์มีสิทธิ์เกินควร มองหา user ฐานข้อมูลที่ DROP ตารางได้, โทเค็นบุคคลที่สามที่จัดการบัญชีได้, หรือ API key ที่ใช้ร่วมกันข้ามสภาพแวดล้อม ชอบหนึ่งคีย์ต่อบริการ ต่อสภาพแวดล้อม พร้อมสิทธิ์น้อยที่สุด
พรอมต์เช็คลัดที่นำไปวางใน Claude Code:
สุดท้าย ยืนยันเกตเเร็ล: บล็อกความลับออกจาก source control (pre-commit/CI), และตรวจว่าการสำรองหรือ snapshot ไม่รวมรหัสผ่านแบบ plain-text หากแพลตฟอร์มรองรับ snapshot และ rollback ให้ยืนยันว่าความลับถูกฉีดที่รันไทม์ ไม่ได้ถูกฝังในอิมเมจที่บันทึก
พรอมต์กว้างได้คำตอบกว้าง บังคับให้โมเดลยืนยันด้วยหลักฐาน: ตำแหน่งไฟล์จริง, เส้นทางการติดตามที่คุณทำได้, รีโปรที่รันได้, และสิ่งที่จะทำให้คำกล่าวผิด
ใช้แพทเทิร์นละข้อ แล้วให้มันแก้ไขหลังจากคุณยืนยันหรือปฏิเสธรายละเอียด
ถ้าผลลัพธ์ยังคลุมเครือ ให้บีบลง:
"ตอบเฉพาะด้วย: พาธไฟล์, ชื่อฟังก์ชัน, บรรทัดเสี่ยง, และผลกระทบหนึ่งประโยค"
จุดอัปเดตโปรไฟล์มักซ่อนบั๊กการควบคุมการเข้าถึง นี่คือกรณีสั้นที่คุณสามารถทำตามเช็คลิสต์นี้
สถานการณ์: endpoint API อัปเดตโปรไฟล์ผู้ใช้:
PATCH /api/profile?accountId=123 พร้อม JSON เช่น { "displayName": "Sam" }.
คุณขอให้ Claude Code หาฮэндเลอร์ ติดตามการใช้ accountId และพิสูจน์ว่าเซิร์ฟเวอร์ตรวจความเป็นเจ้าของหรือไม่
สิ่งที่มักพบ:
accountId จากคิวรีสตริงและอัปเดตบัญชีนั้นโดยไม่ตรวจว่าตรงกับผู้ใช้ที่ล็อกอินหรือไม่displayName ถูก trim แต่ accountId ไม่ถูกตรวจว่าเป็นจำนวนเต็ม"... WHERE account_id=" + accountIdรายงานที่ดีต้องชัดเจน:
accountId; SQL ถูกสร้างจากอินพุตที่ไม่น่าเชื่อถือaccountId จากไคลเอนต์ ใช้ id ของผู้ใช้ที่ผ่านการยืนยันทางฝั่งเซิร์ฟเวอร์; ทำ parameterize คิวรีaccountId ที่ไม่ใช่ตัวเลขหลังแพตซ์ ให้ตรวจเร็ว:
accountId อื่นและยืนยันว่าล้มเหลววิธีที่เร็วที่สุดจะพลาดช่องโหว่คือเชื่อสิ่งที่ UI ดูเหมือนไม่ให้สิทธิ์ ปุ่มที่ซ่อนหรือปิดใช้งานไม่ใช่การเช็กสิทธิ์ ถ้าเซิร์ฟเวอร์ยอมรับคำขอได้ ใครก็สามารถส่งคำขอนั้นซ้ำด้วย user ID หรือ role ต่างออกไป หรือเรียก API โดยตรง
กับดักทั่วไปอีกอย่างคือคำขอที่กำกว้าง "ทำการตรวจความปลอดภัย" มักให้รายงานทั่วไป การตรวจแบบสั้นต้องมีขอบเขตแคบ (endpoint ไหน บทบาทไหน ข้อมูลไหน) และรูปแบบผลลัพธ์เข้มงวด (ชื่อไฟล์, ฟังก์ชัน, บรรทัดเสี่ยง, รีโปรขั้นต่ำ)
กฎเดียวกันใช้กับผลลัพธ์จาก AI: อย่ายอมรับคำกล่าวโดยไม่ชี้ตำแหน่ง ถ้าข้อค้นพบไม่รวมตำแหน่งโค้ดและขั้นตอนทีละก้าว ให้ถือว่าไม่ได้รับการพิสูจน์
กับดักเหล่านี้เกิดซ้ำ:
ถ้าคุณจับตัวเองเพิ่มฟิลเตอร์หลังกรณีขอบมากขึ้น ให้หยุด การแก้จริงมักอยู่ก่อนหน้านั้น: ตรวจรับค่าที่ขอบ และทำให้การเช็กสิทธิ์ชัดเจนและรวมศูนย์
สิ่งเหล่านี้ไม่แทนการตรวจเต็ม แต่จับความผิดพลาดที่เกิดเวลาทุกคนเหนื่อย จดจ่อกับสิ่งที่พิสูจน์ได้เร็ว: คำขอที่ส่งได้ เพจที่โหลดได้ บรรทึกที่หาได้
ห้าการตรวจด่วนที่คุ้มค่า:
เขียน 3 การแก้หลักที่คุณส่งได้ในสัปดาห์นี้ อย่าเป็นลิสต์ความปรารถนา ตัวอย่าง: (1) เพิ่ม rate limiting ให้ล็อกอินและรีเซ็ตพาสเวิร์ด, (2) บังคับเช็กความเป็นเจ้าของฝั่งเซิร์ฟเวอร์ใน endpoint "get by id", (3) จำกัดความยาวอินพุตและปฏิเสธอักขระไม่คาดคิดสำหรับฟิลด์ค้นหา
การตรวจแบบสั้นได้ผลเมื่อผลลัพธ์เปลี่ยนสิ่งที่คุณส่งจริง รับเช็คลิสต์นี้เป็นขั้นตอนที่ทำซ้ำได้ในบิลด์ ไม่ใช่ภารกิจแก้เฉพาะครั้งเดียว
เปลี่ยนทุกข้อค้นพบเป็นรายการ backlog ที่เข้าใจยาก:
เลือกความถี่ที่เข้ากับความเสี่ยงและขนาดทีม สำหรับหลายทีม ทุกรีลีสคือดีที่สุด หากรีลีสบ่อย ทำการตรวจ 30–60 นาทีทุกเดือนและเช็กสั้นก่อนส่ง
ทำให้ทำซ้ำง่ายด้วยการสร้างแพ็กพรอมต์ที่ใช้ได้ซ้ำและเทมเพลตเช็คลิสต์ เก็บพรอมต์ที่เน้นผลลัพธ์เชิงรูปธรรม: แสดง route, guard, คำขอที่ล้มเหลว, และพฤติกรรมที่คาดหวัง เก็บแพ็กไว้ที่ที่ทีมทำงานอยู่แล้วเพื่อจะได้ไม่ถูกข้าม
ถ้าคุณสร้างแอปผ่านแชท ให้ฝังเช็คลิสต์ลงในการวางแผน เพิ่มบันทึกสั้น ๆ "สมมติฐานด้านความปลอดภัย" สำหรับ authn/authz, อินพุต, และความลับ แล้วรันการตรวจทันทีหลังเวอร์ชันแรกที่ใช้งานได้
Platforms like Koder.ai (koder.ai) can fit well with this habit because they let you iterate quickly while keeping review checkpoints. Using snapshots and rollback around risky changes makes it easier to ship security fixes without getting stuck when a change breaks behavior.