สัปดาห์ที่แล้วมีข่าวหนึ่งที่ผมอ่านแล้วต้องวางกาแฟ: OpenCode (coding agent ตัวหนึ่ง) มีช่องโหว่ที่ทำให้ MCP server ที่ไม่น่าไว้ใจรันคำสั่งบนเครื่องนักพัฒนาได้ แค่ตอนกด sign-in ผ่าน OAuth ไม่ต้องให้ agent เรียก tool อะไรเลยด้วยซ้ำ
ข่าวนี้ไม่ใช่เรื่องของ OpenCode ตัวเดียว มันชี้ให้เห็นสิ่งที่ทีม ops/security หลายทีมยังมองข้าม: การเพิ่ม MCP server เข้า agent ไม่ต่างจากการ curl | bash ของเวอร์ชันสมัยใหม่ บทความนี้จะเล่าข่าวก่อน แล้วค่อยไล่ว่าถ้าจะรัน agent กับ MCP ใน infra จริง ควรวางด่านอะไรบ้าง ทั้งหมดเป็นมุม defensive ไม่มี exploit และตัวอย่าง config เป็นของสมมติทั้งหมด
ข่าวที่ 1: OpenCode และ OAuth sign-in ของ MCP server
ตามรายงานของ The Hacker News (เผยแพร่ 22 ตุลาคม 2026) บริษัท Pillar Security พบว่า OpenCode เวอร์ชัน 1.0.137 ถึง 1.18.32 บน Windows และ WSL เท่านั้น (macOS กับ Linux ไม่โดน) มีปัญหาตอนทำ OAuth กับ remote MCP server
กลไกคือ remote MCP server เป็นคนส่ง "authorization endpoint" URL กลับมา แล้ว OpenCode เอา URL นั้นไปเปิดเบราว์เซอร์ผ่าน helper ที่ประกอบคำสั่ง PowerShell โดยไม่ escape ผลคือ URL ที่ถูกออกแบบมาให้มีคำสั่ง PowerShell แฝง จะถูกรันด้วยสิทธิ์ของนักพัฒนาคนนั้นเลย ที่น่าสนใจคือ URL ยังหน้าตาเป็น HTTPS ธรรมดา เช็คแค่ว่าขึ้นต้นด้วย http หรือ https จึงกันไม่ได้
รายละเอียดที่ควรรู้ตามรายงาน: Pillar แจ้งผู้พัฒนาแบบ private เมื่อ 29 สิงหาคม ทีมแก้ในเวอร์ชัน 1.18.33 ซึ่งออกวันที่ 28 กันยายน และเปิดเผยต่อสาธารณะ 19 ตุลาคม Pillar ให้คะแนนความรุนแรงที่เสนอไว้ 9.8 จาก 10 ไม่มี CVE (ผู้พัฒนาไม่ได้ขอ) ซึ่งแปลว่า scanner ที่ไล่ดูแต่ CVE จะ ไม่เห็น เคสนี้เลย และรายงานระบุว่ายังไม่พบการโจมตีจริง
บทเรียนข้อแรกจึงเป็นเรื่องที่ไม่เกี่ยวกับ MCP โดยตรง: ถ้า inventory ของคุณพึ่ง CVE feed อย่างเดียว คุณจะพลาดช่องโหว่ในเครื่องมือฝั่ง developer ที่ไม่มีเลข CVE ต้องมีรายการ "agent/CLI ที่ใช้อยู่ในองค์กรและเวอร์ชัน" แยกต่างหาก
ข่าวที่ 2: ปัญหาเชิงระบบของ STDIO transport (OX Security)
อีกชิ้นที่ควรอ่านคู่กันคือ advisory ของ OX Security ที่เผยแพร่ 15 เมษายน 2026 (ไม่ใช่ข่าวสดแต่ยังเกี่ยวข้อง และถูกอ้างถึงต่อเนื่อง) ประเด็นหลักคือ MCP แบบ STDIO ให้ผู้ใช้กำหนด command กับ args ซึ่งถูกส่งไปรันเป็น subprocess ตรงๆ โดยไม่มี allowlist หรือการ sanitize ใน SDK เอง OX จึงเรียกว่าเป็นช่องโหว่ระบบ (systemic) ที่ไหลไปอยู่ในหลายผลิตภัณฑ์
ผลิตภัณฑ์ที่ OX ระบุว่าได้รับผลมีหลายตัว ตัวที่คนในวงการ AI infra น่าจะคุ้นคือ LiteLLM ซึ่งมี CVE-2026-30623 (ต้อง authenticate, แก้แล้วใน v1.83.6-nightly และ v1.83.7-stable) รวมถึง LangFlow, Flowise, Windsurf และอื่นๆ อีกหลายตัว
อีกส่วนที่น่าคิดคือจุดยืนของผู้ให้บริการ OX ระบุว่าหลายเจ้าตอบว่าพฤติกรรมนี้ "by design" และชี้ว่า sandbox เช่น Docker ช่วยลดความเสี่ยงได้ ส่วน OX แย้งว่า sandbox ก็ยังโดนใช้ขุดเหรียญหรือเป็น proxy ได้ ผมไม่ตัดสินว่าฝั่งไหนถูก เพราะจากมุม ops สิ่งที่ต้องรู้คือ คุณคาดหวังให้ upstream ปิดช่องนี้ให้ไม่ได้ ต้องออกแบบด่านของตัวเอง
ทำไม MCP ถึงเป็นโจทย์ ops ไม่ใช่แค่โจทย์ dev
ลองนึกภาพ MCP server เป็น 3 อย่างพร้อมกัน
-
โปรแกรมที่รันบนเครื่อง (STDIO แบบ
npx some-mcp-serverคือดาวน์โหลดแพ็กเกจแล้วรันทันที) - ผู้ให้ข้อความที่ LLM จะอ่านและเชื่อ (tool description, ผลลัพธ์ของ tool คือ input เข้า prompt)
- ตัวถือสิทธิ์ (token ของ GitHub, Jira, cloud API ที่ใส่ไว้ให้ tool ใช้)
ทั้งสามอย่างนี้ปกติทีม ops ดูแลแยกกัน: ด่านของ software supply chain, ด่านของ prompt injection, ด่านของ secret management พอมาอยู่ในก้อนเดียวคือ "MCP server" มันเลยตกหล่นระหว่างทีม ไม่มีใครเป็นเจ้าของ
6 ด่านที่ควรวางก่อนปล่อย agent เข้า infra จริง
ด่านที่ 1: ทะเบียน MCP server ที่อนุมัติแล้ว (allowlist ระดับองค์กร)
ใครจะเพิ่ม MCP server ต้องผ่านรีวิวเหมือนเพิ่ม dependency ใหม่ เก็บเป็นไฟล์ใน repo ที่มี owner ชัดเจน เช่น
# mcp-registry.yaml (ตัวอย่างสมมติ)
servers:
- name: internal-docs-search
transport: streamable-http
url: https://mcp.example.internal/docs
owner: platform-team
scopes: [read]
reviewed: 2026-10-01
- name: ticket-reader
transport: stdio
command: /opt/mcp/bin/ticket-reader # pin path, ไม่ใช้ npx
args: ["--readonly"]
owner: sre-team
reviewed: 2026-09-20
จุดที่ผมย้ำกับตัวเองคือ allowlist ต้องเช็คทั้ง command และ args จาก advisory ของ OX จะเห็นว่ามีเคสที่ allowlist ชื่อคำสั่งอย่าง npx แต่ผู้ใช้ยัดอาร์กิวเมนต์ที่ทำให้มันรันคำสั่งอื่นได้ ถ้าอนุญาตแค่ "npx" เท่ากับไม่ได้อนุญาตอะไรเลย
ด่านที่ 2: ตรึงเวอร์ชันและที่มา (pin + verify)
npx -y some-mcp-server@latest ในไฟล์ config ของ agent คือการให้ใครก็ตามที่ครอบครอง package นั้นรันโค้ดบนเครื่องคุณทุกครั้งที่ agent เริ่ม ให้ pin เวอร์ชันเป็นเลขตายตัว หรือดีกว่านั้นคือ build เป็น image/binary ภายในแล้วอ้างด้วย digest
# ดูว่าเครื่อง dev ในทีมมี MCP config อะไรอยู่บ้าง (ตัวอย่างหาแบบหยาบ)
grep -rn --include="*.json" -E '"(command|url)"\s*:' ~/.config 2>/dev/null | grep -i mcp
คำสั่งข้างบนเป็นแค่จุดเริ่ม ในองค์กรจริงควรให้ MDM หรือ endpoint tooling เก็บ inventory แทน
ด่านที่ 3: แยก identity ของ agent ออกจากคน
อย่าให้ agent ใช้ token ส่วนตัวของนักพัฒนา สร้าง service identity แยก ให้สิทธิ์เท่าที่ tool ต้องใช้ ถ้า tool แค่อ่านตั๋ว ก็ควรได้ token แบบ read-only เหมือนที่เราทำกับ IRSA บน EKS: role ต่อ workload ไม่ใช่ role กลางที่ทุกอย่างแชร์กัน
ถ้าเป็นฝั่ง cloud ให้ใช้ credential อายุสั้น (STS, workload identity) แทน long-lived key และอย่าใส่ secret ลงในไฟล์ config ของ MCP ตรงๆ ให้ดึงจาก secret manager ตอน runtime
ด่านที่ 4: Sandbox ที่ปิดเน็ตและ filesystem โดยค่าเริ่มต้น
MCP server แบบ STDIO ที่ต้องรันในเครื่องเดียวกับ agent ให้รันใน container หรือ sandbox ที่
- filesystem เป็น read-only ยกเว้น directory ทำงานที่กำหนด
- ไม่มีสิทธิ์ root และ drop capability ที่ไม่จำเป็น
- egress ถูกจำกัดเหลือ domain ที่ tool ต้องคุยจริง
# ตัวอย่าง pod spec สมมติสำหรับ MCP server ที่รันใน cluster
securityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
ตรงนี้ขอยอมรับฝั่ง "sandbox ช่วยได้" ที่เหล่าผู้ให้บริการอ้าง: มันช่วยลด blast radius จริง แต่ OX ก็พูดถูกว่ามันไม่ได้ทำให้ปลอดภัย ถ้า container ออกเน็ตได้เต็มที่ ก็ยังถูกใช้ทำอะไรแปลกๆ ได้ ต้องมีทั้งสองอย่าง: sandbox คู่กับ egress policy
ด่านที่ 5: Human-in-the-loop เฉพาะ action ที่ย้อนกลับไม่ได้
ไม่ต้องให้คนกดอนุมัติทุก tool call เพราะสุดท้ายคนจะกด approve รัวจนไร้ความหมาย (approval fatigue) แบ่งเป็นระดับ
- อ่านอย่างเดียว (list, get, search): รันได้เลย แต่ log
- เขียนที่ย้อนกลับได้ (สร้างตั๋ว, comment): รันได้ แต่มีโควตาต่อชั่วโมง
- ย้อนกลับไม่ได้หรือกระทบ production (delete, deploy, เปลี่ยน IAM, ส่งข้อความออกนอกองค์กร): ต้องมีคนยืนยันทุกครั้ง
ด่านที่ 6: Audit log ที่ตอบได้ว่า "ใคร สั่งอะไร ผ่าน agent ตัวไหน ได้ผลอะไร"
log ที่มีแค่ "agent เรียก tool X" ไม่พอตอนเกิดเหตุ ควรเก็บอย่างน้อย: identity ของ agent, ผู้ใช้ที่ต้นเรื่อง, ชื่อ MCP server และเวอร์ชัน, ชื่อ tool, พารามิเตอร์ (mask ค่า secret), เวลา, ผลลัพธ์ (สำเร็จ/ล้มเหลว) และส่งเข้าที่เดียวกับ log security อื่นๆ จะได้ค้นข้ามกันได้ เช่น ตอนจะตอบว่า "token ที่รั่วถูกใช้ผ่าน tool ไหนบ้าง"
แล้วข่าว OpenCode สอนอะไรเพิ่ม
กลับไปที่เคส OAuth ของ OpenCode มีบทเรียนที่ผมว่าใช้ได้กับทุก agent
ทุกค่าที่มาจาก MCP server ต้องถือว่าไม่น่าไว้ใจ ไม่ใช่แค่ผลลัพธ์ของ tool URL สำหรับ OAuth, ชื่อ tool, description, metadata ล้วนเป็น input จากภายนอก ถ้าโค้ดฝั่ง client เอาไปประกอบเป็นคำสั่ง shell ก็จบเหมือนกัน นี่คือ command injection แบบคลาสสิกที่ใส่ชุดใหม่
ช่วงเวลาที่เสี่ยงที่สุดคือตอนเชื่อมต่อครั้งแรก ไม่ใช่ตอนใช้งาน ดังนั้นกฎ "ห้ามต่อ remote MCP server ที่ไม่อยู่ในทะเบียน" ต้องบังคับตั้งแต่ขั้น sign-in ไม่ใช่รอดูตอนเรียก tool
อัปเดตเครื่องมือ developer ให้เป็นกิจวัตรเหมือน patch OS เคสนี้แก้ออกมาตั้งแต่ 28 กันยายน แต่เปิดเผยเมื่อ 19 ตุลาคม คนที่อัปเดตตามปกติปลอดภัยก่อนข่าวออกสามสัปดาห์ คนที่ปล่อยเวอร์ชันเก่าไว้ก็เพิ่งรู้ตอนอ่านข่าว
เช็คลิสต์เริ่มต้นสำหรับสัปดาห์นี้
ถ้าไม่มีเวลาทำครบทั้ง 6 ด่าน ลองเริ่มจากสามอย่างนี้ซึ่งใช้แรงน้อยแต่ได้ผลมาก
- ทำ inventory ว่าในทีมใช้ agent/CLI ตัวไหน เวอร์ชันอะไร (รวมตัวที่ไม่มี CVE) แล้วเช็คกับข่าวล่าสุด เช่น ถ้ามีคนใช้ OpenCode บน Windows/WSL ให้ยืนยันว่าเป็น 1.18.33 ขึ้นไป
- ค้นหา
npx ... @latestหรือคำสั่ง STDIO ที่ไม่ได้ pin ในไฟล์ config ของ MCP แล้ว pin ให้หมด - ถอด token ส่วนตัวออกจาก config ของ agent แล้วย้ายไปใช้ identity แยกที่สิทธิ์น้อยที่สุด
ปิดท้าย
ผมไม่ได้บอกว่าอย่าใช้ MCP มันเป็นของที่มีประโยชน์จริง ทุกวันนี้ agent ที่คุยกับระบบ ticket, เอกสาร และ log ได้ช่วยลดงานจุกจิกไปเยอะ แต่เราควรคุยกันตรงๆ ว่ามันคือ "โค้ดจากภายนอกที่ได้สิทธิ์ของเรา" และปฏิบัติกับมันเท่ากับ dependency ที่ผ่านการรีวิว ไม่ใช่ปลั๊กอินที่ติดตั้งตามบล็อก
ครั้งหน้าที่มีคนในทีมบอกว่า "ผมเพิ่มเซิร์ฟเวอร์ MCP ตัวใหม่เข้า agent แล้วนะ" ลองถามกลับสามคำถาม: ใครเป็นเจ้าของ, มันรันด้วยสิทธิ์ของใคร, และถ้ามันทำอะไรแปลกๆ เราจะรู้จาก log ตรงไหน ถ้าตอบไม่ได้ครบ ก็ยังไม่ถึงเวลาเข้า production ครับ
แหล่งอ้างอิง
- The Hacker News, "OpenCode Flaw Lets Malicious MCP Servers Execute Code During Sign-In on Windows and WSL" (22 ต.ค. 2026): https://thehackernews.com/2026/10/opencode-flaw-lets-malicious-mcp.html
- OX Security, "MCP Supply Chain Advisory: RCE Vulnerabilities Across the AI Ecosystem" (15 เม.ย. 2026): https://www.ox.security/blog/mcp-supply-chain-advisory-rce-vulnerabilities-across-the-ai-ecosystem/
หมายเหตุ: รายละเอียดช่องโหว่ในบทความนี้สรุปจากรายงานสาธารณะข้างต้น ตัวอย่าง config ทั้งหมดเป็นของสมมติ ไม่ใช่ข้อมูลระบบจริงของใคร

Top comments (0)