Gateway

ความปลอดภัย

กำหนดขอบเขตก่อน: โมเดลความปลอดภัยของผู้ช่วยส่วนตัว

คำแนะนำด้านความปลอดภัยของ OpenClaw ถือว่าเป็นการปรับใช้แบบ ผู้ช่วยส่วนตัว: ขอบเขตผู้ปฏิบัติงานที่เชื่อถือได้หนึ่งขอบเขต ซึ่งอาจมี agent หลายตัว

  • ท่าทีด้านความปลอดภัยที่รองรับ: ผู้ใช้/ขอบเขตความไว้วางใจหนึ่งรายต่อ Gateway (ควรใช้ผู้ใช้ OS/โฮสต์/VPS หนึ่งรายต่อขอบเขต)
  • ไม่ใช่ขอบเขตความปลอดภัยที่รองรับ: Gateway/agent เดียวที่ใช้ร่วมกันโดยผู้ใช้ที่ไม่ไว้วางใจกันหรือเป็นปฏิปักษ์ต่อกัน
  • หากต้องการการแยกผู้ใช้ที่เป็นปฏิปักษ์ ให้แยกตามขอบเขตความไว้วางใจ (Gateway + ข้อมูลประจำตัวแยกกัน และ ideally ใช้ผู้ใช้ OS/โฮสต์แยกกัน)
  • หากผู้ใช้ที่ไม่ไว้วางใจกันหลายคนสามารถส่งข้อความถึง agent ที่เปิดใช้เครื่องมือหนึ่งตัว ให้ถือว่าพวกเขาใช้สิทธิ์เครื่องมือที่มอบหมายชุดเดียวกันสำหรับ agent นั้นร่วมกัน

หน้านี้อธิบายการเสริมความแข็งแกร่ง ภายในโมเดลนั้น ไม่ได้อ้างว่ามีการแยกแบบหลายผู้เช่าที่เป็นปฏิปักษ์บน Gateway ที่ใช้ร่วมกันหนึ่งตัว

ก่อนเปลี่ยนการเข้าถึงระยะไกล นโยบาย DM, reverse proxy หรือการเปิดเผยต่อสาธารณะ ให้ใช้ คู่มือปฏิบัติการการเปิดเผย Gateway เป็น รายการตรวจสอบก่อนเริ่มงานและสำหรับย้อนกลับ

ตรวจสอบอย่างรวดเร็ว: openclaw security audit

ดูเพิ่มเติม: การยืนยันอย่างเป็นทางการ (โมเดลความปลอดภัย)

เรียกใช้สิ่งนี้เป็นประจำ (โดยเฉพาะหลังจากเปลี่ยน config หรือเปิดเผยพื้นผิวเครือข่าย):

bash
openclaw security auditopenclaw security audit --deepopenclaw security audit --fixopenclaw security audit --json

security audit --fix จงใจจำกัดขอบเขตให้แคบ: มันเปลี่ยนนโยบายกลุ่มแบบเปิดทั่วไปเป็น allowlists, คืนค่า logging.redactSensitive: "tools", ทำให้สิทธิ์ของ state/config/include-file เข้มงวดขึ้น และใช้การรีเซ็ต Windows ACL แทน POSIX chmod เมื่อทำงานบน Windows

มันแจ้งเตือนจุดพลาดทั่วไป (การเปิดเผยการยืนยันตัวตนของ Gateway, การเปิดเผยการควบคุมเบราว์เซอร์, allowlists ที่ยกระดับ, สิทธิ์ระบบไฟล์, การอนุมัติ exec ที่ผ่อนปรน และการเปิดเผยเครื่องมือผ่านช่องทางเปิด)

OpenClaw เป็นทั้งผลิตภัณฑ์และการทดลอง: คุณกำลังเชื่อมพฤติกรรมของโมเดลแนวหน้ากับพื้นผิวข้อความจริงและเครื่องมือจริง ไม่มีการตั้งค่าใดที่ "ปลอดภัยสมบูรณ์แบบ" เป้าหมายคือการตั้งใจให้ชัดเจนเกี่ยวกับ:

  • ใครสามารถคุยกับ bot ของคุณได้
  • bot ได้รับอนุญาตให้ดำเนินการที่ไหน
  • bot แตะต้องอะไรได้บ้าง

เริ่มจากสิทธิ์เข้าถึงที่เล็กที่สุดที่ยังใช้งานได้ แล้วค่อยขยายเมื่อคุณมั่นใจมากขึ้น

การล็อก dependency ของแพ็กเกจที่เผยแพร่

ซอร์ส checkout ของ OpenClaw ใช้ pnpm-lock.yaml แพ็กเกจ npm openclaw ที่เผยแพร่ และแพ็กเกจ npm plugin ที่ OpenClaw เป็นเจ้าของมี npm-shrinkwrap.json ซึ่งเป็น lockfile dependency ที่เผยแพร่ได้ของ npm ดังนั้นการติดตั้งแพ็กเกจจะใช้กราฟ dependency ถ่ายโอนที่ตรวจทานแล้วจาก release แทนการ resolve กราฟใหม่ ในเวลาติดตั้ง

Shrinkwrap เป็นขอบเขตการเสริมความแข็งแกร่งของ supply-chain และการทำซ้ำ release ไม่ใช่ sandbox สำหรับโมเดลภาษาธรรมดา คำสั่งของ maintainer และการตรวจสอบ การตรวจแพ็กเกจ ดู npm shrinkwrap

การปรับใช้และความไว้วางใจโฮสต์

OpenClaw ถือว่าโฮสต์และขอบเขต config เชื่อถือได้:

  • หากใครบางคนสามารถแก้ไข state/config ของโฮสต์ Gateway (~/.openclaw รวมถึง openclaw.json) ให้ถือว่าบุคคลนั้นเป็นผู้ปฏิบัติงานที่เชื่อถือได้
  • การเรียกใช้ Gateway หนึ่งตัวสำหรับผู้ปฏิบัติงานหลายรายที่ไม่ไว้วางใจกัน/เป็นปฏิปักษ์ต่อกัน ไม่ใช่การตั้งค่าที่แนะนำ
  • สำหรับทีมที่มีความไว้วางใจผสม ให้แยกขอบเขตความไว้วางใจด้วย gateways แยกกัน (หรืออย่างน้อยแยกผู้ใช้ OS/โฮสต์)
  • ค่าเริ่มต้นที่แนะนำ: ผู้ใช้หนึ่งรายต่อเครื่อง/โฮสต์ (หรือ VPS), Gateway หนึ่งตัวสำหรับผู้ใช้นั้น และ agent หนึ่งตัวขึ้นไปใน Gateway นั้น
  • ภายใน instance ของ Gateway เดียว การเข้าถึงของผู้ปฏิบัติงานที่ผ่านการยืนยันตัวตนคือบทบาท control-plane ที่เชื่อถือได้ ไม่ใช่บทบาท tenant ต่อผู้ใช้
  • ตัวระบุ session (sessionKey, session IDs, labels) เป็นตัวเลือกเส้นทาง ไม่ใช่โทเค็นการอนุญาต
  • หากหลายคนสามารถส่งข้อความถึง agent ที่เปิดใช้เครื่องมือหนึ่งตัว แต่ละคนสามารถชี้นำชุดสิทธิ์เดียวกันนั้นได้ การแยก session/memory ต่อผู้ใช้ช่วยด้านความเป็นส่วนตัว แต่ไม่ได้เปลี่ยน agent ที่ใช้ร่วมกันให้เป็นการอนุญาตโฮสต์ต่อผู้ใช้

การทำงานกับไฟล์อย่างปลอดภัย

OpenClaw ใช้ @openclaw/fs-safe สำหรับการเข้าถึงไฟล์แบบจำกัด root, การเขียนแบบ atomic, การแตก archive, พื้นที่ทำงานชั่วคราว และตัวช่วยไฟล์ลับ OpenClaw ตั้งค่าเริ่มต้นให้ตัวช่วย POSIX Python แบบ optional ของ fs-safe เป็น ปิด; ตั้งค่า OPENCLAW_FS_SAFE_PYTHON_MODE=auto หรือ require เฉพาะเมื่อคุณต้องการการเสริมความแข็งแกร่งเพิ่มเติมสำหรับการกลายพันธุ์แบบ fd-relative และสามารถรองรับ runtime ของ Python ได้

รายละเอียด: การทำงานกับไฟล์อย่างปลอดภัย

พื้นที่ทำงาน Slack ที่ใช้ร่วมกัน: ความเสี่ยงจริง

หาก "ทุกคนใน Slack สามารถส่งข้อความถึง bot ได้" ความเสี่ยงหลักคือสิทธิ์เครื่องมือที่มอบหมาย:

  • ผู้ส่งที่ได้รับอนุญาตคนใดก็สามารถชักนำให้เกิดการเรียกเครื่องมือ (exec, เบราว์เซอร์, เครื่องมือเครือข่าย/ไฟล์) ภายในนโยบายของ agent ได้;
  • การแทรก prompt/content จากผู้ส่งหนึ่งรายอาจทำให้เกิดการกระทำที่ส่งผลต่อ state, อุปกรณ์ หรือผลลัพธ์ที่ใช้ร่วมกัน;
  • หาก agent ที่ใช้ร่วมกันหนึ่งตัวมีข้อมูลประจำตัว/ไฟล์ที่อ่อนไหว ผู้ส่งที่ได้รับอนุญาตคนใดก็อาจขับเคลื่อนการ exfiltration ผ่านการใช้เครื่องมือได้

ใช้ agent/gateway แยกกันพร้อมเครื่องมือขั้นต่ำสำหรับ workflow ของทีม; เก็บ agent ที่มีข้อมูลส่วนตัวให้เป็นส่วนตัว

agent ที่บริษัทใช้ร่วมกัน: รูปแบบที่ยอมรับได้

สิ่งนี้ยอมรับได้เมื่อทุกคนที่ใช้ agent นั้นอยู่ในขอบเขตความไว้วางใจเดียวกัน (เช่น ทีมหนึ่งของบริษัท) และ agent ถูกจำกัดขอบเขตไว้เฉพาะงานธุรกิจอย่างเข้มงวด

  • เรียกใช้บนเครื่อง/VM/container เฉพาะ;
  • ใช้ผู้ใช้ OS เฉพาะ + เบราว์เซอร์/profile/accounts เฉพาะสำหรับ runtime นั้น;
  • อย่าลงชื่อเข้าใช้ Apple/Google accounts ส่วนตัว หรือ password-manager/browser profiles ส่วนตัวใน runtime นั้น

หากคุณผสมอัตลักษณ์ส่วนตัวและบริษัทบน runtime เดียวกัน คุณจะทำให้การแยกขอบเขตยุบลงและเพิ่มความเสี่ยงในการเปิดเผยข้อมูลส่วนตัว

แนวคิดความไว้วางใจของ Gateway และ Node

ให้ถือว่า Gateway และ Node เป็นโดเมนความไว้วางใจของผู้ปฏิบัติงานเดียวกัน โดยมีบทบาทต่างกัน:

  • Gateway คือ control plane และพื้นผิวนโยบาย (gateway.auth, นโยบายเครื่องมือ, การกำหนดเส้นทาง)
  • Node คือพื้นผิวการดำเนินการระยะไกลที่จับคู่กับ Gateway นั้น (คำสั่ง, การกระทำอุปกรณ์, ความสามารถเฉพาะโฮสต์)
  • ผู้เรียกที่ผ่านการยืนยันตัวตนกับ Gateway จะได้รับความไว้วางใจในขอบเขต Gateway หลังจากจับคู่แล้ว การกระทำของ Node คือการกระทำของผู้ปฏิบัติงานที่เชื่อถือได้บน Node นั้น
  • ระดับขอบเขตของผู้ปฏิบัติงานและการตรวจสอบในเวลาการอนุมัติสรุปไว้ใน ขอบเขตผู้ปฏิบัติงาน
  • ไคลเอนต์ backend แบบ loopback โดยตรงที่ผ่านการยืนยันตัวตนด้วย token/password ของ gateway ที่ใช้ร่วมกัน สามารถทำ RPC ของ control-plane ภายในได้โดยไม่ต้องนำเสนออัตลักษณ์อุปกรณ์ของผู้ใช้ สิ่งนี้ไม่ใช่การข้ามการจับคู่ระยะไกลหรือเบราว์เซอร์: ไคลเอนต์เครือข่าย, ไคลเอนต์ Node, ไคลเอนต์ device-token และอัตลักษณ์อุปกรณ์ที่ระบุชัดเจน ยังต้องผ่านการจับคู่และการบังคับใช้ scope-upgrade
  • sessionKey คือการเลือก routing/context ไม่ใช่ auth ต่อผู้ใช้
  • การอนุมัติ exec (allowlist + ask) เป็น guardrails สำหรับเจตนาของผู้ปฏิบัติงาน ไม่ใช่การแยกแบบหลายผู้เช่าที่เป็นปฏิปักษ์
  • ค่าเริ่มต้นของผลิตภัณฑ์ OpenClaw สำหรับการตั้งค่าผู้ปฏิบัติงานเดียวที่เชื่อถือได้คือ host exec บน gateway/node ได้รับอนุญาตโดยไม่มี prompt ขออนุมัติ (security="full", ask="off" เว้นแต่คุณจะทำให้เข้มงวดขึ้น) ค่าเริ่มต้นนั้นเป็น UX ที่ตั้งใจไว้ ไม่ใช่ช่องโหว่ในตัวเอง
  • การอนุมัติ exec ผูกกับ context คำขอที่แน่นอนและ operand ไฟล์ local โดยตรงแบบ best-effort; มันไม่ได้จำลองเชิงความหมายทุกเส้นทาง loader ของ runtime/interpreter ใช้ sandboxing และการแยกโฮสต์สำหรับขอบเขตที่แข็งแรง

หากคุณต้องการการแยกผู้ใช้ที่เป็นปฏิปักษ์ ให้แยกขอบเขตความไว้วางใจตามผู้ใช้ OS/โฮสต์ และเรียกใช้ gateways แยกกัน

เมทริกซ์ขอบเขตความไว้วางใจ

ใช้สิ่งนี้เป็นโมเดลอย่างรวดเร็วเมื่อ triage ความเสี่ยง:

ขอบเขตหรือการควบคุม ความหมาย การตีความผิดที่พบบ่อย
gateway.auth (token/password/trusted-proxy/device auth) ยืนยันตัวตนผู้เรียกกับ API ของ gateway "ต้องมีลายเซ็นต่อข้อความในทุก frame จึงจะปลอดภัย"
sessionKey คีย์ routing สำหรับการเลือก context/session "Session key เป็นขอบเขต auth ของผู้ใช้"
Prompt/content guardrails ลดความเสี่ยงการใช้โมเดลในทางที่ผิด "Prompt injection เพียงอย่างเดียวพิสูจน์ auth bypass"
canvas.eval / browser evaluate ความสามารถของผู้ปฏิบัติงานที่ตั้งใจไว้เมื่อเปิดใช้ "primitive JS eval ใดๆ เป็น vuln โดยอัตโนมัติในโมเดลความไว้วางใจนี้"
เชลล์ ! ของ TUI ภายในเครื่อง การดำเนินการ local ที่ผู้ปฏิบัติงานทริกเกอร์อย่างชัดเจน "คำสั่งอำนวยความสะดวกของ local shell คือ remote injection"
การจับคู่ Node และคำสั่ง Node การดำเนินการระยะไกลระดับผู้ปฏิบัติงานบนอุปกรณ์ที่จับคู่ "การควบคุมอุปกรณ์ระยะไกลควรถูกถือว่าเป็นการเข้าถึงของผู้ใช้ที่ไม่เชื่อถือโดยค่าเริ่มต้น"
gateway.nodes.pairing.autoApproveCidrs นโยบายลงทะเบียน Node บนเครือข่ายที่เชื่อถือได้แบบ opt-in "allowlist ที่ปิดเป็นค่าเริ่มต้นเป็นช่องโหว่การจับคู่อัตโนมัติ"

ไม่ใช่ช่องโหว่โดยการออกแบบ

ผลการตรวจพบทั่วไปที่อยู่นอกขอบเขต

รูปแบบเหล่านี้ถูกรายงานบ่อยและมักถูกปิดเป็นไม่ต้องดำเนินการ เว้นแต่ จะมีการสาธิตการข้ามขอบเขตจริง:

  • ห่วงโซ่ที่มีเพียง prompt-injection โดยไม่มีการข้ามนโยบาย, auth หรือ sandbox
  • ข้อกล่าวอ้างที่ถือว่ามีการทำงานแบบหลายผู้เช่าที่เป็นปฏิปักษ์บนโฮสต์หรือ config เดียวที่ใช้ร่วมกัน
  • ข้อกล่าวอ้างที่จัดประเภทการเข้าถึง read-path ปกติของผู้ปฏิบัติงาน (เช่น sessions.list / sessions.preview / chat.history) เป็น IDOR ในการตั้งค่า shared-gateway
  • ผลการตรวจพบในการปรับใช้เฉพาะ localhost (เช่น HSTS บน gateway ที่เป็น loopback-only)
  • ผลการตรวจพบลายเซ็น inbound webhook ของ Discord สำหรับ inbound paths ที่ไม่มีอยู่ ใน repo นี้
  • รายงานที่ถือว่า metadata การจับคู่ Node เป็นชั้นการอนุมัติต่อคำสั่งลำดับที่สองที่ซ่อนอยู่ สำหรับ system.run ทั้งที่ขอบเขตการดำเนินการจริงยังคงเป็น นโยบายคำสั่ง Node ทั่วโลกของ gateway รวมกับการอนุมัติ exec ของ Node เอง
  • รายงานที่ถือว่า gateway.nodes.pairing.autoApproveCidrs ที่กำหนดค่าไว้เป็น ช่องโหว่ในตัวเอง การตั้งค่านี้ปิดเป็นค่าเริ่มต้น ต้องมี รายการ CIDR/IP อย่างชัดเจน ใช้เฉพาะกับการจับคู่ role: node ครั้งแรกโดย ไม่มี scopes ที่ร้องขอ และไม่ auto-approve operator/browser/Control UI, WebChat, role upgrades, scope upgrades, metadata changes, public-key changes, หรือ same-host loopback trusted-proxy header paths เว้นแต่จะเปิดใช้ loopback trusted-proxy auth อย่างชัดเจน
  • ผลการตรวจพบ "ขาดการอนุญาตต่อผู้ใช้" ที่ถือว่า sessionKey เป็น auth token

baseline ที่เสริมความแข็งแกร่งใน 60 วินาที

ใช้ baseline นี้ก่อน แล้วจึงเลือกเปิดใช้เครื่องมือใหม่ต่อ agent ที่เชื่อถือได้:

json5
{  gateway: {    mode: "local",    bind: "loopback",    auth: { mode: "token", token: "replace-with-long-random-token" },  },  session: {    dmScope: "per-channel-peer",  },  tools: {    profile: "messaging",    deny: ["group:automation", "group:runtime", "group:fs", "sessions_spawn", "sessions_send"],    fs: { workspaceOnly: true },    exec: { security: "deny", ask: "always" },    elevated: { enabled: false },  },  channels: {    whatsapp: { dmPolicy: "pairing", groups: { "*": { requireMention: true } } },  },}

สิ่งนี้ทำให้ Gateway อยู่เฉพาะ local, แยก DM และปิดเครื่องมือ control-plane/runtime เป็นค่าเริ่มต้น

กฎอย่างรวดเร็วสำหรับ inbox ที่ใช้ร่วมกัน

หากมีมากกว่าหนึ่งคนที่สามารถ DM bot ของคุณได้:

  • ตั้งค่า session.dmScope: "per-channel-peer" (หรือ "per-account-channel-peer" สำหรับช่องทางหลายบัญชี)
  • คง dmPolicy: "pairing" หรือรายการอนุญาตแบบเข้มงวดไว้
  • ห้ามรวม DM ที่ใช้ร่วมกันกับการเข้าถึงเครื่องมือแบบกว้าง
  • วิธีนี้ทำให้กล่องขาเข้าแบบร่วมมือกัน/ใช้ร่วมกันแข็งแกร่งขึ้น แต่ไม่ได้ออกแบบมาเพื่อแยกผู้เช่าร่วมที่เป็นปรปักษ์เมื่อผู้ใช้มีสิทธิ์เขียน host/config ร่วมกัน

โมเดลการมองเห็นบริบท

OpenClaw แยกแนวคิดสองอย่างออกจากกัน:

  • การอนุญาตให้ทริกเกอร์: ใครสามารถทริกเกอร์ agent ได้ (dmPolicy, groupPolicy, รายการอนุญาต, ประตูการกล่าวถึง)
  • การมองเห็นบริบท: บริบทเพิ่มเติมใดถูกฉีดเข้าไปในอินพุตของโมเดล (เนื้อหาการตอบกลับ, ข้อความที่อ้างอิง, ประวัติ thread, เมทาดาทาที่ส่งต่อ)

รายการอนุญาตควบคุมการทริกเกอร์และการอนุญาตคำสั่ง การตั้งค่า contextVisibility ควบคุมวิธีกรองบริบทเพิ่มเติม (การตอบกลับที่อ้างอิง, รากของ thread, ประวัติที่ดึงมา):

  • contextVisibility: "all" (ค่าเริ่มต้น) คงบริบทเพิ่มเติมไว้ตามที่ได้รับ
  • contextVisibility: "allowlist" กรองบริบทเพิ่มเติมให้เหลือเฉพาะผู้ส่งที่ผ่านการตรวจรายการอนุญาตที่ใช้งานอยู่
  • contextVisibility: "allowlist_quote" ทำงานเหมือน allowlist แต่ยังคงการตอบกลับที่อ้างอิงอย่างชัดเจนไว้หนึ่งรายการ

ตั้งค่า contextVisibility ต่อช่องทางหรือต่อห้อง/การสนทนา ดูรายละเอียดการตั้งค่าที่ แชทกลุ่ม

แนวทางคัดแยกเชิงคำแนะนำ:

  • คำกล่าวอ้างที่แสดงเพียงว่า "โมเดลสามารถเห็นข้อความที่อ้างอิงหรือข้อความย้อนหลังจากผู้ส่งที่ไม่อยู่ในรายการอนุญาต" เป็นข้อค้นพบด้านการทำให้แข็งแกร่งที่แก้ไขได้ด้วย contextVisibility ไม่ใช่การเลี่ยงผ่านขอบเขต auth หรือ sandbox โดยตัวมันเอง
  • เพื่อให้มีผลกระทบด้านความปลอดภัย รายงานยังต้องมีการสาธิตการเลี่ยงผ่านขอบเขตความไว้วางใจ (auth, นโยบาย, sandbox, การอนุมัติ หรือขอบเขตอื่นที่บันทึกไว้)

สิ่งที่การตรวจสอบ audit ตรวจ (ระดับสูง)

  • การเข้าถึงขาเข้า (นโยบาย DM, นโยบายกลุ่ม, รายการอนุญาต): คนแปลกหน้าสามารถทริกเกอร์บอทได้หรือไม่?
  • รัศมีผลกระทบของเครื่องมือ (เครื่องมือยกระดับ + ห้องเปิด): prompt injection สามารถกลายเป็นการกระทำกับ shell/file/network ได้หรือไม่?
  • ความคลาดเคลื่อนของระบบไฟล์ exec: เครื่องมือระบบไฟล์ที่แก้ไขข้อมูลถูกปฏิเสธ ขณะที่ exec/process ยังพร้อมใช้งานโดยไม่มีข้อจำกัดระบบไฟล์ของ sandbox หรือไม่?
  • ความคลาดเคลื่อนของการอนุมัติ exec (security=full, autoAllowSkills, รายการอนุญาต interpreter ที่ไม่มี strictInlineEval): guardrails ของ host-exec ยังทำงานอย่างที่คุณคิดหรือไม่?
    • security="full" เป็นคำเตือนเชิงท่าทีกว้าง ๆ ไม่ใช่หลักฐานของบั๊ก เป็นค่าเริ่มต้นที่เลือกไว้สำหรับการตั้งค่าผู้ช่วยส่วนตัวที่เชื่อถือได้; ทำให้เข้มงวดขึ้นเฉพาะเมื่อ threat model ของคุณต้องการ guardrails แบบการอนุมัติหรือรายการอนุญาต
  • การเปิดเผยเครือข่าย (การ bind/auth ของ Gateway, Tailscale Serve/Funnel, โทเค็น auth ที่อ่อน/สั้น)
  • การเปิดเผยการควบคุมเบราว์เซอร์ (โหนดระยะไกล, พอร์ต relay, endpoint CDP ระยะไกล)
  • สุขอนามัยดิสก์ภายในเครื่อง (สิทธิ์, symlink, config include, พาธ "โฟลเดอร์ที่ซิงค์")
  • Plugins (plugins โหลดโดยไม่มีรายการอนุญาตที่ชัดเจน)
  • ความคลาดเคลื่อน/การกำหนดค่านโยบายผิด (ตั้งค่า sandbox docker ไว้แต่ปิดโหมด sandbox; รูปแบบ gateway.nodes.denyCommands ไม่มีผลเพราะการจับคู่เป็นชื่อคำสั่งแบบตรงตัวเท่านั้น (เช่น system.run) และไม่ตรวจข้อความ shell; รายการ gateway.nodes.allowCommands ที่อันตราย; tools.profile="minimal" ระดับ global ถูกแทนที่ด้วยโปรไฟล์ต่อ agent; เครื่องมือที่ Plugin เป็นเจ้าของเข้าถึงได้ภายใต้นโยบายเครื่องมือที่ผ่อนปรน)
  • ความคลาดเคลื่อนของความคาดหวัง runtime (เช่น สมมติว่า implicit exec ยังหมายถึง sandbox เมื่อ tools.exec.host ตอนนี้มีค่าเริ่มต้นเป็น auto, หรือกำหนด tools.exec.host="sandbox" อย่างชัดเจนขณะที่โหมด sandbox ปิดอยู่)
  • สุขอนามัยของโมเดล (เตือนเมื่อโมเดลที่กำหนดค่าดูเป็นรุ่นเก่า; ไม่ใช่การบล็อกแบบแข็ง)

ถ้าคุณรัน --deep OpenClaw จะพยายาม probe Gateway แบบ live ด้วย best-effort ด้วย

แผนที่การจัดเก็บข้อมูลรับรอง

ใช้ส่วนนี้เมื่อ audit การเข้าถึงหรือตัดสินใจว่าจะสำรองข้อมูลอะไร:

  • WhatsApp: ~/.openclaw/credentials/whatsapp/<accountId>/creds.json
  • โทเค็นบอท Telegram: config/env หรือ channels.telegram.tokenFile (ไฟล์ปกติเท่านั้น; symlink ถูกปฏิเสธ)
  • โทเค็นบอท Discord: config/env หรือ SecretRef (provider แบบ env/file/exec)
  • โทเค็น Slack: config/env (channels.slack.*)
  • รายการอนุญาตการจับคู่:
    • ~/.openclaw/credentials/<channel>-allowFrom.json (บัญชีเริ่มต้น)
    • ~/.openclaw/credentials/<channel>-<accountId>-allowFrom.json (บัญชีที่ไม่ใช่ค่าเริ่มต้น)
  • โปรไฟล์ auth ของโมเดล: ~/.openclaw/agents/<agentId>/agent/auth-profiles.json
  • สถานะ runtime ของ Codex (ค่าเริ่มต้น): ~/.openclaw/agents/<agentId>/agent/codex-home/
  • สถานะ runtime ของ Codex ที่ใช้ร่วมกัน (เลือกเปิดใช้): $CODEX_HOME หรือ ~/.codex เมื่อ plugins.entries.codex.config.appServer.homeScope เป็น "user" โหมดนี้ใช้ บัญชี Codex, config, plugins และที่เก็บ thread แบบ native; เปิดใช้เฉพาะสำหรับ Gateway ภายในเครื่องที่เจ้าของควบคุม ดู Codex harness
  • payload ความลับที่สำรองด้วยไฟล์ (ไม่บังคับ): ~/.openclaw/secrets.json
  • การนำเข้า OAuth รุ่นเก่า: ~/.openclaw/credentials/oauth.json

เช็กลิสต์ security audit

เมื่อ audit แสดงข้อค้นพบ ให้ถือว่านี่คือลำดับความสำคัญ:

  1. อะไรก็ตามที่ "เปิด" + เปิดใช้เครื่องมือ: ล็อก DM/กลุ่มก่อน (การจับคู่/รายการอนุญาต) แล้วค่อยทำให้นโยบายเครื่องมือ/sandboxing เข้มงวดขึ้น
  2. การเปิดเผยเครือข่ายสาธารณะ (LAN bind, Funnel, ไม่มี auth): แก้ไขทันที
  3. การเปิดเผยการควบคุมเบราว์เซอร์จากระยะไกล: ปฏิบัติเหมือนเป็นการเข้าถึงของ operator (tailnet-only, จับคู่โหนดอย่างตั้งใจ, หลีกเลี่ยงการเปิดเผยสาธารณะ)
  4. สิทธิ์: ตรวจให้แน่ใจว่า state/config/credentials/auth ไม่สามารถอ่านได้โดย group/world
  5. Plugins: โหลดเฉพาะสิ่งที่คุณเชื่อถืออย่างชัดเจน
  6. การเลือกโมเดล: เลือกโมเดลสมัยใหม่ที่แข็งแกร่งต่อคำสั่งสำหรับบอทใด ๆ ที่มีเครื่องมือ

อภิธานศัพท์ security audit

ข้อค้นพบ audit แต่ละรายการถูกอ้างอิงด้วย checkId แบบมีโครงสร้าง (เช่น gateway.bind_no_auth หรือ tools.exec.security_full_configured) คลาสความรุนแรง ระดับ critical ที่พบบ่อย:

  • fs.* - สิทธิ์ระบบไฟล์บน state, config, credentials, auth profiles
  • gateway.* - โหมด bind, auth, Tailscale, Control UI, การตั้งค่า trusted-proxy
  • hooks.*, browser.*, sandbox.*, tools.exec.* - การทำให้แข็งแกร่งรายพื้นผิว
  • plugins.*, skills.* - ห่วงโซ่อุปทานของ plugin/skill และข้อค้นพบจากการสแกน
  • security.exposure.* - การตรวจแบบข้ามส่วนที่นโยบายการเข้าถึงมาบรรจบกับรัศมีผลกระทบของเครื่องมือ

ดูแค็ตตาล็อกฉบับเต็มพร้อมระดับความรุนแรง, คีย์การแก้ไข และการรองรับ auto-fix ได้ที่ การตรวจ security audit

Control UI ผ่าน HTTP

Control UI ต้องการ บริบทที่ปลอดภัย (HTTPS หรือ localhost) เพื่อสร้าง identity ของอุปกรณ์ gateway.controlUi.allowInsecureAuth เป็นตัวสลับความเข้ากันได้ภายในเครื่อง:

  • บน localhost จะอนุญาต auth ของ Control UI โดยไม่มี identity ของอุปกรณ์เมื่อหน้า ถูกโหลดผ่าน HTTP ที่ไม่ปลอดภัย
  • ไม่เลี่ยงผ่านการตรวจการจับคู่
  • ไม่ผ่อนปรนข้อกำหนด identity ของอุปกรณ์ระยะไกล (non-localhost)

ควรใช้ HTTPS (Tailscale Serve) หรือเปิด UI บน 127.0.0.1

เฉพาะสำหรับสถานการณ์ break-glass เท่านั้น gateway.controlUi.dangerouslyDisableDeviceAuth จะปิดการตรวจ identity ของอุปกรณ์ทั้งหมด นี่เป็นการลดระดับความปลอดภัยอย่างร้ายแรง; ปิดไว้เว้นแต่คุณกำลังดีบักอยู่จริงและสามารถย้อนกลับได้อย่างรวดเร็ว

แยกจาก flag อันตรายเหล่านั้น gateway.auth.mode: "trusted-proxy" ที่สำเร็จ สามารถรับเซสชัน Control UI ของ operator โดยไม่มี identity ของอุปกรณ์ได้ นี่เป็น พฤติกรรม auth-mode โดยตั้งใจ ไม่ใช่ทางลัด allowInsecureAuth และยังคง ไม่ขยายไปถึงเซสชัน Control UI แบบบทบาทโหนด

openclaw security audit จะเตือนเมื่อเปิดใช้การตั้งค่านี้

สรุป flag ที่ไม่ปลอดภัยหรืออันตราย

openclaw security audit จะแจ้ง config.insecure_or_dangerous_flags เมื่อ เปิดใช้สวิตช์ดีบักที่ทราบว่าไม่ปลอดภัย/อันตราย ปล่อยค่าเหล่านี้ว่างไว้ใน production แต่ละ flag ที่เปิดใช้จะถูกรายงานเป็นข้อค้นพบของตัวเอง หากกำหนดค่า การ suppress audit ไว้ security.audit.suppressions.active จะยังอยู่ใน ผลลัพธ์ audit ที่ active แม้ข้อค้นพบที่ตรงกันจะย้ายไปที่ suppressedFindings

Flag ที่ audit ติดตามในวันนี้
  • gateway.controlUi.allowInsecureAuth=true
  • gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true
  • gateway.controlUi.dangerouslyDisableDeviceAuth=true
  • security.audit.suppressions configured (<count>)
  • hooks.gmail.allowUnsafeExternalContent=true
  • hooks.mappings[<index>].allowUnsafeExternalContent=true
  • tools.exec.applyPatch.workspaceOnly=false
  • plugins.entries.acpx.config.permissionMode=approve-all
คีย์ `dangerous*` / `dangerously*` ทั้งหมดใน config schema

Control UI และเบราว์เซอร์:

  • gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback
  • gateway.controlUi.dangerouslyDisableDeviceAuth
  • browser.ssrfPolicy.dangerouslyAllowPrivateNetwork

การจับคู่ชื่อช่องทาง (ช่องทางที่ bundled และช่องทาง plugin; ยังใช้ได้ต่อ accounts.<accountId> เมื่อเกี่ยวข้อง):

  • channels.discord.dangerouslyAllowNameMatching
  • channels.slack.dangerouslyAllowNameMatching
  • channels.googlechat.dangerouslyAllowNameMatching
  • channels.msteams.dangerouslyAllowNameMatching
  • channels.synology-chat.dangerouslyAllowNameMatching (ช่องทาง plugin)
  • channels.synology-chat.dangerouslyAllowInheritedWebhookPath (ช่องทาง plugin)
  • channels.zalouser.dangerouslyAllowNameMatching (ช่องทาง plugin)
  • channels.irc.dangerouslyAllowNameMatching (ช่องทาง plugin)
  • channels.mattermost.dangerouslyAllowNameMatching (ช่องทาง plugin)

การเปิดเผยเครือข่าย:

  • channels.telegram.network.dangerouslyAllowPrivateNetwork (รวมถึงต่อบัญชีด้วย)

Sandbox Docker (ค่าเริ่มต้น + ต่อ agent):

  • agents.defaults.sandbox.docker.dangerouslyAllowReservedContainerTargets
  • agents.defaults.sandbox.docker.dangerouslyAllowExternalBindSources
  • agents.defaults.sandbox.docker.dangerouslyAllowContainerNamespaceJoin

การกำหนดค่า reverse proxy

ถ้าคุณรัน Gateway อยู่หลัง reverse proxy (nginx, Caddy, Traefik ฯลฯ) ให้กำหนดค่า gateway.trustedProxies เพื่อให้จัดการ IP ไคลเอนต์ที่ถูกส่งต่อได้ถูกต้อง

เมื่อ Gateway ตรวจพบ proxy headers จากที่อยู่ที่ ไม่ อยู่ใน trustedProxies จะ ไม่ ถือว่าการเชื่อมต่อเป็นไคลเอนต์ภายในเครื่อง หากปิดใช้งาน gateway auth การเชื่อมต่อเหล่านั้นจะถูกปฏิเสธ วิธีนี้ป้องกันการเลี่ยงผ่านการยืนยันตัวตนที่การเชื่อมต่อผ่าน proxy อาจดูเหมือนมาจาก localhost และได้รับความไว้วางใจอัตโนมัติ

gateway.trustedProxies ยังป้อนให้ gateway.auth.mode: "trusted-proxy" ด้วย แต่ auth mode นั้นเข้มงวดกว่า:

  • trusted-proxy auth ล้มเหลวแบบปิดกับ proxy ที่มีแหล่งที่มาจาก loopback โดยค่าเริ่มต้น
  • reverse proxy แบบ loopback บน host เดียวกันสามารถใช้ gateway.trustedProxies สำหรับการตรวจจับไคลเอนต์ภายในเครื่องและการจัดการ IP ที่ส่งต่อ
  • reverse proxy แบบ loopback บน host เดียวกันสามารถผ่าน gateway.auth.mode: "trusted-proxy" ได้เฉพาะเมื่อ gateway.auth.trustedProxy.allowLoopback = true; มิฉะนั้นให้ใช้ token/password auth
yaml
gateway:  trustedProxies:    - "10.0.0.1" # reverse proxy IP  # Optional. Default false.  # Only enable if your proxy cannot provide X-Forwarded-For.  allowRealIpFallback: false  auth:    mode: password    password: ${OPENCLAW_GATEWAY_PASSWORD}

เมื่อกำหนดค่า trustedProxies แล้ว Gateway จะใช้ X-Forwarded-For เพื่อระบุ IP ของไคลเอนต์ X-Real-IP จะถูกละเว้นโดยค่าเริ่มต้น เว้นแต่จะตั้งค่า gateway.allowRealIpFallback: true อย่างชัดเจน

trusted proxy headers ไม่ได้ทำให้การจับคู่อุปกรณ์โหนดเชื่อถือโดยอัตโนมัติ gateway.nodes.pairing.autoApproveCidrs เป็นนโยบาย operator ที่แยกต่างหากและ ปิดไว้โดยค่าเริ่มต้น แม้จะเปิดใช้แล้ว พาธ trusted-proxy header ที่มีแหล่งที่มาจาก loopback จะถูกยกเว้นจากการอนุมัติโหนดอัตโนมัติ เพราะผู้เรียกภายในเครื่องสามารถปลอมแปลง headers เหล่านั้นได้ รวมถึงเมื่อเปิดใช้ loopback trusted-proxy auth อย่างชัดเจน

พฤติกรรม reverse proxy ที่ดี (เขียนทับ forwarding headers ขาเข้า):

nginx
proxy_set_header X-Forwarded-For $remote_addr;proxy_set_header X-Real-IP $remote_addr;

พฤติกรรม reverse proxy ที่ไม่ดี (ต่อท้าย/คง forwarding headers ที่ไม่น่าเชื่อถือ):

nginx
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

หมายเหตุเกี่ยวกับ HSTS และ origin

  • OpenClaw Gateway ให้ความสำคัญกับ local/loopback เป็นอันดับแรก หากคุณยุติ TLS ที่ reverse proxy ให้ตั้งค่า HSTS บนโดเมน HTTPS ที่หันเข้าหา proxy ที่นั่น
  • หาก Gateway ยุติ HTTPS เอง คุณสามารถตั้งค่า gateway.http.securityHeaders.strictTransportSecurity เพื่อปล่อย header HSTS จากการตอบกลับของ OpenClaw ได้
  • คำแนะนำการปรับใช้โดยละเอียดอยู่ใน การยืนยันตัวตนผ่าน Proxy ที่เชื่อถือได้
  • สำหรับการปรับใช้ Control UI ที่ไม่ใช่ loopback จะต้องมี gateway.controlUi.allowedOrigins ตามค่าเริ่มต้น
  • gateway.controlUi.allowedOrigins: ["*"] เป็นนโยบาย browser-origin แบบอนุญาตทั้งหมดอย่างชัดเจน ไม่ใช่ค่าเริ่มต้นที่เสริมความปลอดภัยแล้ว หลีกเลี่ยงการใช้นอกการทดสอบในเครื่องที่ควบคุมอย่างเข้มงวด
  • ความล้มเหลวในการยืนยันตัวตนของ browser-origin บน loopback ยังคงถูกจำกัดอัตรา แม้เมื่อเปิดใช้งาน การยกเว้น loopback ทั่วไป แต่ lockout key จะถูกกำหนดขอบเขตต่อค่า Origin ที่ normalize แล้ว แทนที่จะใช้ bucket localhost ร่วมกันเพียงอันเดียว
  • gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true เปิดใช้งานโหมด fallback ของ origin จาก Host-header; ให้ถือว่าเป็นนโยบายอันตรายที่ operator เลือกเอง
  • ให้ถือว่า DNS rebinding และพฤติกรรม proxy-host header เป็นข้อกังวลด้านการเสริมความปลอดภัยของการปรับใช้; จำกัด trustedProxies ให้เข้มงวดและหลีกเลี่ยงการเปิด Gateway ให้เข้าถึงได้โดยตรงจากอินเทอร์เน็ตสาธารณะ

บันทึก session ในเครื่องอยู่บนดิสก์

OpenClaw จัดเก็บ transcript ของ session บนดิสก์ภายใต้ ~/.openclaw/agents/<agentId>/sessions/*.jsonl สิ่งนี้จำเป็นสำหรับความต่อเนื่องของ session และ (หากเลือกใช้) การทำดัชนีหน่วยความจำของ session แต่ก็หมายความว่า process/user ใดก็ตามที่เข้าถึง filesystem ได้สามารถอ่านบันทึกเหล่านั้นได้ ให้ถือว่าการเข้าถึงดิสก์เป็น trust boundary และล็อกสิทธิ์บน ~/.openclaw ให้แน่นหนา (ดูส่วน audit ด้านล่าง) หากคุณต้องการ การแยกระหว่าง agents ที่เข้มงวดยิ่งขึ้น ให้รันภายใต้ผู้ใช้ OS แยกกันหรือโฮสต์แยกกัน

การประมวลผล Node (system.run)

หากจับคู่ node ของ macOS ไว้ Gateway สามารถเรียกใช้ system.run บน node นั้นได้ นี่คือ การเรียกใช้โค้ดระยะไกล บน Mac:

  • ต้องมีการจับคู่ node (การอนุมัติ + token)
  • การจับคู่ node ของ Gateway ไม่ใช่พื้นผิวการอนุมัติแบบรายคำสั่ง แต่เป็นการกำหนดตัวตน/ความเชื่อถือของ node และการออก token
  • Gateway ใช้นโยบายคำสั่ง node ส่วนกลางแบบคร่าว ๆ ผ่าน gateway.nodes.allowCommands / denyCommands
  • ควบคุมบน Mac ผ่าน Settings → Exec approvals (security + ask + allowlist)
  • นโยบาย system.run ต่อ node คือไฟล์ exec approvals ของ node เอง (exec.approvals.node.*) ซึ่งอาจเข้มงวดกว่าหรือผ่อนปรนกว่านโยบาย command-ID ส่วนกลางของ Gateway
  • node ที่รันด้วย security="full" และ ask="off" กำลังทำตามโมเดล trusted-operator เริ่มต้น ให้ถือว่านี่เป็นพฤติกรรมที่คาดไว้ เว้นแต่การปรับใช้ของคุณจะกำหนดท่าทีการอนุมัติหรือ allowlist ที่เข้มงวดกว่าอย่างชัดเจน
  • โหมดการอนุมัติผูกกับบริบทคำขอที่แน่นอน และเมื่อเป็นไปได้ จะผูกกับ operand ของสคริปต์/ไฟล์ในเครื่องที่เป็นรูปธรรมหนึ่งรายการ หาก OpenClaw ไม่สามารถระบุไฟล์ในเครื่องโดยตรงเพียงไฟล์เดียวสำหรับคำสั่ง interpreter/runtime ได้อย่างแน่นอน การประมวลผลที่อิงการอนุมัติจะถูกปฏิเสธ แทนที่จะสัญญาว่าครอบคลุมเชิงความหมายทั้งหมด
  • สำหรับ host=node การรันที่อิงการอนุมัติจะจัดเก็บ systemRunPlan ที่เตรียมไว้แบบ canonical ด้วย; การ forward ที่อนุมัติในภายหลังจะใช้ plan ที่จัดเก็บนั้นซ้ำ และการตรวจสอบของ Gateway จะปฏิเสธการแก้ไข command/cwd/session context จากผู้เรียก หลังจากสร้างคำขอ การอนุมัติแล้ว
  • หากคุณไม่ต้องการการประมวลผลระยะไกล ให้ตั้งค่า security เป็น deny และลบการจับคู่ node สำหรับ Mac เครื่องนั้น

ความแตกต่างนี้สำคัญต่อการ triage:

  • node ที่จับคู่ไว้ซึ่ง reconnect แล้วโฆษณารายการคำสั่งที่แตกต่างออกไป โดยตัวมันเองไม่ใช่ช่องโหว่ หากนโยบายส่วนกลางของ Gateway และ exec approvals ในเครื่องของ node ยังคงบังคับใช้ boundary การประมวลผลจริง
  • รายงานที่ถือว่า metadata การจับคู่ node เป็นชั้นการอนุมัติรายคำสั่งที่ซ่อนอยู่ชั้นที่สอง มักเป็นความสับสนด้านนโยบาย/UX ไม่ใช่การข้าม security boundary

Skills แบบไดนามิก (watcher / remote nodes)

OpenClaw สามารถรีเฟรชรายการ Skills ระหว่าง session ได้:

  • Skills watcher: การเปลี่ยนแปลงใน SKILL.md สามารถอัปเดต snapshot ของ Skills ใน turn ถัดไปของ agent
  • Remote nodes: การเชื่อมต่อ node ของ macOS สามารถทำให้ Skills เฉพาะ macOS มีสิทธิ์ใช้งานได้ (อิงจากการ probe bin)

ให้ถือว่าโฟลเดอร์ skill เป็น โค้ดที่เชื่อถือได้ และจำกัดผู้ที่สามารถแก้ไขได้

โมเดลภัยคุกคาม

ผู้ช่วย AI ของคุณสามารถ:

  • เรียกใช้คำสั่ง shell ใดก็ได้
  • อ่าน/เขียนไฟล์
  • เข้าถึงบริการเครือข่าย
  • ส่งข้อความถึงใครก็ได้ (หากคุณให้สิทธิ์เข้าถึง WhatsApp)

ผู้ที่ส่งข้อความถึงคุณสามารถ:

  • พยายามหลอก AI ของคุณให้ทำสิ่งไม่ดี
  • social engineer เพื่อเข้าถึงข้อมูลของคุณ
  • probe รายละเอียดโครงสร้างพื้นฐาน

แนวคิดหลัก: access control ก่อน intelligence

ความล้มเหลวส่วนใหญ่ตรงนี้ไม่ใช่ exploit ที่ซับซ้อน แต่คือ "มีคนส่งข้อความถึง bot แล้ว bot ก็ทำตามที่เขาขอ"

ท่าทีของ OpenClaw:

  • ตัวตนก่อน: ตัดสินว่าใครคุยกับ bot ได้ (การจับคู่ DM / allowlists / "open" อย่างชัดเจน)
  • ขอบเขตถัดมา: ตัดสินว่า bot ได้รับอนุญาตให้ทำงานที่ไหน (allowlists ของกลุ่ม + mention gating, tools, sandboxing, สิทธิ์ของอุปกรณ์)
  • โมเดลสุดท้าย: สมมติว่าโมเดลถูกชักจูงได้; ออกแบบให้การชักจูงมี blast radius จำกัด

โมเดลการอนุญาตคำสั่ง

คำสั่ง Slash และ directives จะถูกปฏิบัติตามเฉพาะสำหรับ ผู้ส่งที่ได้รับอนุญาต เท่านั้น การอนุญาตได้มาจาก allowlists/การจับคู่ของ channel บวกกับ commands.useAccessGroups (ดู การกำหนดค่า และ คำสั่ง Slash) หาก allowlist ของ channel ว่างหรือมี "*", คำสั่งจะเปิดใช้งานสำหรับ channel นั้นโดยมีผล

/exec เป็นความสะดวกเฉพาะ session สำหรับ operator ที่ได้รับอนุญาต มัน ไม่ เขียน config หรือ เปลี่ยน session อื่น

ความเสี่ยงของเครื่องมือ control plane

เครื่องมือในตัวสองรายการสามารถเปลี่ยนแปลง control-plane แบบถาวรได้:

  • gateway สามารถตรวจสอบ config ด้วย config.schema.lookup / config.get และสามารถทำการเปลี่ยนแปลงถาวรด้วย config.apply, config.patch, และ update.run
  • cron สามารถสร้างงานตามกำหนดเวลาที่รันต่อไปหลังจาก chat/task เดิมสิ้นสุดลง

เครื่องมือ runtime gateway ที่ agent เห็นยังคงปฏิเสธการเขียนทับ tools.exec.ask หรือ tools.exec.security; alias เดิม tools.bash.* จะถูก normalize ไปยังเส้นทาง exec ที่ได้รับการป้องกันเดียวกันก่อนเขียน การแก้ไข gateway config.apply และ gateway config.patch ที่ขับเคลื่อนโดย agent จะ fail-closed ตามค่าเริ่มต้น: มีเพียงชุดแคบ ๆ ของการปรับ runtime ที่มีความเสี่ยงต่ำ, mention-gating, และเส้นทาง visible-reply เท่านั้นที่ agent ปรับได้ ค่าเริ่มต้นของโมเดลทั่วโลก และ prompt overlays ยังคงอยู่ภายใต้การควบคุมของ operator ดังนั้น config tree ที่ละเอียดอ่อนใหม่ จึงได้รับการป้องกัน เว้นแต่จะถูกเพิ่มเข้า allowlist อย่างตั้งใจ

สำหรับ agent/surface ใดก็ตามที่จัดการเนื้อหาที่ไม่น่าเชื่อถือ ให้ปฏิเสธสิ่งเหล่านี้ตามค่าเริ่มต้น:

json5
{  tools: {    deny: ["gateway", "cron", "sessions_spawn", "sessions_send"],  },}

commands.restart=false บล็อกเฉพาะการกระทำ restart เท่านั้น ไม่ได้ปิดใช้งานการกระทำ config/update ของ gateway

Plugins

Plugins รัน in-process กับ Gateway ให้ถือว่าเป็นโค้ดที่เชื่อถือได้:

  • ติดตั้ง plugins จากแหล่งที่คุณเชื่อถือเท่านั้น
  • ควรใช้ allowlists plugins.allow อย่างชัดเจน
  • ตรวจสอบ config ของ plugin ก่อนเปิดใช้งาน
  • restart Gateway หลังเปลี่ยนแปลง plugin
  • หากคุณติดตั้งหรืออัปเดต plugins (openclaw plugins install <package>, openclaw plugins update <id>) ให้ถือว่าเหมือนการรันโค้ดที่ไม่น่าเชื่อถือ:
    • เส้นทางติดตั้งคือไดเรกทอรีต่อ plugin ภายใต้ root การติดตั้ง plugin ที่ใช้งานอยู่
    • OpenClaw ไม่รันการบล็อกโค้ดอันตรายในเครื่องแบบ built-in ระหว่าง install/update ใช้ security.installPolicy สำหรับการตัดสินใจ allow/block ในเครื่องที่ operator เป็นเจ้าของ และ openclaw security audit --deep สำหรับการสแกนวินิจฉัย
    • การติดตั้ง plugin ผ่าน npm และ git จะรันการปรับ dependency ของ package-manager ให้สอดคล้องกันเฉพาะใน flow install/update ที่ชัดเจนเท่านั้น เส้นทางในเครื่องและ archive จะถูกถือว่าเป็นแพ็กเกจ plugin ที่มีทุกอย่างในตัว; OpenClaw จะคัดลอก/อ้างอิงโดยไม่รัน npm install
    • ควรใช้เวอร์ชันที่ pin ไว้แบบ exact (@scope/pkg@1.2.3) และตรวจสอบโค้ดที่ unpack แล้วบนดิสก์ก่อนเปิดใช้งาน
    • --dangerously-force-unsafe-install ถูกเลิกใช้แล้วและไม่เปลี่ยนพฤติกรรม install/update ของ plugin อีกต่อไป
    • กำหนดค่า security.installPolicy เมื่อ operator ต้องการคำสั่งในเครื่องที่เชื่อถือได้เพื่อทำการตัดสินใจ allow/block เฉพาะโฮสต์สำหรับการติดตั้ง skill และ plugin นโยบายนี้รันหลังจากจัดเตรียม material จาก source แล้ว แต่ก่อนดำเนินการติดตั้งต่อไป ใช้กับ Skills ของ ClawHub ด้วย และไม่ถูกข้ามโดย flags unsafe ที่เลิกใช้แล้ว

รายละเอียด: Plugins

โมเดลการเข้าถึง DM: การจับคู่, allowlist, open, disabled

channel ปัจจุบันทั้งหมดที่รองรับ DM รองรับนโยบาย DM (dmPolicy หรือ *.dm.policy) ที่ gate DM ขาเข้า ก่อน ประมวลผลข้อความ:

  • pairing (ค่าเริ่มต้น): ผู้ส่งที่ไม่รู้จักจะได้รับรหัสการจับคู่สั้น ๆ และ bot จะละเว้นข้อความของพวกเขาจนกว่าจะได้รับอนุมัติ รหัสหมดอายุหลัง 1 ชั่วโมง; DM ซ้ำจะไม่ส่งรหัสซ้ำจนกว่าจะสร้างคำขอใหม่ คำขอที่รอดำเนินการถูกจำกัดไว้ที่ 3 ต่อ channel ตามค่าเริ่มต้น
  • allowlist: ผู้ส่งที่ไม่รู้จักถูกบล็อก (ไม่มี handshake การจับคู่)
  • open: อนุญาตให้ทุกคน DM ได้ (สาธารณะ) ต้องมี allowlist ของ channel ที่มี "*" (opt-in อย่างชัดเจน)
  • disabled: ละเว้น DM ขาเข้าทั้งหมด

อนุมัติผ่าน CLI:

bash
openclaw pairing list <channel>openclaw pairing approve <channel> <code>

รายละเอียด + ไฟล์บนดิสก์: การจับคู่

การแยก session ของ DM (โหมดหลายผู้ใช้)

ตามค่าเริ่มต้น OpenClaw จะ route DM ทั้งหมดเข้าสู่ session หลัก เพื่อให้ผู้ช่วยของคุณมีความต่อเนื่องข้ามอุปกรณ์และ channel หาก หลายคน สามารถ DM ถึง bot ได้ (DM แบบ open หรือ allowlist หลายคน) ให้พิจารณาแยก session ของ DM:

json5
{  session: { dmScope: "per-channel-peer" },}

สิ่งนี้ป้องกันการรั่วไหลของบริบทข้ามผู้ใช้ ในขณะที่ยังคงแยก group chats ไว้

นี่เป็น boundary ของ messaging-context ไม่ใช่ boundary ของ host-admin หากผู้ใช้เป็นปรปักษ์ต่อกันและใช้โฮสต์/config ของ Gateway เดียวกัน ให้รัน gateway แยกกันต่อ trust boundary แทน

โหมด DM ที่ปลอดภัย (แนะนำ)

ให้ถือว่า snippet ด้านบนเป็น โหมด DM ที่ปลอดภัย:

  • ค่าเริ่มต้น: session.dmScope: "main" (DM ทั้งหมดใช้ session เดียวร่วมกันเพื่อความต่อเนื่อง)
  • ค่าเริ่มต้นของ local CLI onboarding: เขียน session.dmScope: "per-channel-peer" เมื่อไม่ได้ตั้งค่าไว้ (เก็บค่าที่ตั้งไว้อย่างชัดเจนเดิมไว้)
  • โหมด DM ที่ปลอดภัย: session.dmScope: "per-channel-peer" (แต่ละคู่ channel+sender ได้บริบท DM ที่แยกกัน)
  • การแยก peer ข้าม channel: session.dmScope: "per-peer" (ผู้ส่งแต่ละคนได้ session เดียวในทุก channel ประเภทเดียวกัน)

หากคุณรันหลายบัญชีบน channel เดียวกัน ให้ใช้ per-account-channel-peer แทน หากบุคคลเดียวกันติดต่อคุณในหลาย channel ให้ใช้ session.identityLinks เพื่อรวม session DM เหล่านั้นเป็นตัวตน canonical เดียว ดู การจัดการ Session และ การกำหนดค่า

Allowlists สำหรับ DM และกลุ่ม

OpenClaw มีเลเยอร์ "ใครสามารถ trigger ฉันได้?" แยกกันสองชั้น:

  • รายการอนุญาต DM (allowFrom / channels.discord.allowFrom / channels.slack.allowFrom; แบบเดิม: channels.discord.dm.allowFrom, channels.slack.dm.allowFrom): ใครได้รับอนุญาตให้คุยกับบอตในข้อความโดยตรง
    • เมื่อ dmPolicy="pairing" การอนุมัติจะถูกเขียนไปยังที่เก็บรายการอนุญาตการจับคู่แบบผูกกับบัญชีภายใต้ ~/.openclaw/credentials/ (<channel>-allowFrom.json สำหรับบัญชีเริ่มต้น, <channel>-<accountId>-allowFrom.json สำหรับบัญชีที่ไม่ใช่ค่าเริ่มต้น) แล้วผสานกับรายการอนุญาตในคอนฟิก
  • รายการอนุญาตกลุ่ม (เฉพาะช่องทาง): กลุ่ม/ช่อง/กิลด์ใดที่บอตจะยอมรับข้อความ
    • รูปแบบที่พบบ่อย:
      • channels.whatsapp.groups, channels.telegram.groups, channels.imessage.groups: ค่าเริ่มต้นต่อกลุ่ม เช่น requireMention; เมื่อตั้งค่าแล้ว ค่านี้จะทำหน้าที่เป็นรายการอนุญาตกลุ่มด้วย (ใส่ "*" เพื่อคงพฤติกรรมอนุญาตทั้งหมด)
      • groupPolicy="allowlist" + groupAllowFrom: จำกัดว่าใครสามารถเรียกใช้บอต ภายใน เซสชันกลุ่มได้ (WhatsApp/Telegram/Signal/iMessage/Microsoft Teams)
      • channels.discord.guilds / channels.slack.channels: รายการอนุญาตต่อพื้นผิว + ค่าเริ่มต้นของการกล่าวถึง
    • การตรวจกลุ่มทำตามลำดับนี้: groupPolicy/รายการอนุญาตกลุ่มก่อน แล้วจึงเป็นการเปิดใช้งานด้วยการกล่าวถึง/การตอบกลับ
    • การตอบกลับข้อความของบอต (การกล่าวถึงโดยนัย) ไม่ ข้ามรายการอนุญาตของผู้ส่ง เช่น groupAllowFrom
    • หมายเหตุด้านความปลอดภัย: ให้ถือว่า dmPolicy="open" และ groupPolicy="open" เป็นการตั้งค่าสำหรับทางเลือกสุดท้าย ควรใช้น้อยที่สุด; แนะนำให้ใช้การจับคู่ + รายการอนุญาต เว้นแต่คุณจะเชื่อถือสมาชิกทุกคนในห้องอย่างเต็มที่

รายละเอียด: การกำหนดค่า และ กลุ่ม

Prompt injection (คืออะไร และเหตุใดจึงสำคัญ)

Prompt injection คือกรณีที่ผู้โจมตีสร้างข้อความที่บงการโมเดลให้ทำบางอย่างที่ไม่ปลอดภัย ("ละเว้นคำสั่งของคุณ", "เปิดเผยระบบไฟล์ของคุณ", "ตามลิงก์นี้แล้วรันคำสั่ง" เป็นต้น)

แม้จะมี system prompt ที่แข็งแรง prompt injection ก็ยังไม่ถูกแก้ได้หมด แนวป้องกันใน system prompt เป็นเพียงคำแนะนำแบบอ่อนเท่านั้น; การบังคับใช้จริงมาจากนโยบายเครื่องมือ, การอนุมัติ exec, sandboxing และรายการอนุญาตของช่องทาง (และผู้ปฏิบัติการสามารถปิดสิ่งเหล่านี้ได้ตามการออกแบบ) สิ่งที่ช่วยได้จริง:

  • ล็อก DM ขาเข้าให้แน่น (การจับคู่/รายการอนุญาต)
  • แนะนำให้ใช้การบังคับกล่าวถึงในกลุ่ม; หลีกเลี่ยงบอตแบบ "เปิดตลอดเวลา" ในห้องสาธารณะ
  • ถือว่าลิงก์ ไฟล์แนบ และคำสั่งที่วางมาเป็นสิ่งไม่ปลอดภัยโดยค่าเริ่มต้น
  • รันการเรียกใช้เครื่องมือที่อ่อนไหวใน sandbox; เก็บความลับออกจากระบบไฟล์ที่เอเจนต์เข้าถึงได้
  • หมายเหตุ: sandboxing เป็นแบบเลือกเปิดใช้ หากโหมด sandbox ปิดอยู่ host=auto โดยนัยจะ resolve ไปยังโฮสต์ Gateway ส่วน host=sandbox แบบชัดเจนยังคงล้มเหลวแบบปิด เพราะไม่มี runtime ของ sandbox ให้ใช้ ตั้งค่า host=gateway หากคุณต้องการให้พฤติกรรมนั้นชัดเจนในคอนฟิก
  • จำกัดเครื่องมือความเสี่ยงสูง (exec, browser, web_fetch, web_search) ให้ใช้เฉพาะกับเอเจนต์ที่เชื่อถือได้หรือรายการอนุญาตที่ระบุชัดเจน
  • หากคุณอนุญาต interpreter (python, node, ruby, perl, php, lua, osascript) ให้เปิด tools.exec.strictInlineEval เพื่อให้รูปแบบ inline eval ยังต้องได้รับการอนุมัติอย่างชัดเจน
  • การวิเคราะห์การอนุมัติ shell ยังปฏิเสธรูปแบบ POSIX parameter-expansion ($VAR, $?, $$, $1, $@, ${…}) ภายใน heredoc ที่ไม่ quote ดังนั้นเนื้อหา heredoc ที่อยู่ในรายการอนุญาตจะไม่สามารถแอบทำ shell expansion ผ่านการตรวจรายการอนุญาตในฐานะข้อความธรรมดาได้ ให้ quote ตัวปิด heredoc (เช่น <<'EOF') เพื่อเลือกใช้ความหมายของเนื้อหาแบบ literal; heredoc ที่ไม่ quote และจะขยายตัวแปรจะถูกปฏิเสธ
  • การเลือกโมเดลมีผล: โมเดลเก่า/เล็ก/legacy ทนทานต่อ prompt injection และการใช้เครื่องมือผิดทางได้น้อยกว่ามาก สำหรับเอเจนต์ที่เปิดใช้เครื่องมือ ให้ใช้โมเดลรุ่นล่าสุดที่แข็งแรงที่สุดและเสริมความทนทานต่อคำสั่งมากที่สุดเท่าที่มี

สัญญาณอันตรายที่ควรถือว่าไม่น่าเชื่อถือ:

  • "อ่านไฟล์/URL นี้แล้วทำตามที่เขียนไว้อย่างเคร่งครัด"
  • "ละเว้น system prompt หรือกฎความปลอดภัยของคุณ"
  • "เปิดเผยคำสั่งที่ซ่อนอยู่หรือผลลัพธ์ของเครื่องมือ"
  • "วางเนื้อหาทั้งหมดของ ~/.openclaw หรือ log ของคุณ"

การล้างโทเค็นพิเศษในเนื้อหาภายนอก

OpenClaw จะลบ literal ของโทเค็นพิเศษใน chat-template ของ LLM แบบ self-hosted ที่พบบ่อยออกจากเนื้อหาและเมตาดาตาภายนอกที่ถูกห่อไว้ ก่อนที่สิ่งเหล่านั้นจะถึงโมเดล กลุ่ม marker ที่ครอบคลุมรวมถึงโทเค็น role/turn ของ Qwen/ChatML, Llama, Gemma, Mistral, Phi และ GPT-OSS

เหตุผล:

  • แบ็กเอนด์ที่เข้ากันได้กับ OpenAI ซึ่งอยู่หน้าโมเดล self-hosted บางครั้งจะคงโทเค็นพิเศษที่ปรากฏในข้อความผู้ใช้ไว้ แทนที่จะปิดบัง ผู้โจมตีที่สามารถเขียนลงในเนื้อหาภายนอกขาเข้า (หน้าที่ fetch มา, เนื้อหาอีเมล, ผลลัพธ์เครื่องมืออ่านไฟล์) อาจแทรกขอบเขต role assistant หรือ system สังเคราะห์ แล้วหลบแนวป้องกันของ wrapped-content ได้
  • การล้างเกิดขึ้นที่ชั้นห่อเนื้อหาภายนอก จึงใช้ได้สม่ำเสมอทั้งกับเครื่องมือ fetch/read และเนื้อหาช่องทางขาเข้า แทนที่จะทำแยกตามผู้ให้บริการ
  • คำตอบขาออกของโมเดลมี sanitizer แยกอยู่แล้ว ซึ่งลบโครงสร้าง runtime ภายในที่รั่วออกมา เช่น <tool_call>, <function_calls>, <system-reminder>, <previous_response> และรายการคล้ายกัน ออกจากคำตอบที่ผู้ใช้เห็น ณ ขอบเขตการส่งมอบช่องทางขั้นสุดท้าย sanitizer ของเนื้อหาภายนอกคือส่วนคู่กันฝั่งขาเข้า

สิ่งนี้ไม่ได้แทนที่การเสริมความแข็งแรงอื่น ๆ ในหน้านี้ - dmPolicy, รายการอนุญาต, การอนุมัติ exec, sandboxing และ contextVisibility ยังคงเป็นงานหลัก สิ่งนี้ปิด bypass เฉพาะจุดในชั้น tokenizer สำหรับสแต็ก self-hosted ที่ส่งต่อข้อความผู้ใช้พร้อมโทเค็นพิเศษแบบครบถ้วน

แฟล็ก bypass เนื้อหาภายนอกที่ไม่ปลอดภัย

OpenClaw มีแฟล็ก bypass แบบชัดเจนที่ปิดการห่อความปลอดภัยของเนื้อหาภายนอก:

  • hooks.mappings[].allowUnsafeExternalContent
  • hooks.gmail.allowUnsafeExternalContent
  • ฟิลด์ payload ของ Cron allowUnsafeExternalContent

คำแนะนำ:

  • ปล่อยให้ค่าเหล่านี้ไม่ได้ตั้ง/เป็น false ใน production
  • เปิดใช้ชั่วคราวเท่านั้นสำหรับการดีบักที่จำกัดขอบเขตแน่นหนา
  • หากเปิดใช้ ให้แยกเอเจนต์นั้นออก (sandbox + เครื่องมือน้อยที่สุด + namespace เซสชันเฉพาะ)

หมายเหตุความเสี่ยงของ hook:

  • payload ของ hook เป็นเนื้อหาที่ไม่น่าเชื่อถือ แม้การส่งจะมาจากระบบที่คุณควบคุม (เนื้อหาเมล/เอกสาร/เว็บสามารถมี prompt injection ได้)
  • ระดับโมเดลที่อ่อนเพิ่มความเสี่ยงนี้ สำหรับ automation ที่ขับเคลื่อนด้วย hook แนะนำให้ใช้ระดับโมเดลสมัยใหม่ที่แข็งแรง และคุมนโยบายเครื่องมือให้แน่น (tools.profile: "messaging" หรือเข้มงวดกว่า) พร้อม sandboxing เมื่อทำได้

Prompt injection ไม่จำเป็นต้องอาศัย DM สาธารณะ

แม้ว่า มีเพียงคุณเท่านั้น ที่ส่งข้อความถึงบอตได้ prompt injection ก็ยังเกิดขึ้นได้ผ่าน เนื้อหาที่ไม่น่าเชื่อถือ ใด ๆ ที่บอตอ่าน (ผลลัพธ์ web search/fetch, หน้า browser, อีเมล, เอกสาร, ไฟล์แนบ, log/code ที่วางมา) กล่าวอีกอย่างคือ: ผู้ส่งไม่ใช่ พื้นผิวภัยคุกคามเพียงอย่างเดียว; ตัวเนื้อหาเอง สามารถพกคำสั่งเชิงโจมตีมาได้

เมื่อเปิดใช้เครื่องมือ ความเสี่ยงทั่วไปคือการขโมย context หรือกระตุ้นให้เกิด การเรียกเครื่องมือ ลดขอบเขตผลกระทบโดย:

  • ใช้ เอเจนต์อ่าน แบบ read-only หรือปิดเครื่องมือ เพื่อสรุปเนื้อหาที่ไม่น่าเชื่อถือ แล้วค่อยส่งสรุปนั้นให้เอเจนต์หลัก
  • ปิด web_search / web_fetch / browser สำหรับเอเจนต์ที่เปิดใช้เครื่องมือ เว้นแต่จำเป็น
  • สำหรับอินพุต URL ของ OpenResponses (input_file / input_image) ให้ตั้ง gateway.http.endpoints.responses.files.urlAllowlist และ gateway.http.endpoints.responses.images.urlAllowlist ให้เข้มงวด และคง maxUrlParts ไว้ต่ำ รายการอนุญาตว่างจะถูกถือว่าไม่ได้ตั้งค่า; ใช้ files.allowUrl: false / images.allowUrl: false หากคุณต้องการปิดการ fetch URL ทั้งหมด
  • สำหรับอินพุตไฟล์ของ OpenResponses ข้อความ input_file ที่ decode แล้วจะยังถูกแทรกเป็น เนื้อหาภายนอกที่ไม่น่าเชื่อถือ อย่าพึ่งพาว่าข้อความไฟล์นั้นเชื่อถือได้เพียงเพราะ Gateway decode ในเครื่อง บล็อกที่ถูกแทรกยังคงมี marker ขอบเขต <<&lt;EXTERNAL_UNTRUSTED_CONTENT ...&gt;>> แบบชัดเจน พร้อมเมตาดาตา Source: External แม้เส้นทางนี้จะละ banner SECURITY NOTICE: ที่ยาวกว่า
  • การห่อตาม marker แบบเดียวกันจะถูกใช้เมื่อ media-understanding ดึงข้อความ จากเอกสารแนบ ก่อนต่อท้ายข้อความนั้นเข้ากับ media prompt
  • เปิด sandboxing และรายการอนุญาตเครื่องมือที่เข้มงวดสำหรับเอเจนต์ใด ๆ ที่แตะอินพุตที่ไม่น่าเชื่อถือ
  • เก็บความลับออกจาก prompt; ส่งผ่าน env/config บนโฮสต์ Gateway แทน

แบ็กเอนด์ LLM แบบ self-hosted

แบ็กเอนด์ self-hosted ที่เข้ากันได้กับ OpenAI เช่น vLLM, SGLang, TGI, LM Studio, หรือสแต็ก tokenizer ของ Hugging Face แบบกำหนดเอง อาจแตกต่างจากผู้ให้บริการ hosted ในวิธี จัดการโทเค็นพิเศษของ chat-template หากแบ็กเอนด์ tokenize สตริง literal เช่น <|im_start|>, <|start_header_id|> หรือ <start_of_turn> เป็น โทเค็นเชิงโครงสร้างของ chat-template ภายในเนื้อหาผู้ใช้ ข้อความที่ไม่น่าเชื่อถืออาจพยายาม ปลอมขอบเขต role ที่ชั้น tokenizer

OpenClaw จะลบ literal ของโทเค็นพิเศษจากกลุ่มโมเดลที่พบบ่อยออกจาก เนื้อหาภายนอกที่ถูกห่อไว้ ก่อนส่งต่อไปยังโมเดล เปิดใช้การห่อเนื้อหาภายนอกไว้เสมอ และแนะนำให้ใช้การตั้งค่าแบ็กเอนด์ที่แยกหรือ escape โทเค็นพิเศษ ในเนื้อหาที่ผู้ใช้ให้มา เมื่อมีให้ใช้ ผู้ให้บริการ hosted เช่น OpenAI และ Anthropic ใช้การล้างฝั่งคำขอของตนเองอยู่แล้ว

ความแข็งแรงของโมเดล (หมายเหตุด้านความปลอดภัย)

ความต้านทานต่อ prompt injection ไม่ เท่ากันในทุกระดับโมเดล โมเดลที่เล็กกว่า/ถูกกว่ามักเสี่ยงต่อการใช้เครื่องมือผิดทางและการยึดคำสั่งมากกว่า โดยเฉพาะภายใต้ prompt เชิงโจมตี

คำแนะนำ:

  • ใช้โมเดลรุ่นล่าสุดระดับดีที่สุด สำหรับบอตใด ๆ ที่สามารถรันเครื่องมือหรือแตะไฟล์/เครือข่ายได้
  • อย่าใช้ระดับเก่า/อ่อนกว่า/เล็กกว่า สำหรับเอเจนต์ที่เปิดใช้เครื่องมือหรือ inbox ที่ไม่น่าเชื่อถือ; ความเสี่ยง prompt-injection สูงเกินไป
  • หากจำเป็นต้องใช้โมเดลที่เล็กกว่า ให้ ลดขอบเขตผลกระทบ (เครื่องมือ read-only, sandboxing ที่แข็งแรง, การเข้าถึงระบบไฟล์ขั้นต่ำ, รายการอนุญาตที่เข้มงวด)
  • เมื่อรันโมเดลขนาดเล็ก ให้ เปิด sandboxing สำหรับทุกเซสชัน และ ปิด web_search/web_fetch/browser เว้นแต่อินพุตถูกควบคุมอย่างเข้มงวด
  • สำหรับผู้ช่วยส่วนตัวแบบแชตเท่านั้นที่มีอินพุตที่เชื่อถือได้และไม่มีเครื่องมือ โมเดลที่เล็กกว่ามักใช้ได้

Reasoning และเอาต์พุตแบบละเอียดในกลุ่ม

/reasoning, /verbose และ /trace อาจเปิดเผย reasoning ภายใน, เอาต์พุตของเครื่องมือ หรือ diagnostics ของ plugin ที่ ไม่ได้ตั้งใจให้ปรากฏในช่องสาธารณะ ในการตั้งค่าแบบกลุ่ม ให้ถือว่าสิ่งเหล่านี้เป็น การดีบัก เท่านั้น และปิดไว้ เว้นแต่คุณต้องการใช้อย่างชัดเจน

คำแนะนำ:

  • ปิดใช้ /reasoning, /verbose และ /trace ในห้องสาธารณะ
  • หากคุณเปิดใช้ ให้ทำเฉพาะใน DM ที่เชื่อถือได้หรือห้องที่ควบคุมอย่างเข้มงวด
  • จำไว้ว่า: เอาต์พุต verbose และ trace อาจมี args ของเครื่องมือ, URLs, diagnostics ของ plugin และข้อมูลที่โมเดลเห็น

ตัวอย่างการเสริมความแข็งแรงของการกำหนดค่า

สิทธิ์ของไฟล์

เก็บคอนฟิก + state ให้เป็นส่วนตัวบนโฮสต์ Gateway:

  • ~/.openclaw/openclaw.json: 600 (ผู้ใช้อ่าน/เขียนเท่านั้น)
  • ~/.openclaw: 700 (ผู้ใช้เท่านั้น)

openclaw doctor สามารถเตือนและเสนอให้ปรับสิทธิ์เหล่านี้ให้เข้มงวดขึ้นได้

การเปิดเผยเครือข่าย (bind, port, firewall)

Gateway multiplex WebSocket + HTTP บนพอร์ตเดียว:

  • ค่าเริ่มต้น: 18789
  • คอนฟิก/แฟล็ก/env: gateway.port, --port, OPENCLAW_GATEWAY_PORT

พื้นผิว HTTP นี้รวม Control UI และโฮสต์ canvas:

  • Control UI (แอสเซ็ต SPA) (base path เริ่มต้น /)
  • โฮสต์ canvas: /__openclaw__/canvas/ และ /__openclaw__/a2ui/ (HTML/JS ใด ๆ; ให้ถือว่าเป็นเนื้อหาที่ไม่น่าเชื่อถือ)

หากคุณโหลดเนื้อหา canvas ใน browser ปกติ ให้ปฏิบัติกับมันเหมือนหน้าเว็บที่ไม่น่าเชื่อถืออื่น ๆ:

  • อย่าเปิดโฮสต์ canvas ให้เครือข่าย/ผู้ใช้ที่ไม่น่าเชื่อถือเข้าถึง
  • อย่าให้เนื้อหา canvas ใช้ origin เดียวกับพื้นผิวเว็บที่มีสิทธิ์สูง เว้นแต่คุณจะเข้าใจผลกระทบอย่างเต็มที่

โหมด bind ควบคุมว่า Gateway รับฟังที่ใด:

  • gateway.bind: "loopback" (ค่าเริ่มต้น): เฉพาะไคลเอนต์ในเครื่องเท่านั้นที่เชื่อมต่อได้
  • bind ที่ไม่ใช่ loopback ("lan", "tailnet", "custom") ขยายพื้นผิวการโจมตี ใช้เฉพาะเมื่อมีการยืนยันตัวตนของ Gateway (โทเค็น/รหัสผ่านที่ใช้ร่วมกัน หรือ trusted proxy ที่กำหนดค่าอย่างถูกต้อง) และ firewall จริง

กฎคร่าว ๆ:

  • แนะนำให้ใช้ Tailscale Serve แทนการ bind ผ่าน LAN (Serve จะคง Gateway ไว้บน loopback และให้ Tailscale จัดการการเข้าถึง)
  • หากคุณจำเป็นต้อง bind กับ LAN ให้ firewall พอร์ตนั้นด้วยรายการอนุญาต IP ต้นทางที่จำกัดมาก อย่า port-forward พอร์ตนั้นแบบกว้าง
  • อย่าเปิดเผย Gateway แบบไม่ผ่านการยืนยันตัวตนบน 0.0.0.0 เด็ดขาด

การเผยแพร่พอร์ต Docker ด้วย UFW

หากคุณรัน OpenClaw ด้วย Docker บน VPS โปรดจำไว้ว่าพอร์ตคอนเทนเนอร์ที่เผยแพร่ (-p HOST:CONTAINER หรือ ports: ของ Compose) จะถูก route ผ่าน forwarding chains ของ Docker ไม่ใช่เฉพาะกฎ INPUT ของโฮสต์เท่านั้น

เพื่อให้ทราฟฟิก Docker สอดคล้องกับนโยบาย firewall ของคุณ ให้บังคับใช้กฎใน DOCKER-USER (chain นี้จะถูกประเมินก่อนกฎ accept ของ Docker เอง) บนดิสโทรสมัยใหม่จำนวนมาก iptables/ip6tables ใช้ frontend iptables-nft และยังคงนำกฎเหล่านี้ไปใช้กับ backend nftables

ตัวอย่างรายการอนุญาตขั้นต่ำ (IPv4):

bash
# /etc/ufw/after.rules (append as its own *filter section)*filter:DOCKER-USER - [0:0]-A DOCKER-USER -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN-A DOCKER-USER -s 127.0.0.0/8 -j RETURN-A DOCKER-USER -s 10.0.0.0/8 -j RETURN-A DOCKER-USER -s 172.16.0.0/12 -j RETURN-A DOCKER-USER -s 192.168.0.0/16 -j RETURN-A DOCKER-USER -s 100.64.0.0/10 -j RETURN-A DOCKER-USER -p tcp --dport 80 -j RETURN-A DOCKER-USER -p tcp --dport 443 -j RETURN-A DOCKER-USER -m conntrack --ctstate NEW -j DROP-A DOCKER-USER -j RETURNCOMMIT

IPv6 มีตารางแยกต่างหาก เพิ่มนโยบายที่ตรงกันใน /etc/ufw/after6.rules หาก เปิดใช้ Docker IPv6

หลีกเลี่ยงการ hardcode ชื่อ interface เช่น eth0 ในตัวอย่างเอกสาร ชื่อ interface แตกต่างกันไปตามอิมเมจ VPS (ens3, enp* ฯลฯ) และการไม่ตรงกันอาจทำให้ กฎปฏิเสธของคุณถูกข้ามโดยไม่ตั้งใจ

การตรวจสอบอย่างรวดเร็วหลัง reload:

bash
ufw reloadiptables -S DOCKER-USERip6tables -S DOCKER-USERnmap -sT -p 1-65535 <public-ip> --open

พอร์ตภายนอกที่คาดไว้ควรมีเฉพาะพอร์ตที่คุณตั้งใจเปิดเผยเท่านั้น (สำหรับการตั้งค่าส่วนใหญ่: SSH + พอร์ต reverse proxy ของคุณ)

การค้นพบ mDNS/Bonjour

เมื่อเปิดใช้ Plugin bonjour ที่มาพร้อมชุดติดตั้ง Gateway จะ broadcast การมีอยู่ของตนผ่าน mDNS (_openclaw-gw._tcp บนพอร์ต 5353) สำหรับการค้นพบอุปกรณ์ในเครือข่ายท้องถิ่น ในโหมด full สิ่งนี้รวมถึงระเบียน TXT ที่อาจเปิดเผยรายละเอียดการทำงาน:

  • cliPath: เส้นทางระบบไฟล์แบบเต็มไปยังไบนารี CLI (เปิดเผยชื่อผู้ใช้และตำแหน่งติดตั้ง)
  • sshPort: ประกาศความพร้อมใช้งาน SSH บนโฮสต์
  • displayName, lanHost: ข้อมูลชื่อโฮสต์

ข้อพิจารณาด้านความปลอดภัยในการปฏิบัติงาน: การ broadcast รายละเอียดโครงสร้างพื้นฐานทำให้ทุกคนในเครือข่ายท้องถิ่น reconnaissance ได้ง่ายขึ้น แม้แต่ข้อมูลที่ดู “ไม่เป็นอันตราย” เช่นเส้นทางระบบไฟล์และความพร้อมใช้งาน SSH ก็ช่วยให้ผู้โจมตีทำแผนที่สภาพแวดล้อมของคุณได้

คำแนะนำ:

  1. ปิด Bonjour ไว้ เว้นแต่จำเป็นต้องค้นพบผ่าน LAN Bonjour จะ auto-start บนโฮสต์ macOS และเป็นแบบ opt-in ในที่อื่น ๆ; URL Gateway โดยตรง, Tailnet, SSH หรือ DNS-SD แบบ wide-area ช่วยหลีกเลี่ยง multicast ท้องถิ่นได้

  2. โหมด minimal (ค่าเริ่มต้นเมื่อเปิดใช้ Bonjour, แนะนำสำหรับ gateway ที่เปิดเผย): ละเว้นฟิลด์ละเอียดอ่อนจาก mDNS broadcasts:

    json5
    {  discovery: {    mdns: { mode: "minimal" },  },}
  3. โหมดปิด mDNS หากคุณต้องการเปิดใช้ Plugin ไว้แต่ระงับการค้นพบอุปกรณ์ในเครือข่ายท้องถิ่น:

    json5
    {  discovery: {    mdns: { mode: "off" },  },}
  4. โหมด full (opt-in): รวม cliPath + sshPort ในระเบียน TXT:

    json5
    {  discovery: {    mdns: { mode: "full" },  },}
  5. ตัวแปรสภาพแวดล้อม (ทางเลือก): ตั้งค่า OPENCLAW_DISABLE_BONJOUR=1 เพื่อปิด mDNS โดยไม่เปลี่ยน config

เมื่อเปิดใช้ Bonjour ในโหมด minimal Gateway จะ broadcast ข้อมูลเพียงพอสำหรับการค้นพบอุปกรณ์ (role, gatewayPort, transport) แต่ละเว้น cliPath และ sshPort แอปที่ต้องการข้อมูลเส้นทาง CLI สามารถดึงข้อมูลผ่านการเชื่อมต่อ WebSocket ที่ผ่านการยืนยันตัวตนแทนได้

ล็อกดาวน์ Gateway WebSocket (การยืนยันตัวตนภายในเครื่อง)

Gateway auth เป็น ข้อบังคับตามค่าเริ่มต้น หากไม่ได้กำหนด gateway auth path ที่ถูกต้อง Gateway จะปฏิเสธการเชื่อมต่อ WebSocket (fail-closed)

Onboarding จะสร้าง token ตามค่าเริ่มต้น (แม้สำหรับ loopback) ดังนั้น client ภายในเครื่องต้องยืนยันตัวตน

ตั้งค่า token เพื่อให้ client WS ทั้งหมด ต้องยืนยันตัวตน:

json5
{  gateway: {    auth: { mode: "token", token: "your-token" },  },}

Doctor สามารถสร้างให้คุณได้: openclaw doctor --generate-gateway-token

ตัวเลือกเพิ่มเติม: pin TLS ระยะไกลด้วย gateway.remote.tlsFingerprint เมื่อใช้ wss:// Plaintext ws:// ยอมรับสำหรับ loopback, literal IP ส่วนตัว, .local และ URL gateway ของ Tailnet *.ts.net สำหรับชื่อ private-DNS ที่เชื่อถือได้อื่น ๆ ให้ตั้งค่า OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 บน process ของ client เป็น break-glass สิ่งนี้ตั้งใจให้เป็นเฉพาะสภาพแวดล้อมของ process เท่านั้น ไม่ใช่คีย์ config openclaw.json การจับคู่มือถือและเส้นทาง gateway แบบ manual หรือ scanned ของ Android เข้มงวดกว่า: cleartext ยอมรับสำหรับ loopback แต่ private-LAN, link-local, .local และ ชื่อโฮสต์ที่ไม่มีจุดต้องใช้ TLS เว้นแต่คุณจะ opt in อย่างชัดเจนเข้าสู่เส้นทาง cleartext ของเครือข่ายส่วนตัวที่เชื่อถือได้

การจับคู่อุปกรณ์ภายในเครื่อง:

  • การจับคู่อุปกรณ์ได้รับการอนุมัติอัตโนมัติสำหรับการเชื่อมต่อ local loopback โดยตรง เพื่อให้ client บนโฮสต์เดียวกันลื่นไหล
  • OpenClaw ยังมีเส้นทาง self-connect แบบ backend/container-local ที่จำกัดสำหรับ helper flows ที่ใช้ shared-secret ที่เชื่อถือได้
  • การเชื่อมต่อ Tailnet และ LAN รวมถึง tailnet binds บนโฮสต์เดียวกัน จะถือว่าเป็น remote สำหรับการจับคู่และยังต้องได้รับการอนุมัติ
  • หลักฐาน forwarded-header บนคำขอ loopback จะตัดสิทธิ์ความเป็น loopback ในท้องถิ่น การอนุมัติอัตโนมัติแบบ metadata-upgrade ถูกจำกัดขอบเขตอย่างแคบ ดู การจับคู่ Gateway สำหรับกฎทั้งสองข้อ

โหมดการยืนยันตัวตน:

  • gateway.auth.mode: "token": bearer token ที่ใช้ร่วมกัน (แนะนำสำหรับการตั้งค่าส่วนใหญ่)
  • gateway.auth.mode: "password": การยืนยันตัวตนด้วยรหัสผ่าน (แนะนำให้ตั้งผ่าน env: OPENCLAW_GATEWAY_PASSWORD)
  • gateway.auth.mode: "trusted-proxy": เชื่อถือ reverse proxy ที่รับรู้ตัวตนให้ยืนยันตัวตนผู้ใช้และส่งตัวตนผ่าน header (ดู การยืนยันตัวตนผ่านพร็อกซีที่เชื่อถือได้)

รายการตรวจสอบการ rotation (token/password):

  1. สร้าง/ตั้งค่า secret ใหม่ (gateway.auth.token หรือ OPENCLAW_GATEWAY_PASSWORD)
  2. รีสตาร์ท Gateway (หรือรีสตาร์ทแอป macOS หากแอปนั้น supervise Gateway)
  3. อัปเดต client ระยะไกลใด ๆ (gateway.remote.token / .password บนเครื่องที่เรียกเข้า Gateway)
  4. ตรวจสอบว่าคุณไม่สามารถเชื่อมต่อด้วย credential เดิมได้อีกต่อไป

Header ตัวตนของ Tailscale Serve

เมื่อ gateway.auth.allowTailscale เป็น true (ค่าเริ่มต้นสำหรับ Serve) OpenClaw จะยอมรับ header ตัวตนของ Tailscale Serve (tailscale-user-login) สำหรับการยืนยันตัวตน Control UI/WebSocket OpenClaw ตรวจสอบตัวตนโดย resolve ที่อยู่ x-forwarded-for ผ่าน Tailscale daemon ภายในเครื่อง (tailscale whois) และจับคู่กับ header สิ่งนี้จะ trigger เฉพาะสำหรับคำขอที่เข้าถึง loopback และมี x-forwarded-for, x-forwarded-proto และ x-forwarded-host ตามที่ Tailscale inject เข้ามา สำหรับเส้นทางตรวจสอบตัวตนแบบ async นี้ ความพยายามที่ล้มเหลวสำหรับ {scope, ip} เดียวกันจะถูก serialize ก่อนที่ limiter จะบันทึกความล้มเหลว ดังนั้นการ retry ที่ผิดพร้อมกัน จาก client Serve เดียวกันจึงสามารถ lock out ความพยายามครั้งที่สองได้ทันที แทนที่จะ race ผ่านไปเป็น mismatch ธรรมดาสองครั้ง endpoint HTTP API (เช่น /v1/*, /tools/invoke และ /api/channels/*) ไม่ ใช้การยืนยันตัวตนผ่าน header ตัวตนของ Tailscale แต่ยังคงทำตามโหมด HTTP auth ที่กำหนดไว้ของ gateway

หมายเหตุขอบเขตสำคัญ:

  • การยืนยันตัวตน HTTP bearer ของ Gateway มีผลเป็นการเข้าถึงระดับ operator แบบทั้งหมดหรือไม่มีเลย
  • ให้ถือว่า credential ที่สามารถเรียก /v1/chat/completions, /v1/responses, route ของ Plugin เช่น /api/v1/admin/rpc หรือ /api/channels/* เป็น secret ของ operator ที่มีสิทธิ์เต็มสำหรับ gateway นั้น
  • บนพื้นผิว HTTP ที่เข้ากันได้กับ OpenAI การยืนยันตัวตน bearer ด้วย shared-secret จะคืนค่า scope operator เริ่มต้นแบบเต็ม (operator.admin, operator.approvals, operator.pairing, operator.read, operator.talk.secrets, operator.write) และ owner semantics สำหรับ agent turns; ค่า x-openclaw-scopes ที่แคบกว่าไม่ลดสิทธิ์ของเส้นทาง shared-secret นั้น
  • semantics ของ scope ต่อคำขอบน HTTP ใช้เฉพาะเมื่อคำขอมาจากโหมดที่มีตัวตน เช่น trusted proxy auth หรือจาก private ingress แบบ no-auth ที่ระบุไว้อย่างชัดเจน
  • ในโหมดที่มีตัวตนเหล่านั้น การละเว้น x-openclaw-scopes จะ fallback ไปยังชุด scope operator เริ่มต้นตามปกติ; ส่ง header อย่างชัดเจนเมื่อคุณต้องการชุด scope ที่แคบกว่า header ระดับ owner ที่เข้ากันได้กับ OpenAI เช่น x-openclaw-model ต้องใช้ operator.admin เมื่อ scope ถูกจำกัดให้แคบลง
  • /tools/invoke และ endpoint ประวัติ HTTP session ทำตามกฎ shared-secret เดียวกัน: token/password bearer auth จะถูกถือเป็นการเข้าถึง operator แบบเต็มที่นั่นด้วย ขณะที่โหมดที่มีตัวตนยังคงเคารพ scope ที่ประกาศไว้
  • อย่าแชร์ credential เหล่านี้กับ caller ที่ไม่น่าเชื่อถือ; แนะนำให้ใช้ gateway แยกตามขอบเขตความเชื่อถือ

สมมติฐานความเชื่อถือ: การยืนยันตัวตน Serve แบบไม่มี token ถือว่าโฮสต์ gateway เชื่อถือได้ อย่าถือว่าสิ่งนี้เป็นการป้องกัน process ที่เป็นอันตรายบนโฮสต์เดียวกัน หากโค้ดภายในเครื่องที่ไม่น่าเชื่อถือ อาจรันบนโฮสต์ gateway ให้ปิด gateway.auth.allowTailscale และบังคับใช้การยืนยันตัวตนด้วย shared-secret อย่างชัดเจนด้วย gateway.auth.mode: "token" หรือ "password"

กฎความปลอดภัย: อย่าส่งต่อ header เหล่านี้จาก reverse proxy ของคุณเอง หาก คุณ terminate TLS หรือ proxy ด้านหน้า gateway ให้ปิด gateway.auth.allowTailscale และใช้การยืนยันตัวตนด้วย shared-secret (gateway.auth.mode: "token" หรือ "password") หรือ การยืนยันตัวตนผ่านพร็อกซีที่เชื่อถือได้ แทน

พร็อกซีที่เชื่อถือได้:

  • หากคุณ terminate TLS ด้านหน้า Gateway ให้ตั้งค่า gateway.trustedProxies เป็น IP ของ proxy ของคุณ
  • OpenClaw จะเชื่อถือ x-forwarded-for (หรือ x-real-ip) จาก IP เหล่านั้นเพื่อกำหนด IP ของ client สำหรับการตรวจสอบการจับคู่ภายในเครื่องและการตรวจสอบ HTTP auth/local
  • ตรวจสอบให้แน่ใจว่า proxy ของคุณ เขียนทับ x-forwarded-for และบล็อกการเข้าถึงโดยตรงไปยังพอร์ต Gateway

ดู Tailscale และ ภาพรวมเว็บ

การควบคุมเบราว์เซอร์ผ่านโฮสต์ Node (แนะนำ)

หาก Gateway ของคุณอยู่ระยะไกลแต่เบราว์เซอร์รันบนอีกเครื่องหนึ่ง ให้รัน โฮสต์ Node บนเครื่องเบราว์เซอร์และให้ Gateway proxy การทำงานของเบราว์เซอร์ (ดู เครื่องมือเบราว์เซอร์) ให้ถือการจับคู่ Node เหมือนการเข้าถึง admin

รูปแบบที่แนะนำ:

  • ให้ Gateway และโฮสต์ Node อยู่บน tailnet เดียวกัน (Tailscale)
  • จับคู่ Node อย่างตั้งใจ; ปิดการ route proxy ของเบราว์เซอร์หากคุณไม่ต้องการ

หลีกเลี่ยง:

  • การเปิดเผยพอร์ต relay/control ผ่าน LAN หรืออินเทอร์เน็ตสาธารณะ
  • Tailscale Funnel สำหรับ endpoint ควบคุมเบราว์เซอร์ (การเปิดเผยต่อสาธารณะ)

Secret บนดิสก์

ให้ถือว่าสิ่งใดก็ตามภายใต้ ~/.openclaw/ (หรือ $OPENCLAW_STATE_DIR/) อาจมี secret หรือข้อมูลส่วนตัว:

  • openclaw.json: การกำหนดค่าอาจมีโทเค็น (gateway, remote gateway), การตั้งค่าผู้ให้บริการ และรายการอนุญาต.
  • credentials/**: ข้อมูลประจำตัวของช่องทาง (ตัวอย่าง: ข้อมูลประจำตัว WhatsApp), รายการอนุญาตการจับคู่, การนำเข้า OAuth แบบเดิม.
  • agents/<agentId>/agent/auth-profiles.json: คีย์ API, โปรไฟล์โทเค็น, โทเค็น OAuth และ keyRef/tokenRef แบบไม่บังคับ.
  • agents/<agentId>/agent/codex-home/**: บัญชี app-server ของ Codex ต่อเอเจนต์, การกำหนดค่า, skills, plugins, สถานะเธรดเนทีฟ และการวินิจฉัย (ค่าเริ่มต้น).
  • $CODEX_HOME/** หรือ ~/.codex/**: เมื่อ Codex plugin ใช้ appServer.homeScope: "user" อย่างชัดเจน Gateway จะสามารถอ่านและอัปเดตบัญชี Codex แบบเนทีฟ, การกำหนดค่า, plugins และเธรดได้ ให้ถือว่านี่เป็นสิทธิ์เข้าถึงของเจ้าของที่มีสิทธิ์สูง; โหมดนี้เป็น local-stdio-only และการจัดการเธรดเนทีฟเป็นของเจ้าของเท่านั้น.
  • secrets.json (ไม่บังคับ): เพย์โหลดลับที่อิงไฟล์ซึ่งใช้โดยผู้ให้บริการ SecretRef แบบ file (secrets.providers).
  • agents/<agentId>/agent/auth.json: ไฟล์ความเข้ากันได้แบบเดิม รายการ api_key แบบคงที่จะถูกลบออกเมื่อพบ.
  • agents/<agentId>/sessions/**: ทรานสคริปต์เซสชัน (*.jsonl) + เมทาดาทาการกำหนดเส้นทาง (sessions.json) ที่อาจมีข้อความส่วนตัวและเอาต์พุตของเครื่องมือ.
  • แพ็กเกจ plugin ที่บันเดิลมา: plugins ที่ติดตั้งแล้ว (รวมถึง node_modules/ ของแพ็กเกจเหล่านั้น).
  • sandboxes/**: เวิร์กสเปซ sandbox ของเครื่องมือ; อาจสะสมสำเนาของไฟล์ที่คุณอ่าน/เขียนภายใน sandbox.

เคล็ดลับการเพิ่มความปลอดภัย:

  • จำกัดสิทธิ์ให้เข้มงวด (700 สำหรับไดเรกทอรี, 600 สำหรับไฟล์).
  • ใช้การเข้ารหัสดิสก์ทั้งลูกบนโฮสต์ gateway.
  • แนะนำให้ใช้บัญชีผู้ใช้ OS แยกต่างหากสำหรับ Gateway หากโฮสต์ถูกใช้ร่วมกัน.

ไฟล์ .env ของเวิร์กสเปซ

OpenClaw โหลดไฟล์ .env ภายในเวิร์กสเปซสำหรับเอเจนต์และเครื่องมือ แต่จะไม่ยอมให้ไฟล์เหล่านั้นเขียนทับการควบคุมรันไทม์ของ gateway อย่างเงียบ ๆ.

  • ตัวแปรสภาพแวดล้อมสำหรับข้อมูลประจำตัวผู้ให้บริการจะถูกบล็อกจากไฟล์ .env ของเวิร์กสเปซที่ไม่น่าเชื่อถือ ตัวอย่างรวมถึง GEMINI_API_KEY, GOOGLE_API_KEY, XAI_API_KEY, MISTRAL_API_KEY, GROQ_API_KEY, DEEPSEEK_API_KEY, PERPLEXITY_API_KEY, BRAVE_API_KEY, TAVILY_API_KEY, EXA_API_KEY, FIRECRAWL_API_KEY และคีย์ auth ของผู้ให้บริการที่ประกาศโดย plugins ที่น่าเชื่อถือซึ่งติดตั้งไว้ ให้วางข้อมูลประจำตัวผู้ให้บริการไว้ในสภาพแวดล้อมของกระบวนการ Gateway, ~/.openclaw/.env ($OPENCLAW_STATE_DIR/.env), บล็อก env ของการกำหนดค่า หรือการนำเข้า login-shell แบบไม่บังคับ.
  • คีย์ใดก็ตามที่ขึ้นต้นด้วย OPENCLAW_* จะถูกบล็อกจากไฟล์ .env ของเวิร์กสเปซที่ไม่น่าเชื่อถือ.
  • การตั้งค่าเอนด์พอยต์ของช่องทางสำหรับ Matrix, Mattermost, IRC และ Synology Chat จะถูกบล็อกจากการเขียนทับโดย .env ของเวิร์กสเปซเช่นกัน ดังนั้นเวิร์กสเปซที่โคลนมาจะไม่สามารถเปลี่ยนเส้นทางทราฟฟิกของตัวเชื่อมต่อที่บันเดิลผ่านการกำหนดค่าเอนด์พอยต์ภายในเครื่องได้ คีย์ env ของเอนด์พอยต์ (เช่น MATRIX_HOMESERVER, MATTERMOST_URL, IRC_HOST, SYNOLOGY_CHAT_INCOMING_URL) ต้องมาจากสภาพแวดล้อมของกระบวนการ gateway หรือ env.shellEnv ไม่ใช่จาก .env ที่โหลดจากเวิร์กสเปซ.
  • การบล็อกเป็นแบบ fail-closed: ตัวแปรควบคุมรันไทม์ใหม่ที่เพิ่มในรุ่นอนาคตจะไม่สามารถสืบทอดจาก .env ที่ถูกเช็กอินหรือผู้โจมตีจัดหาให้ได้; คีย์จะถูกละเว้นและ gateway จะคงค่าของตนเองไว้.
  • ตัวแปรสภาพแวดล้อมของกระบวนการ/OS ที่น่าเชื่อถือ, dotenv รันไทม์ส่วนกลาง, env ของการกำหนดค่า และการนำเข้า login-shell ที่เปิดใช้งานยังคงมีผล - สิ่งนี้จำกัดเฉพาะการโหลดไฟล์ .env ของเวิร์กสเปซเท่านั้น.

เหตุผล: ไฟล์ .env ของเวิร์กสเปซมักอยู่ถัดจากโค้ดเอเจนต์, ถูกคอมมิตโดยไม่ตั้งใจ หรือถูกเขียนโดยเครื่องมือ การบล็อกข้อมูลประจำตัวผู้ให้บริการป้องกันไม่ให้เวิร์กสเปซที่โคลนมาแทนที่บัญชีผู้ให้บริการด้วยบัญชีที่ผู้โจมตีควบคุม การบล็อกคำนำหน้า OPENCLAW_* ทั้งหมดหมายความว่าการเพิ่มแฟล็ก OPENCLAW_* ใหม่ภายหลังจะไม่มีทางถดถอยไปเป็นการสืบทอดจากสถานะเวิร์กสเปซอย่างเงียบ ๆ.

Logs และทรานสคริปต์ (การปกปิดและการเก็บรักษา)

Logs และทรานสคริปต์อาจรั่วไหลข้อมูลอ่อนไหวได้ แม้การควบคุมการเข้าถึงจะถูกต้อง:

  • Logs ของ Gateway อาจรวมสรุปเครื่องมือ, ข้อผิดพลาด และ URL.
  • ทรานสคริปต์เซสชันอาจรวมความลับที่วางไว้, เนื้อหาไฟล์, เอาต์พุตคำสั่ง และลิงก์.

คำแนะนำ:

  • เปิดการปกปิด log และทรานสคริปต์ไว้ (logging.redactSensitive: "tools"; ค่าเริ่มต้น).
  • เพิ่มรูปแบบกำหนดเองสำหรับสภาพแวดล้อมของคุณผ่าน logging.redactPatterns (โทเค็น, ชื่อโฮสต์, URL ภายใน).
  • เมื่อแชร์การวินิจฉัย แนะนำให้ใช้ openclaw status --all (วางได้, ความลับถูกปกปิด) แทน logs ดิบ.
  • ลบทิ้งทรานสคริปต์เซสชันและไฟล์ log เก่าหากคุณไม่ต้องการเก็บไว้นาน.

รายละเอียด: การบันทึก

ข้อความส่วนตัว: จับคู่เป็นค่าเริ่มต้น

json5
{  channels: { whatsapp: { dmPolicy: "pairing" } },}

กลุ่ม: ต้องมีการกล่าวถึงทุกที่

json
{  "channels": {    "whatsapp": {      "groups": {        "*": { "requireMention": true }      }    }  },  "agents": {    "list": [      {        "id": "main",        "groupChat": { "mentionPatterns": ["@openclaw", "@mybot"] }      }    ]  }}

ในแชตกลุ่ม ให้ตอบเฉพาะเมื่อถูกกล่าวถึงอย่างชัดเจน.

หมายเลขแยกต่างหาก (WhatsApp, Signal, Telegram)

สำหรับช่องทางที่อิงหมายเลขโทรศัพท์ ให้พิจารณารัน AI ของคุณบนหมายเลขโทรศัพท์แยกจากหมายเลขส่วนตัว:

  • หมายเลขส่วนตัว: การสนทนาของคุณยังคงเป็นส่วนตัว
  • หมายเลขบอต: AI จัดการสิ่งเหล่านี้ พร้อมขอบเขตที่เหมาะสม

โหมดอ่านอย่างเดียว (ผ่าน sandbox และเครื่องมือ)

คุณสามารถสร้างโปรไฟล์อ่านอย่างเดียวได้โดยผสาน:

  • agents.defaults.sandbox.workspaceAccess: "ro" (หรือ "none" หากไม่ให้เข้าถึงเวิร์กสเปซ)
  • รายการอนุญาต/ปฏิเสธเครื่องมือที่บล็อก write, edit, apply_patch, exec, process เป็นต้น.

ตัวเลือกเพิ่มความปลอดภัยเพิ่มเติม:

  • tools.exec.applyPatch.workspaceOnly: true (ค่าเริ่มต้น): ทำให้แน่ใจว่า apply_patch ไม่สามารถเขียน/ลบภายนอกไดเรกทอรีเวิร์กสเปซ แม้เมื่อปิด sandboxing ตั้งเป็น false เฉพาะเมื่อคุณตั้งใจให้ apply_patch แตะไฟล์นอกเวิร์กสเปซ.
  • tools.fs.workspaceOnly: true (ไม่บังคับ): จำกัดเส้นทาง read/write/edit/apply_patch และเส้นทางโหลดรูปภาพพรอมป์เนทีฟอัตโนมัติให้อยู่ภายในไดเรกทอรีเวิร์กสเปซ (มีประโยชน์หากวันนี้คุณอนุญาตเส้นทางแบบสัมบูรณ์และต้องการราวกันตกเดียว).
  • จำกัดรากระบบไฟล์ให้แคบ: หลีกเลี่ยงรากที่กว้าง เช่น ไดเรกทอรี home ของคุณสำหรับเวิร์กสเปซเอเจนต์/เวิร์กสเปซ sandbox รากที่กว้างอาจเปิดเผยไฟล์ภายในเครื่องที่อ่อนไหว (เช่น state/config ภายใต้ ~/.openclaw) ให้เครื่องมือระบบไฟล์.

baseline ที่ปลอดภัย (คัดลอก/วาง)

การกำหนดค่า "ค่าเริ่มต้นที่ปลอดภัย" หนึ่งชุดที่ทำให้ Gateway เป็นส่วนตัว, ต้องจับคู่ข้อความส่วนตัว และหลีกเลี่ยงบอตกลุ่มที่เปิดตลอดเวลา:

json5
{  gateway: {    mode: "local",    bind: "loopback",    port: 18789,    auth: { mode: "token", token: "your-long-random-token" },  },  channels: {    whatsapp: {      dmPolicy: "pairing",      groups: { "*": { requireMention: true } },    },  },}

หากคุณต้องการให้การเรียกใช้เครื่องมือ "ปลอดภัยกว่าเป็นค่าเริ่มต้น" ด้วย ให้เพิ่ม sandbox + ปฏิเสธเครื่องมืออันตรายสำหรับเอเจนต์ที่ไม่ใช่เจ้าของ (ตัวอย่างด้านล่างใน "โปรไฟล์การเข้าถึงต่อเอเจนต์").

baseline ในตัวสำหรับเทิร์นเอเจนต์ที่ขับเคลื่อนด้วยแชต: ผู้ส่งที่ไม่ใช่เจ้าของไม่สามารถใช้เครื่องมือ cron หรือ gateway.

Sandboxing (แนะนำ)

เอกสารเฉพาะ: Sandboxing

สองแนวทางที่เสริมกัน:

  • รัน Gateway ทั้งหมดใน Docker (ขอบเขตคอนเทนเนอร์): Docker
  • Tool sandbox (agents.defaults.sandbox, host gateway + เครื่องมือที่แยกด้วย sandbox; Docker เป็นแบ็กเอนด์ค่าเริ่มต้น): Sandboxing

พิจารณาการเข้าถึงเวิร์กสเปซเอเจนต์ภายใน sandbox ด้วย:

  • agents.defaults.sandbox.workspaceAccess: "none" (ค่าเริ่มต้น) ทำให้เวิร์กสเปซเอเจนต์ถูกห้ามเข้าถึง; เครื่องมือรันกับเวิร์กสเปซ sandbox ภายใต้ ~/.openclaw/sandboxes
  • agents.defaults.sandbox.workspaceAccess: "ro" เมานต์เวิร์กสเปซเอเจนต์แบบอ่านอย่างเดียวที่ /agent (ปิดใช้งาน write/edit/apply_patch)
  • agents.defaults.sandbox.workspaceAccess: "rw" เมานต์เวิร์กสเปซเอเจนต์แบบอ่าน/เขียนที่ /workspace
  • sandbox.docker.binds เพิ่มเติมจะถูกตรวจสอบกับเส้นทางต้นทางที่ทำให้เป็นมาตรฐานและเป็นแบบ canonical แล้ว เทคนิค parent-symlink และ alias ของ home แบบ canonical ยังคง fail closed หาก resolve เข้าไปในรากที่ถูกบล็อก เช่น /etc, /var/run หรือไดเรกทอรีข้อมูลประจำตัวภายใต้ home ของ OS.

ราวกันตกการมอบหมายเอเจนต์ย่อย

หากคุณอนุญาตเครื่องมือเซสชัน ให้ถือว่าการรันเอเจนต์ย่อยที่ถูกมอบหมายเป็นการตัดสินใจด้านขอบเขตอีกแบบหนึ่ง:

  • ปฏิเสธ sessions_spawn เว้นแต่ว่าเอเจนต์จำเป็นต้องมอบหมายจริง ๆ.
  • จำกัด agents.defaults.subagents.allowAgents และการเขียนทับ agents.list[].subagents.allowAgents ต่อเอเจนต์ใด ๆ ให้เป็นเอเจนต์เป้าหมายที่ทราบว่าปลอดภัย.
  • สำหรับเวิร์กโฟลว์ใด ๆ ที่ต้องคงอยู่ใน sandbox ให้เรียก sessions_spawn ด้วย sandbox: "require" (ค่าเริ่มต้นคือ inherit).
  • sandbox: "require" จะล้มเหลวทันทีเมื่อรันไทม์ลูกเป้าหมายไม่ได้อยู่ใน sandbox.

ความเสี่ยงของการควบคุมเบราว์เซอร์

การเปิดใช้การควบคุมเบราว์เซอร์ทำให้โมเดลสามารถควบคุมเบราว์เซอร์จริงได้. หากโปรไฟล์เบราว์เซอร์นั้นมีเซสชันที่ล็อกอินอยู่แล้ว โมเดลสามารถ เข้าถึงบัญชีและข้อมูลเหล่านั้นได้ ให้ถือว่าโปรไฟล์เบราว์เซอร์เป็น สถานะอ่อนไหว:

  • แนะนำให้ใช้โปรไฟล์เฉพาะสำหรับเอเจนต์ (โปรไฟล์ openclaw ค่าเริ่มต้น).
  • หลีกเลี่ยงการชี้เอเจนต์ไปยังโปรไฟล์ส่วนตัวที่คุณใช้ประจำทุกวัน.
  • ปิดการควบคุมเบราว์เซอร์ของโฮสต์สำหรับเอเจนต์ใน sandbox เว้นแต่ว่าคุณไว้วางใจ.
  • API ควบคุมเบราว์เซอร์แบบ standalone loopback ยอมรับเฉพาะ auth ด้วยความลับร่วม (gateway token bearer auth หรือรหัสผ่าน gateway) เท่านั้น ไม่ใช้ trusted-proxy หรือ header ตัวตน Tailscale Serve.
  • ถือว่าการดาวน์โหลดของเบราว์เซอร์เป็นอินพุตที่ไม่น่าเชื่อถือ; แนะนำให้ใช้ไดเรกทอรีดาวน์โหลดที่แยกไว้.
  • ปิดการซิงค์เบราว์เซอร์/ตัวจัดการรหัสผ่านในโปรไฟล์เอเจนต์หากทำได้ (ลด blast radius).
  • สำหรับ remote gateways ให้ถือว่า "การควบคุมเบราว์เซอร์" เทียบเท่ากับ "สิทธิ์เข้าถึงของผู้ปฏิบัติการ" ต่อทุกสิ่งที่โปรไฟล์นั้นเข้าถึงได้.
  • ให้ Gateway และโฮสต์ node อยู่เฉพาะใน tailnet; หลีกเลี่ยงการเปิดพอร์ตควบคุมเบราว์เซอร์ให้ LAN หรืออินเทอร์เน็ตสาธารณะ.
  • ปิดการกำหนดเส้นทางพร็อกซีของเบราว์เซอร์เมื่อไม่ต้องใช้ (gateway.nodes.browser.mode="off").
  • โหมด Chrome MCP existing-session ไม่ได้ "ปลอดภัยกว่า"; มันสามารถทำหน้าที่เป็นคุณในทุกสิ่งที่โปรไฟล์ Chrome บนโฮสต์นั้นเข้าถึงได้.

นโยบาย SSRF ของเบราว์เซอร์ (เข้มงวดเป็นค่าเริ่มต้น)

นโยบายการนำทางเบราว์เซอร์ของ OpenClaw เข้มงวดเป็นค่าเริ่มต้น: ปลายทางส่วนตัว/ภายในจะยังคงถูกบล็อก เว้นแต่คุณจะเลือกเปิดใช้อย่างชัดเจน.

  • ค่าเริ่มต้น: browser.ssrfPolicy.dangerouslyAllowPrivateNetwork ไม่ได้ตั้งค่า ดังนั้นการนำทางเบราว์เซอร์จะยังคงบล็อกปลายทางส่วนตัว/ภายใน/การใช้งานพิเศษ.
  • alias เดิม: browser.ssrfPolicy.allowPrivateNetwork ยังคงยอมรับเพื่อความเข้ากันได้.
  • โหมดเลือกเปิด: ตั้ง browser.ssrfPolicy.dangerouslyAllowPrivateNetwork: true เพื่ออนุญาตปลายทางส่วนตัว/ภายใน/การใช้งานพิเศษ.
  • ในโหมดเข้มงวด ให้ใช้ hostnameAllowlist (รูปแบบเช่น *.example.com) และ allowedHostnames (ข้อยกเว้นโฮสต์แบบตรงตัว รวมถึงชื่อที่ถูกบล็อก เช่น localhost) สำหรับข้อยกเว้นที่ชัดเจน.
  • การนำทางจะถูกตรวจสอบก่อนคำขอ และตรวจซ้ำแบบ best-effort บน URL http(s) สุดท้ายหลังการนำทาง เพื่อลดการ pivot ผ่าน redirect.

ตัวอย่างนโยบายเข้มงวด:

json5
{  browser: {    ssrfPolicy: {      dangerouslyAllowPrivateNetwork: false,      hostnameAllowlist: ["*.example.com", "example.com"],      allowedHostnames: ["localhost"],    },  },}

โปรไฟล์การเข้าถึงต่อเอเจนต์ (หลายเอเจนต์)

ด้วยการกำหนดเส้นทางหลายเอเจนต์ เอเจนต์แต่ละตัวสามารถมี sandbox + นโยบายเครื่องมือของตนเอง: ใช้สิ่งนี้เพื่อให้ สิทธิ์เต็ม, อ่านอย่างเดียว หรือ ไม่มีสิทธิ์เข้าถึง ต่อเอเจนต์. ดู Sandbox และเครื่องมือแบบหลายเอเจนต์ สำหรับรายละเอียดเต็ม และกฎลำดับความสำคัญ.

กรณีใช้งานทั่วไป:

  • เอเจนต์ส่วนตัว: สิทธิ์เต็ม, ไม่มี sandbox
  • เอเจนต์ครอบครัว/งาน: อยู่ใน sandbox + เครื่องมืออ่านอย่างเดียว
  • เอเจนต์สาธารณะ: อยู่ใน sandbox + ไม่มีเครื่องมือระบบไฟล์/shell

ตัวอย่าง: สิทธิ์เต็ม (ไม่มี sandbox)

json5
{  agents: {    list: [      {        id: "personal",        workspace: "~/.openclaw/workspace-personal",        sandbox: { mode: "off" },      },    ],  },}

ตัวอย่าง: เครื่องมือแบบอ่านอย่างเดียว + พื้นที่ทำงานแบบอ่านอย่างเดียว

json5
{  agents: {    list: [      {        id: "family",        workspace: "~/.openclaw/workspace-family",        sandbox: {          mode: "all",          scope: "agent",          workspaceAccess: "ro",        },        tools: {          allow: ["read"],          deny: ["write", "edit", "apply_patch", "exec", "process", "browser"],        },      },    ],  },}

ตัวอย่าง: ไม่มีสิทธิ์เข้าถึงระบบไฟล์/เชลล์ (อนุญาตการส่งข้อความผ่านผู้ให้บริการ)

json5
{  agents: {    list: [      {        id: "public",        workspace: "~/.openclaw/workspace-public",        sandbox: {          mode: "all",          scope: "agent",          workspaceAccess: "none",        },        // Session tools can reveal sensitive data from transcripts. By default OpenClaw limits these tools        // to the current session + spawned subagent sessions, but you can clamp further if needed.        // See `tools.sessions.visibility` in the configuration reference.        tools: {          sessions: { visibility: "tree" }, // self | tree | agent | all          allow: [            "sessions_list",            "sessions_history",            "sessions_send",            "sessions_spawn",            "session_status",            "whatsapp",            "telegram",            "slack",            "discord",          ],          deny: [            "read",            "write",            "edit",            "apply_patch",            "exec",            "process",            "browser",            "canvas",            "nodes",            "cron",            "gateway",            "image",          ],        },      },    ],  },}

การตอบสนองต่อเหตุการณ์

หาก AI ของคุณทำสิ่งที่ไม่เหมาะสม:

ควบคุมสถานการณ์

  1. หยุดมัน: หยุดแอป macOS (หากแอปนั้นควบคุม Gateway) หรือยุติกระบวนการ openclaw gateway ของคุณ
  2. ปิดการเปิดเผย: ตั้งค่า gateway.bind: "loopback" (หรือปิดใช้งาน Tailscale Funnel/Serve) จนกว่าคุณจะเข้าใจว่าเกิดอะไรขึ้น
  3. ระงับการเข้าถึง: เปลี่ยน DM/กลุ่มที่มีความเสี่ยงเป็น dmPolicy: "disabled" / กำหนดให้ต้องมีการกล่าวถึง และลบรายการอนุญาตทั้งหมด "*" หากคุณเคยตั้งไว้

หมุนเวียนข้อมูลลับ (ให้ถือว่าถูกบุกรุกหากข้อมูลลับรั่วไหล)

  1. หมุนเวียนการยืนยันตัวตนของ Gateway (gateway.auth.token / OPENCLAW_GATEWAY_PASSWORD) แล้วรีสตาร์ท
  2. หมุนเวียนข้อมูลลับของไคลเอนต์ระยะไกล (gateway.remote.token / .password) บนเครื่องใดก็ตามที่สามารถเรียก Gateway ได้
  3. หมุนเวียนข้อมูลรับรองของผู้ให้บริการ/API (ข้อมูลรับรอง WhatsApp, โทเค็น Slack/Discord, คีย์โมเดล/API ใน auth-profiles.json และค่าข้อมูลลับที่เข้ารหัสเมื่อใช้งาน)

ตรวจสอบ

  1. ตรวจสอบบันทึกของ Gateway: /tmp/openclaw/openclaw-YYYY-MM-DD.log (หรือ logging.file)
  2. ตรวจทานทรานสคริปต์ที่เกี่ยวข้อง: ~/.openclaw/agents/<agentId>/sessions/*.jsonl
  3. ตรวจทานการเปลี่ยนแปลงคอนฟิกล่าสุด (สิ่งใดก็ตามที่อาจขยายการเข้าถึง: gateway.bind, gateway.auth, นโยบาย DM/กลุ่ม, tools.elevated, การเปลี่ยนแปลง Plugin)
  4. เรียกใช้ openclaw security audit --deep อีกครั้งและยืนยันว่าผลการตรวจพบระดับวิกฤตได้รับการแก้ไขแล้ว

รวบรวมข้อมูลสำหรับรายงาน

  • เวลา, OS ของโฮสต์ Gateway + เวอร์ชัน OpenClaw
  • ทรานสคริปต์ของเซสชัน + ส่วนท้ายบันทึกสั้น ๆ (หลังการแก้ไขข้อมูลลับ)
  • สิ่งที่ผู้โจมตีส่ง + สิ่งที่เอเจนต์ทำ
  • Gateway ถูกเปิดเผยเกินกว่า loopback หรือไม่ (LAN/Tailscale Funnel/Serve)

การสแกนข้อมูลลับ

CI เรียกใช้ hook detect-private-key ของ pre-commit กับรีโพซิทอรี หาก ล้มเหลว ให้ลบหรือหมุนเวียนวัสดุคีย์ที่ถูกคอมมิต แล้วทำซ้ำในเครื่อง:

bash
pre-commit run --all-files detect-private-key

การรายงานปัญหาความปลอดภัย

พบช่องโหว่ใน OpenClaw หรือไม่ โปรดรายงานอย่างรับผิดชอบ:

  1. อีเมล: security@openclaw.ai
  2. อย่าโพสต์ต่อสาธารณะจนกว่าจะได้รับการแก้ไข
  3. เราจะให้เครดิตคุณ (เว้นแต่คุณต้องการไม่เปิดเผยตัวตน)
Was this useful?
On this page

On this page