4 คะแนน โดย GN⁺ 2026-03-30 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เมื่อส่งข้อความใน ChatGPT จะมีการรัน โปรแกรม Cloudflare Turnstile ซึ่งตรวจสอบไม่เพียงลายนิ้วมือเบราว์เซอร์ แต่รวมถึง สถานะของแอปพลิเคชัน React ด้วย
  • โปรแกรมที่ถูกถอดรหัสแล้วเก็บข้อมูล 55 คุณสมบัติ และทำกระบวนการตรวจสอบที่แบ่งเป็น 3 ชั้น ได้แก่ เบราว์เซอร์ เครือข่าย และแอปพลิเคชัน
  • จะผ่านได้เฉพาะในสภาพแวดล้อม SPA จริงที่ React เรนเดอร์เสร็จสมบูรณ์แล้วเท่านั้น ทำให้ เบราว์เซอร์แบบ headless หรือคำขอจากบอตแบบง่ายล้มเหลว
  • ลายนิ้วมือที่เก็บรวบรวมจะถูกเข้ารหัสและแปลงเป็น OpenAI-Sentinel-Turnstile-Token โดยยังมีโมดูล Signal Orchestrator และ Proof of Work ทำงานเพิ่มเติม
  • มีเพียงเซิร์ฟเวอร์ Cloudflare เท่านั้นที่รู้คีย์ถอดรหัส ทำให้ เส้นแบ่งด้านความเป็นส่วนตัวถูกกำหนดด้วยนโยบาย ไม่ใช่ด้วยเทคโนโลยี

วิเคราะห์โครงสร้างการทำงานของ Cloudflare Turnstile ระหว่างการส่งข้อความใน ChatGPT

  • ทุกครั้งที่ส่งข้อความใน ChatGPT จะมีการรัน โปรแกรม Cloudflare Turnstile ภายในเบราว์เซอร์โดยอัตโนมัติ
    • จากผลการถอดรหัสโปรแกรม Turnstile 377 ชุดจากทราฟฟิกเครือข่าย พบว่าไม่ได้หยุดแค่การเก็บลายนิ้วมือเบราว์เซอร์ทั่วไป แต่ยัง ตรวจสอบสถานะของแอปพลิเคชัน React ด้วย
    • บอตที่ปลอมแปลงเพียงลายนิ้วมือเบราว์เซอร์ไม่สามารถผ่านได้ และต้องเรนเดอร์ SPA (single-page application) ของ ChatGPT ให้สมบูรณ์จึงจะผ่านการตรวจสอบ

โครงสร้างการเข้ารหัสและกระบวนการถอดรหัส

  • ไบต์โค้ดของ Turnstile ถูกส่งมาในฟิลด์ turnstile.dx ของการตอบกลับจากเซิร์ฟเวอร์ และถูกเข้ารหัสเป็น สตริง base64 ยาว 28,000 อักขระในทุกคำขอ
    • ชั้นเข้ารหัสด้านนอกสามารถถอดรหัสได้ด้วยโทเค็น p และการดำเนินการ XOR โดยทั้งสองค่านี้ถูกแลกเปลี่ยนกันภายในการเรียก HTTP เดียวกัน
    • ผลลัพธ์ที่ถอดรหัสแล้วเป็นไบต์โค้ดในรูป JSON ซึ่งประกอบด้วย คำสั่ง VM 89 รายการ
  • ภายในยังมี blob ที่เข้ารหัสเพิ่มเติมขนาด 19KB ซึ่ง blob นี้ถูกเข้ารหัสด้วยคีย์ XOR คนละชุด
    • คีย์ถูกฝังเป็น ค่า float literal (เช่น 97.35) ภายในไบต์โค้ด และเซิร์ฟเวอร์เป็นผู้สร้างแล้วส่งมายังเบราว์เซอร์
    • ยืนยันการถอดรหัสเป็น JSON ที่ใช้ได้จริงด้วยวิธีเดียวกันในคำขอทั้ง 50 ครั้ง
  • กระบวนการถอดรหัสทั้งหมดประกอบด้วย 5 ขั้นตอนดังนี้
    1. อ่านโทเค็น p จากคำขอ
    2. อ่าน turnstile.dx จากการตอบกลับ
    3. XOR(base64decode(dx), p) → สร้างไบต์โค้ดชั้นนอก
    4. ดึงคีย์จากอาร์กิวเมนต์ตัวสุดท้ายของคำสั่งแบบ 5 อาร์กิวเมนต์ที่อยู่หลัง blob 19KB
    5. XOR(base64decode(blob), str(key)) → ถอดรหัสโปรแกรมภายใน (417~580 คำสั่ง)

รายการตรวจสอบของโปรแกรมที่ถอดรหัสแล้ว

  • โปรแกรมภายในทำงานบน custom VM ที่มี 28 คำสั่ง (opcode) และตำแหน่งแอดเดรสของรีจิสเตอร์แบบ floating-point จะถูกสุ่มใหม่ในทุกคำขอ
  • เก็บข้อมูล 55 คุณสมบัติ (property) โดยตัวอย่างทั้ง 377 ชุดมีรายการเหมือนกันทั้งหมด
  • Layer 1: ลายนิ้วมือเบราว์เซอร์

    • คุณสมบัติที่เกี่ยวกับ WebGL 8 รายการ: UNMASKED_VENDOR_WEBGL, UNMASKED_RENDERER_WEBGL, WEBGL_debug_renderer_info เป็นต้น
    • ข้อมูลหน้าจอ 8 รายการ: colorDepth, pixelDepth, width, height, availWidth, availHeight, availLeft, availTop
    • ฮาร์ดแวร์ 5 รายการ: hardwareConcurrency, deviceMemory, maxTouchPoints, platform, vendor
    • การวัดฟอนต์ 4 รายการ: สร้าง div ที่ซ่อนไว้แล้ววัดขนาดการเรนเดอร์ด้วย fontFamily, fontSize, getBoundingClientRect, innerText
    • การสำรวจ DOM 8 รายการ: createElement, appendChild, removeChild, style, position, visibility, ariaHidden เป็นต้น
    • ที่เก็บข้อมูล 5 รายการ: storage, quota, estimate, setItem, usage
      • ผลลัพธ์จะถูกเก็บไว้ใน localStorage ที่คีย์ 6f376b6560133c2c เพื่อคงอยู่ข้ามการรีโหลดหน้า
  • Layer 2: เครือข่าย Cloudflare

    • เฮดเดอร์จาก edge 5 รายการ: cfIpCity, cfIpLatitude, cfIpLongitude, cfConnectingIp, userRegion
    • ค่าเหล่านี้มีอยู่ได้ผ่านเครือข่าย Cloudflare เท่านั้น ดังนั้น บอตที่เข้าถึง origin server โดยตรง จะมีค่าขาดหายหรือไม่ตรงกัน
  • Layer 3: สถานะแอปพลิเคชัน

    • โครงสร้างภายในของ React 3 รายการ: __reactRouterContext, loaderData, clientBootstrap
    • รายการเหล่านี้จะมีอยู่ก็ต่อเมื่อแอปพลิเคชัน React ของ ChatGPT ถูกเรนเดอร์ครบถ้วนและ SSR hydration เสร็จสมบูรณ์ เท่านั้น
    • เบราว์เซอร์แบบ headless ที่โหลดแค่ HTML หรือไม่รัน JS bundle รวมถึงเฟรมเวิร์กบอตที่ไม่ได้รัน React จริง จะล้มเหลว

กระบวนการสร้างโทเค็น

  • หลังเก็บ 55 คุณสมบัติแล้ว โปรแกรมจะถอดรหัส blob เข้ารหัสขนาด 116 ไบต์ แล้วรันคำสั่งสุดท้าย 4 รายการ
    • JSON.stringify(fingerprint)storeXOR(json, key)RESOLVE
    • ค่าผลลัพธ์จะถูกแปลงเป็นเฮดเดอร์ OpenAI-Sentinel-Turnstile-Token และแนบไปกับทุกคำขอสนทนา

องค์ประกอบเพิ่มเติมของ Sentinel

  • นอกจาก Turnstile แล้ว ยังมีโมดูลตรวจสอบเพิ่มเติมอีก 2 ตัว
  • Signal Orchestrator

    • ประกอบด้วยคำสั่ง 271 รายการ
    • ติดตั้ง event listener สำหรับ keydown, pointermove, click, scroll, paste, wheel
    • ติดตามพร็อพเพอร์ตี window.__oai_so_* จำนวน 36 รายการเพื่อมอนิเตอร์ จังหวะการพิมพ์ ความเร็วเมาส์ รูปแบบการเลื่อน ช่วงเวลาที่ไม่ได้ใช้งาน และเหตุการณ์วางข้อความ
    • นอกเหนือจากการเก็บลายนิ้วมือแล้ว ยังทำหน้าที่เป็น ชั้นตรวจสอบชีวมิติจากพฤติกรรม
  • Proof of Work

    • อิงตาม ลายนิ้วมือ 25 ฟิลด์ + SHA-256 hashcash
    • ระดับความยากเป็นเลขสุ่มสม่ำเสมอในช่วง 400K~500K และ 72% ถูกแก้ได้ภายใน 5ms หรือน้อยกว่า
    • มีแฟล็กตรวจจับแบบไบนารี 7 รายการ ได้แก่ ai, createPRNG, cache, solana, dump, InstallTrigger, data (ตัวอย่างทั้ง 100 ชุดเป็น 0 ทั้งหมด)
    • เพิ่มต้นทุนด้านการคำนวณ แต่ ไม่ใช่มาตรการป้องกันหลัก

ผู้ที่สามารถถอดรหัสโทเค็นได้และความหมายด้านความปลอดภัย

  • เนื่องจากคีย์ XOR ของโปรแกรมภายในถูกสร้างโดยเซิร์ฟเวอร์และฝังอยู่ในไบต์โค้ด จึงมีเพียง เซิร์ฟเวอร์ที่สร้าง turnstile.dx เท่านั้นที่รู้คีย์
  • เส้นแบ่งด้านความเป็นส่วนตัวระหว่างผู้ใช้กับผู้ดูแลระบบถูกกำหนดโดย การตัดสินใจเชิงนโยบาย ไม่ใช่ข้อจำกัดทางคริปโตกราฟี
  • วัตถุประสงค์ของการทำให้อ่านยากมีดังนี้
    • ซ่อนรายการข้อมูลลายนิ้วมือจากการวิเคราะห์แบบสถิต
    • ป้องกันไม่ให้ผู้ดูแลเว็บไซต์ (OpenAI) อ่านค่าลายนิ้วมือดิบได้โดยตรง
    • ทำให้แต่ละโทเค็นมีเอกลักษณ์เพื่อป้องกันการ reuse (replay)
    • ทำให้ภายนอกสังเกตได้ยากเมื่อ Cloudflare เปลี่ยนรายการตรวจสอบ
  • อย่างไรก็ตาม การเข้ารหัสนี้ใช้ คีย์และการดำเนินการ XOR ภายในสตรีมข้อมูลเดียวกัน จึงเป็นเพียง การทำให้อ่านยากเพื่อป้องกันการวิเคราะห์ เท่านั้น

สถิติการเก็บและการวิเคราะห์

รายการ ค่า
โปรแกรมที่ถอดรหัสแล้ว 377/377 (100%)
ผู้ใช้ที่ไม่ซ้ำกันที่สังเกตได้ 32
จำนวนคุณสมบัติต่อโปรแกรม 55 (เหมือนกันทั้งหมด)
จำนวนคำสั่ง 417–580 (เฉลี่ย 480)
คีย์ XOR (50 ตัวอย่าง) 41
คุณสมบัติของ Signal Orchestrator 36
ฟิลด์ของ Proof of Work 25
เวลาแก้ PoW 72% ภายใน 5ms หรือน้อยกว่า

ระเบียบวิธีการวิเคราะห์

  • ใช้เฉพาะ ทราฟฟิกที่เก็บรวบรวมด้วยขั้นตอนที่ชอบด้วยกฎหมาย
  • ไม่มีการเปิดเผยข้อมูลผู้ใช้ส่วนบุคคล
  • ทราฟฟิกทั้งหมดถูกสังเกตภายใต้ ความยินยอมของผู้เข้าร่วม
  • ทำ manual deobfuscation และถอดรหัสแบบออฟไลน์ กับ Sentinel SDK (sdk.js, 1,411 บรรทัด)
  • การถอดรหัสดำเนินการในสภาพแวดล้อมออฟไลน์โดยใช้ Python

1 ความคิดเห็น

 
GN⁺ 2026-03-30
ความคิดเห็นใน Hacker News
  • สวัสดีครับ ผม Nick ทำงานอยู่ใน ทีม Integrity ของ OpenAI
    การตรวจสอบครั้งนี้เป็นส่วนหนึ่งของมาตรการป้องกัน การใช้งานในทางที่ผิด ของแพลตฟอร์ม เช่น บอต การสแครป และการฉ้อโกง
    เป้าหมายคือจัดสรรทรัพยากร GPU ให้ผู้ใช้จริงก่อน เพื่อให้ยังคงเปิดให้ผู้ใช้ฟรีและผู้ที่ไม่ได้ล็อกอินเข้าถึงได้ต่อไป
    เรากำลังติดตามเวลาโหลดหน้าเว็บ เวลาจนถึงโทเค็นแรก ขนาดเพย์โหลด และโฟกัสที่การ ลดโอเวอร์เฮด ของมาตรการป้องกันให้น้อยที่สุด
    สำหรับผู้ใช้ส่วนใหญ่ผลกระทบมีน้อยมาก และมีเพียงส่วนน้อยมากที่อาจเจอความล่าช้าเล็กน้อย
    นอกจากนี้ เรายังประเมินการปรับปรุงความแม่นยำอย่างต่อเนื่อง เพื่อให้การใช้งานในทางที่ผิดทำได้ยากขึ้น พร้อมลด อัตราการตรวจจับผิดพลาด ไปด้วย

    • น่าสนใจที่ OpenAI มองว่าการสแครปเป็นการใช้งานในทางที่ผิด
    • ทุกวันนี้เหมือนต้องมีเบราว์เซอร์หนึ่งตัวที่ยอมรับการตรวจสอบฝั่งไคลเอนต์ทั้งหมดเพื่อใช้บริการที่จำเป็น แล้วก็มีอีกตัวสำหรับหลบการติดตาม
      ผมเข้าใจคำอธิบายของ Nick แต่ก็สงสัยว่าโลกที่ต้องเลือกระหว่าง ความเป็นส่วนตัวกับการใช้งานได้จริง จะเป็นแบบนี้ต่อไปหรือไม่
    • ไม่แน่ใจว่าเกี่ยวข้องกันไหม แต่ในการสนทนายาว ๆ ประสิทธิภาพของ Chat UI แย่มาก
      มีทั้งอาการพิมพ์หน่วง การเรนเดอร์สะดุด ไปจนถึงค้างสนิท
      เจอเหมือนกันทั้งบน iPhone 16 Safari และ MacBook Pro M3 Chrome
    • มีข้อสงสัยว่าแอ็กเคานต์ใหม่ที่คอมเมนต์แค่สองครั้งนั้นเป็นคนจริงหรือเป็น บอตที่มาปกป้อง OpenAI กันแน่
      มีการแซวให้ลองรันเครื่องมือที่ละเมิดความเป็นส่วนตัวของ Cloudflare แล้วเอาผลมาแชร์ดู
    • ดีใจที่ได้ยินคำตอบจากคนของ OpenAI โดยตรง
      ผมเป็นสมาชิก Pro และทั้งทีมใช้จ่ายเกิน 2,000 ดอลลาร์ต่อเดือน
      แต่เวลาใช้ VPN (Mullvad) อินเทอร์เฟซ Chat มักหลุดหรือตั้งเวลาเกินบ่อย แม้จะล็อกอินอยู่แล้วก็ตาม
      ถ้าเป็นผู้ใช้แบบเสียเงิน ก็น่าจะใช้งานได้เสถียรโดยไม่ควรถูกกระทบจากการใช้ VPN
  • มีการบ่นว่า Cloudflare ทำให้ใช้งานเว็บแทบไม่ได้เลย เพียงเพราะมองว่าเบราว์เซอร์หรือ IP ‘น่าสงสัย’
    ถึงขั้นบอกว่าถูกโยนเข้าไปอยู่ใน นรกแคปช่า แค่เพราะใช้ Firefox

    • ความหมายของคำว่า ‘น่าสงสัย’ ของ Cloudflare กำลังขยายกว้างขึ้นเรื่อย ๆ
      คนที่ให้ความสำคัญกับความเป็นส่วนตัว เช่น ใช้ VPN เบราว์เซอร์สายความเป็นส่วนตัว หรือช่วง IP ที่พบไม่บ่อย กลับโดนมากที่สุด
      แต่บอตกลับหลบตัวกรองพวกนี้ได้ง่าย
    • มีคนแนะนำให้ตรวจดูว่าในเครือข่ายมีเว็บทราฟฟิกแปลก ๆ ออกไปโดยไม่รู้ตัวหรือไม่
      ตัวเองก็ใช้ Firefox แต่เจอแคปช่าในระดับปกติเท่านั้น
    • ใช้ Firefox + Ublock Origin และ แทบไม่เคยเห็นแคปช่าเลย
      ปิด CGNAT อยู่ เลยสงสัยว่านั่นอาจเป็นตัวสร้างความแตกต่างหรือเปล่า
    • มีคนเล่าประสบการณ์ชวนอึ้งว่าเพิ่งจ่ายเงินเสร็จแล้วต้องแก้ แคปช่าติดกัน 15 ครั้ง
      ทั้งที่ธนาคารยืนยันตัวตนไปแล้ว แต่เว็บยังแยกไม่ออกว่าเป็นคนหรือไม่ ก็เข้าใจได้ยาก
  • ดูเหมือนว่า OpenAI พยายามป้องกันไม่ให้คนเอา ChatGPT ฟรี สำหรับผู้ใช้ที่ไม่ได้ล็อกอินไป ใช้งานในทางที่ผิดเหมือนเป็น API ฟรี

    • มีคนสงสัยว่ามีการตรวจสอบแบบนี้ทั้งตอนล็อกอินและไม่ล็อกอินหรือไม่
      บนแอป Android มีการตรวจ Play Integrity แต่แอป Claude แค่ให้ล็อกอินและไม่มีการตรวจแบบนี้
    • มีคนแชร์ว่าตัวเองเคยใช้ ChatGPT ได้โดยไม่ต้องล็อกอิน
      แค่พิมพ์คำถามโดยไม่มีคุกกี้หรือบัญชี ก็ได้คำตอบกลับมา เลยรู้สึกแปลกใจ
    • การป้องกันแบบนี้ยังมีเป้าหมายเพื่อปกป้องรูปแบบการใช้งานของ สมาชิก Pro ด้วย
      เพราะค่าบริการแบบสมาชิกถูกกว่า API มาก จึงจำเป็นต้องป้องกันการใช้งานในทางที่ผิด
      การตรวจแค่ระดับโหลด SPA ไม่ใช่อุปสรรคใหญ่ และคนที่รู้เรื่องนี้ก็น่าจะมีเทคนิคหลบได้อยู่แล้ว
      บริษัทอื่น ๆ ก็สร้าง ระบบแอนติบอต ของตัวเองกันทั้งนั้น
    • การได้ใช้ GPT‑5.2 ในราคา 20 ดอลลาร์ต่อเดือนนั้น คุ้มเกินไปมาก และดูเหมือนสักวันราคาน่าจะถูกปรับ
    • ดูเหมือน copilot.microsoft.com ก็ใช้ การป้องกันที่อิง Cloudflare คล้ายกัน
  • น่าสนใจที่ต้องให้ แอป React ของ ChatGPT เรนเดอร์เสร็จสมบูรณ์ ก่อน จึงจะมีพร็อพเพอร์ตีบางอย่างปรากฏ
    นี่เป็นวิธีตรวจจับบอตในระดับ แอปพลิเคชันเลเยอร์ ไม่ใช่ระดับเบราว์เซอร์
    ผมนึกว่าระบบตรวจจับขั้นสูงส่วนใหญ่ก็ทำงานแบบนี้อยู่แล้ว เลยสงสัยว่าการค้นพบครั้งนี้มีความหมายพิเศษอะไรหรือไม่

  • มีคนอยากให้ผู้เขียนอธิบายให้ชัดกว่านี้ว่าทำไมประเด็นนี้ถึงสำคัญ
    สุดท้ายแล้ว OpenAI ก็แค่ต้องการให้ผู้ใช้ ใช้แอป React อย่างเป็นทางการ และยังไม่ค่อยเห็นว่านั่นเป็นปัญหาตรงไหน

    • เลยรู้สึกว่าบทความนั้น คุณภาพต่ำเหมือนเขียนโดย AI
  • น่าสนใจในเชิงเทคนิค
    เท่าที่รู้ Turnstile ปกติไม่ได้มีการตั้งค่ารายเว็บไซต์ลึกขนาดนั้น เลยสงสัยว่า OpenAI เอา ข้อมูลจาก Turnstile มาผูกกับ API ของตัวเอง ได้อย่างไร

  • มีความเห็นว่าไม่เข้าใจว่าทำไมคนทำบอตไม่แค่รัน Windows 11 VM + Chrome ไปเลย
    ถ้าใช้ memory deduplication ก็รัน VM พร้อมกันได้ 50 ตัว และบน AWS ต้นทุนก็แค่ราว 1 เซนต์ต่อการโหลดหน้า 1,000 ครั้ง ซึ่งถูกมาก

    • ตอนนี้มีบริการจำนวนมากที่ขายความสามารถแบบนี้ เป็นแพ็กเกจสำเร็จรูป อยู่แล้ว
      มีทั้งการหมุน IP ปลอมตำแหน่ง ปรับค่าภาษา มี parser ในตัว ฯลฯ และต้นทุนในการเปลี่ยนไปใช้ก็ต่ำ จึงแทบไม่มีเหตุผลต้องสร้างเอง
    • ในทางปฏิบัติ วิธีแบบใช้ VM นี้มีต้นทุนสูงพอที่จะ ช่วยยับยั้งจำนวนบอต ได้
      เพราะแพงกว่าวิธีง่าย ๆ มาก
    • ถ้าไปดู ชุมชน Reddit ด้านการสแครป จะเห็นว่านักพัฒนาบอตไม่พอใจมากเวลาเข้าเว็บผ่านเบราว์เซอร์แบบ headless ไม่ได้
      และถ้าใช้ Linux container แทน Windows ตามที่เสนอ ก็จะเบากว่าและมีประสิทธิภาพมากกว่า
    • มีคนขอให้ช่วยบอกวิธีรัน Windows 11 VM ที่เร่งกราฟิกได้ดี แบบไม่ต้องใช้ GPU passthrough ถ้ามีวิธีที่ทำได้ง่าย
  • มีคำวิจารณ์ว่าเป็น บทความหยาบ ๆ เหมือน ChatGPT เขียน

    • พร้อมมุกว่า “คุณลักษณะดั้งเดิมของเว็บบล็อกคือ ต้นฉบับเละจนแม้แต่โมเดลภาษายังต้องแก้รอบสอง
  • มีคนเคยใช้ส่วนขยายชื่อ KeepChatGPT ในช่วงปี 2023~2024
    วิธีที่มันทำงานโดยสวมรอยเป็นผู้ใช้โดยไม่ต้องใช้ API นั้นน่าสนใจดี
    ต่อมาหยุดใช้หลังจาก Gemini ปรากฏตัว และเกิดข้อผิดพลาดบ่อย แต่ก็ชอบตัวเลือกที่ย้ายแผง AI ไปไว้ด้านขวา
    ลิงก์ GitHub ของ KeepChatGPT

    • ตัวเองใช้แอปช่วยเล็ก ๆ ที่ส่งคิวรีไปยัง ChatGPT ผ่าน WinForms WebView และรับคำตอบกลับมาเป็น JSON
      วิธีนี้ ไม่ติดระบบแอนติบอตของ OpenAI เลย
  • มีคนถามว่าการเชื่อมรวมกันระหว่าง Cloudflare กับแอปนี้เป็น ฟังก์ชันคัสตอมที่เกินกว่า Turnstile มาตรฐาน หรือเป็นฟีเจอร์เฉพาะระดับ enterprise กันแน่