คำขอข้ามต้นทางของคลินิก — เบราว์เซอร์บล็อกคำตอบ แต่แถวลงไปแล้ว
คอร์สนี้ตอบบรรทัดไหนของ clinic-security
หัวข้อที่มีชื่อว่า “คอร์สนี้ตอบบรรทัดไหนของ clinic-security”คอร์สนั้นเขียนเองว่าเรื่องนี้ใหญ่เกินกว่าบทที่เหลือจะรับไหว คอร์สนี้คือคำตอบของบรรทัดนั้น
คอร์สคัดกรองผู้เรียกของคลินิก วางกฎขั้นต่ำไว้ก้อนหนึ่ง
แล้วตั้งชื่อก้อนนั้นเองว่า SecConfig.kt — กฎขั้นต่ำที่ probe ใช้วัดทุกทรงหลังจากนี้
ในก้อนนั้นมีหนึ่งบรรทัดที่ปิดการกัน CSRF ทิ้ง และไม่มีบทไหนบอกว่ามันปิดอะไรไป
คอร์สนั้นวัด 12 ทรง และ 10 ทรง ในนั้นตั้งอยู่บนกฎก้อนนี้ อีก 2 ทรงคือทรงที่ไม่มี
SecConfig.kt เลย ซึ่งเป็นสองทรงที่คอร์สนั้นวัดไว้ ก่อน เขียนกฎก้อนนี้ขึ้นมา
บทสุดท้ายของคอร์สนั้นยังเอ่ยถึง CSRF กับ CORS ไว้ใต้หัวข้อสิ่งที่จงใจไม่แตะ เหตุผลที่มันให้ไว้ไม่ใช่ว่าเรื่องนี้ไม่สำคัญ แต่เป็นว่าแปดบทที่เหลือรับไม่ไหว
ก่อนคอร์สนี้ ทั้งไซต์เอ่ยถึงสองเรื่องนั้นรวมกัน 2 บรรทัด และไม่มีใน deviq/ เลย
นับเมื่อ 2026-09-05 ด้วยคำสั่งเดียว โดยไม่นับไดเรกทอรีของคอร์สนี้เอง
คอร์สนี้จึงเป็นคอร์สแรกที่เป็นเจ้าของเรื่องนี้ทั้งเรื่อง
คอร์สนี้อยู่ในซีรีส์เดิม แต่ probe ของมันสร้างโปรเจกต์ของตัวเอง ไม่ได้ยกใบเดิมมาต่อ
Visit ของที่นี่มีแค่ id กับ note ตารางชื่อ csrf_visit package ชื่อ clinic.csrf
และ container เป็นคนละใบกับของคอร์สนั้น สิ่งที่ยกมาต่อคือคำถาม ไม่ใช่ตัวงาน
สิ่งที่คอร์สนี้ทำคือเปิดบรรทัดนั้นกลับมา แล้ววัดทั้งสองด้าน คือด้านที่ server เห็น และด้านที่เบราว์เซอร์เห็น
คำถามของคอร์ส และคำตอบที่วัดได้
หัวข้อที่มีชื่อว่า “คำถามของคอร์ส และคำตอบที่วัดได้”คำถามเดียว คำตอบสามชั้น และทั้งสามชั้นวัดเป็นจำนวนแถวกับรหัส HTTP
คำถามคือ เบราว์เซอร์บอกว่าคำขอถูกบล็อกด้วย CORS แล้วฐานข้อมูลได้แถวเพิ่มกี่แถว
ชั้นที่หนึ่ง CORS ไม่ได้กันการเขียน มันกันการอ่าน ทรงที่ปลายทางไม่ส่ง header
ของ CORS สักตัว วัดได้ว่า server ตอบ 200 แถวเพิ่ม 1 แถว และ
Access-Control-Allow-Origin ออกมา 0 ตัว เบราว์เซอร์ปฏิเสธที่ขั้นอ่านคำตอบ
ชั้นที่สอง มีสองทรงที่กันได้จริง ทรงที่ต้องถามปลายทางก่อนด้วย
Content-Type: application/json ได้ OPTIONS = 1 และ POST = 0 คือการเขียนไม่เคยเกิด
ส่วนทรงที่ตั้ง CORS ไว้แล้ว server ปฏิเสธเองด้วย 403 และไม่มีแถวลง
เส้นแบ่งจึงไม่ได้อยู่ที่ข้ามโดเมนหรือไม่ มันอยู่ที่ content-type กับ header ซึ่งเป็นที่ที่คนเข้าใจผิดกันพอดี
ชั้นที่สามคมที่สุด CORS ปิดรูที่ CSRF เปิดทิ้งไว้ GET ที่เขียนฐานข้อมูลจริง
ผ่านการกันของ CSRF ไปทั้งดุ้น ได้ 200 และ +1 แถว ส่วนคำขอเดียวกันในทรงที่ตั้ง
CORS ไว้ ได้ 403 และ +0 แถว
ทุกตัวเลขมาจากไหน
หัวข้อที่มีชื่อว่า “ทุกตัวเลขมาจากไหน”สองชุดการวัด ชุดหนึ่งวัดฝั่ง server อีกชุดวัดฝั่งเบราว์เซอร์จริง
CORS ถูกบังคับที่เบราว์เซอร์เป็นหลัก ชุดวัดที่ใช้ HTTP client ล้วนจึงวัดครึ่งที่สำคัญ
ที่สุดไม่ได้เลย มันได้แค่อ้างสเปก คอร์สนี้จึงมีชุดวัดสองชุด
- ฝั่ง server
scripts/clinic-cross-origin/probe.py· 64 ข้ออ้าง ตรงทั้งหมด · 10 ทรง · ออกด้วยรหัส 0 - ฝั่งเบราว์เซอร์
scripts/clinic-cross-origin/browser/· 500 รอบ · 5 ทรง · ผลนิ่ง 20 จาก 20 ทุกทรง
ความนิ่งถูกวัดก่อน ไม่ได้ถูกสมมติ ไซต์นี้มีบันทึกของข้ออ้างที่ผิด 20 จาก 20 รอบ บนเครื่องผู้เขียน และผิด 0 จาก 20 รอบบน runner ด้วย code ชุดเดียวกัน คือแดงที่นี่ เขียวที่โน่น ชุดนี้จึงต้องผ่านการวัดความนิ่งก่อน
มันจ่ายคืนแล้วหนึ่งครั้ง ตั้งแต่ก่อนเขียนบทแรก สองทรงที่ต่างกันแค่ Content-Type
ให้ฝั่ง JavaScript เห็นข้อความเดียวกัน แต่ฝั่ง server ได้ POST = 1 ในทรงหนึ่ง
และ POST = 0 ในอีกทรงหนึ่ง
สิ่งที่คอร์สนี้จงใจไม่แตะ
หัวข้อที่มีชื่อว่า “สิ่งที่คอร์สนี้จงใจไม่แตะ”ประกาศไว้ตรงนี้ เพื่อไม่ให้ใครอ่านจบแล้วเชื่อว่าได้ของที่คอร์สนี้ไม่ได้ให้
- ไม่วัดความเร็ว ทั้งคอร์สไม่มีหน่วยเวลาสักตัว หน่วยคือจำนวนแถว จำนวนคำขอ จำนวน header และรหัส HTTP เหมือนสี่คอร์สก่อนหน้าในซีรีส์เดียวกัน
- ไม่อ้างพฤติกรรมข้ามไซต์ของ
SameSiteชุดวัดฝั่งเบราว์เซอร์เห็นcookieSeenเป็น false ทุกทรง คอร์สนี้จึงอ้างได้แค่ literal ที่ server คายออกมา - ไม่แตะเวลาที่ preflight ถูก cache ไว้ ข้อนั้นมีนาฬิกาอยู่ข้างใน จึงตกนอกกฎ ของหน่วยที่คอร์สนี้ยอมรับ
- ไม่สอน OAuth2 กับ OIDC และไม่แตะหน้า login คอร์สที่ 35 ตัดออกด้วยเหตุผลเดียวกัน
- ไม่สอนการเข้ารหัสรหัสผ่าน เป็นของคอร์ส security ทั่วไป ไม่ใช่ของคอร์สนี้
ก่อนเริ่ม — สิ่งที่ควรมีมาก่อน
หัวข้อที่มีชื่อว่า “ก่อนเริ่ม — สิ่งที่ควรมีมาก่อน”ต้องผ่านคอร์สที่ 35 มาก่อน ส่วนความรู้เรื่อง CSRF กับ CORS ไม่ต้องมี
- ผ่าน คอร์สคัดกรองผู้เรียกของคลินิก มาแล้ว เพราะคอร์สนี้ เปิดบรรทัดที่คอร์สนั้นปิดไว้ ไม่ได้สร้างกฎขึ้นใหม่
- อ่าน Kotlin ออกและเคยเขียน Spring Boot มาก่อน ระดับที่รู้ว่า bean มาจากไหนก็พอ
- ไม่ต้องรู้จัก CSRF หรือ CORS มาก่อน ทุกกลไกถูกอธิบายตอนที่มันโผล่ครั้งแรก
- ต้องมี Docker กับ Gradle เพราะทุกข้ออ้างในคอร์สนี้มาจาก probe ที่คุณรันเองได้
- ตัวเลขทุกตัวผูกกับรุ่นที่ระบุไว้ Spring Boot 4.1.1 · Kotlin 2.4.10 · JDK 25 · และ chromium ที่ Playwright 1.61.0 ปักไว้
เส้นทางการเรียน
หัวข้อที่มีชื่อว่า “เส้นทางการเรียน”แผนผังนี้เติมขึ้นเองเมื่อบทเรียนถูกเพิ่มเข้ามา