Claude Code ฟีเจอร์ "Don't Ask Again" รั่วไหล API Key สู่ GitHub: วิธีตรวจสอบและแก้ไข

การอนุมัติคำสั่งด้วยตัวเลือก "Don't Ask Again" (ไม่ต้องถามอีก) จะบันทึกคำสั่งนั้นเก็บไว้ทั้งบรรทัด รวมถึงรหัสผ่านด้วย นี่คือวิธีตรวจสอบที่ใช้คำสั่งเดียวสำหรับ repo ของคุณ ลำดับการเก็บกวาด และวิธีป้องกันไม่ให้คีย์ต่าง ๆ หลุดเข้าไปในการอนุมัติของเอเจนต์

Ahmed Waheed

Ahmed Waheed

12 November 2026

Claude Code ฟีเจอร์ "Don't Ask Again" รั่วไหล API Key สู่ GitHub: วิธีตรวจสอบและแก้ไข

Apidog สำหรับองค์กร

การติดตั้งแบบ On-Premises

SSO & RBAC

รองรับมาตรฐาน SOC 2

สำรวจ Apidog Enterprise

ปุ่ม “Don’t Ask Again” ของ Claude Code จะบันทึกคำสั่งที่คุณอนุมัติแบบเป๊ะ ๆ ลงในไฟล์ .claude/settings.local.json เป็นกฎ allow ถ้าคำสั่งนั้นมีรหัสผ่านหรือ API key อยู่ ความลับนั้นจะถูกเก็บอยู่ในโฟลเดอร์โปรเจกต์ของคุณแบบข้อความล้วน และถ้าไฟล์นี้ถูก commit ขึ้นไป มันก็จะกลายเป็นข้อมูลสาธารณะ บริษัทด้านความปลอดภัย Apiiro พบไฟล์ลักษณะนี้ถึง 1,122 ไฟล์บน GitHub สาธารณะที่มีความลับจริงรวมกัน 1,379 รายการ นี่คือวิธีตรวจสอบ repo ของคุณเองด้วยคำสั่งเดียว เคลียร์ความเสียหาย และป้องกันไม่ให้เกิดขึ้นอีก

เกิดอะไรขึ้น: ผลการค้นพบของ Apiiro ในตัวเลข

Apiiro ค้นหาไฟล์ .claude/settings.local.json ซึ่งเป็นไฟล์รายโปรเจกต์ที่ Claude Code เก็บการอนุมัติสิทธิ์ส่วนตัวของคุณ จาก GitHub สาธารณะ พบไฟล์ 104,185 ไฟล์ใน repo 103,617 แห่ง ในจำนวนนั้นมี 1,122 ไฟล์ที่มีความลับจริงอย่างน้อยหนึ่งรายการ รวมทั้งหมด 1,379 ความลับที่ไม่ซ้ำกัน ตามรายงานของ iTnews เกี่ยวกับงานวิจัยนี้

ประเภทความลับ จำนวน
รหัสผ่านฐานข้อมูล 379
Supabase service-role keys 122
การล็อกอิน SSH สู่เซิร์ฟเวอร์สาธารณะ 43
โทเคน GitHub, GitLab และ npm 42
AWS keys 23

เมื่อ Apiiro ขยายการค้นหาไปยึงเวอร์ชันเก่ากว่าของไฟล์ใน git, ไฟล์ที่แชร์ร่วมกัน .claude/settings.json และบันทึกการทำงานของ agent จำนวนความลับเพิ่มขึ้นเป็น 2,539 รายการใน repo 1,994 แห่ง Apiiro ไม่ได้ทดสอบว่า credential เหล่านั้นยังใช้งานได้อยู่หรือไม่ แต่มีองค์กรหนึ่งที่ได้รับแจ้งยืนยันว่า key หนึ่งยังใช้งานได้จริง

ตัวเลขของตัวสแกนคือส่วนที่น่ากังวลที่สุด จากไฟล์ 1,122 ไฟล์ที่มีความลับจริง TruffleHog ตรวจพบ 643 ไฟล์ และ gitleaks ตรวจพบ 564 ไฟล์ มี 215 ไฟล์ที่หลุดรอดจากทั้งสองตัว ดังนั้นการบอกว่า “เรารันเครื่องมือสแกนความลับอยู่” ไม่ใช่หลักฐานว่าคุณสะอาด

เรื่องนี้ติดอันดับหนึ่งบน Hacker News ด้วยคะแนน 582 คะแนน Boris Cherny ผู้ดูแล Claude Code ที่ Anthropic ตอบในเธรดนั้นว่า Claude Code ในอดีตไม่ได้ล้างความลับออกจากไฟล์ และทีมงานกำลังพิจารณาเรื่องนี้อยู่ อ่านงานวิจัยต้นฉบับของ Apiiro

ทำไม “Don’t Ask Again” ทำให้ความลับหลุดเข้าไปอยู่ในไฟล์

เมื่อ Claude Code ต้องการรันคำสั่ง Bash มันจะถามก่อนเสมอ หากคุณเลือก “Yes, and don’t ask again” Claude Code จะเขียนการอนุมัติถาวรลงใน .claude/settings.local.json เป็นกฎ allow ตามที่เอกสาร settings ของ Anthropic อธิบายไว้ กฎนี้จะบันทึกข้อความของคำสั่ง ถ้าคำสั่งเป็นแบบนี้:

psql "postgresql://admin:Sup3rS3cret@db.example.com:5432/prod" -c "select count(*) from users"

ไฟล์ settings ของคุณก็จะมีเนื้อหาประมาณนี้:

{
  "permissions": {
    "allow": [
      "Bash(psql \"postgresql://admin:Sup3rS3cret@db.example.com:5432/prod\" -c \"select count(*) from users\")"
    ]
  }
}

รหัสผ่านอยู่ในกฎเพราะมันอยู่ในคำสั่ง Claude Code บันทึกสิ่งที่คุณอนุมัติแบบคำต่อคำ

Diagram of how a Claude Code approval with an inline password flows into settings.local.json and then into a public GitHub repository

ทำไมมันจึงไปอยู่บน GitHub

Claude Code พยายามไม่ให้ไฟล์นี้เข้าสู่ git ครั้งแรกที่มันเขียน .claude/settings.local.json ใน repo ที่ยังไม่ได้ ignore ไฟล์นี้ มันจะเพิ่ม **/.claude/settings.local.json ลงในไฟล์ global git excludes ของคุณ แต่การป้องกันนี้มีช่องโหว่:

ตรวจสอบ repo ของคุณด้วยคำสั่งเดียว

เริ่มจาก repo ที่คุณอยู่ คำสั่งนี้บอกคุณว่าไฟล์ถูก track อยู่หรือไม่ และเคยถูก commit หรือเปล่า:

git ls-files | grep -E '(^|/)\.claude/settings(\.local)?\.json$'
git log --all --name-only --format= | grep -E '\.claude/settings(\.local)?\.json$' | sort -u

ถ้าบรรทัดแรกแสดงผลอะไรออกมา แปลว่าไฟล์อยู่ใน tree ปัจจุบันของคุณ ถ้าบรรทัดที่สองแสดงผลอะไรออกมา แปลว่ามันอยู่ในประวัติของคุณ แม้ว่าคุณจะลบมันไปแล้วก็ตาม

หากต้องการกวาดตรวจทุก repo ใต้โฟลเดอร์หนึ่งพร้อมกัน:

find ~/code -path '*/.claude/settings.local.json' -exec sh -c \
  'cd "$(dirname "$1")/.." && git ls-files --error-unmatch .claude/settings.local.json >/dev/null 2>&1 && echo "TRACKED: $PWD"' _ {} \;

สำหรับองค์กรบน GitHub คุณสามารถใช้ GitHub CLI ค้นหาโค้ดตามชื่อไฟล์ได้:

gh search code permissions --owner your-org --filename settings.local.json

แล้วตรวจเนื้อหาในไฟล์ที่พบ เพราะเครื่องมือสแกนพลาดไป 19% ของไฟล์ที่รั่วไหล คุณควรอ่านกฎต่าง ๆ ด้วยตัวเองแทนการเชื่อผลสแกนสีเขียว:

grep -nE 'Bash\(' .claude/settings.local.json | grep -iE 'pass|token|key|secret|://[^/]*:[^@]*@'

Connection string ที่มี user:password@, header Authorization: Bearer, -p ตามด้วยรหัสผ่านเป็นข้อความจริง หรือสิ่งใดที่ขึ้นต้นด้วย sk-, ghp_, AKIA หรือ eyJ คือ credential ทั้งสิ้น รัน gitleaks กับ repo เป็นขั้นตอนที่สอง ไม่ใช่ขั้นตอนเดียว

วิธีแก้ไขเมื่อไฟล์ settings รั่วไหล

ลำดับขั้นสำคัญมาก ต้องหมุนเปลี่ยน (rotate) credential ก่อน เพราะการลบไฟล์ไม่ช่วยอะไรกับสำเนาที่อยู่ใน fork, clone และ cache ไปแล้ว

  1. หมุนเปลี่ยน credential ทุกตัวที่ไฟล์นี้เคยเก็บ ตรวจประวัติทั้งหมดของไฟล์ด้วย git log -p --all -- .claude/settings.local.json จดทุกความลับที่พบ แล้ว revoke แต่ละตัวที่ผู้ให้บริการของมัน Apiiro ก็แนะนำให้ทำขั้นตอนนี้ก่อน
  2. ถอนการ track ไฟล์และ ignore มันในตัว repo เอง:
git rm --cached .claude/settings.local.json
echo '.claude/settings.local.json' >> .gitignore
git add .gitignore && git commit -m "Stop tracking Claude Code local settings"
git check-ignore -v .claude/settings.local.json

คำสั่งสุดท้ายควรแสดงบรรทัดใน .gitignore ที่ตรงกัน กฎใน repo จะปกป้องทุก clone

  1. ล้างประวัติถ้า repo เป็นสาธารณะหรือถูกแชร์กว้าง git-filter-repo ลบไฟล์ออกจากทุก commit:
git filter-repo --invert-paths --path .claude/settings.local.json
git push --force --all

ขั้นตอนนี้จะเขียนประวัติใหม่สำหรับทุกคน จึงควรเตือนทีมก่อน และมันไม่ไปถึง fork ด้วย จึงเป็นเพียงการเคลียร์ ไม่ใช่ตัวแทนของขั้นตอนที่ 1

  1. เคลียร์ไฟล์ในเครื่องด้วย เปิด .claude/settings.local.json ลบกฎใด ๆ ที่มีความลับเป็นข้อความจริง แล้วแทนที่ด้วย pattern (ดูหัวข้อถัดไป)
  2. เปิดใช้ push protection GitHub secret scanning push protection จะบล็อก push ที่มีรูปแบบความลับที่ระบบจดจำได้ มันไม่ได้จับทุกอย่าง ตามที่ไฟล์ 215 ไฟล์ที่หลุดรอดแสดงให้เห็น แต่มันหยุดรูปแบบโทเคนทั่วไปได้

ป้องกันไม่ให้เกิดขึ้นอีก

ทางแก้พูดง่าย ๆ ว่า: อย่าใส่ความลับเป็นข้อความจริงในคำสั่งที่ agent ของคุณรัน และอนุมัติเป็น pattern แทนคำสั่งเป๊ะ ๆ

Side-by-side comparison of a risky Claude Code allow rule containing a literal password and a safe rule that references an environment variable

อ้างอิงความลับ อย่าพิมพ์มันลงไป เชลล์จะขยายตัวแปรในขณะรัน แต่กฎ allow จะเก็บข้อความตามที่เขียนไว้ ดังนั้น psql "$DATABASE_URL" จะบันทึก $DATABASE_URL ในกฎ ไม่ใช่รหัสผ่าน:

{
  "permissions": {
    "allow": ["Bash(psql \"$DATABASE_URL\" *)", "Bash(npm run test *)"],
    "deny": ["Read(./.env)", "Read(./.env.*)"]
  }
}

กฎ deny มาจากเอกสาร settings ของ Anthropic โดยตรง มันป้องกันไม่ให้ Claude Code อ่านไฟล์ .env ของคุณ จึงไม่สามารถคัดลอก key จากที่นั่นไปใส่ในคำสั่งได้เช่นกัน

จำกัดขอบเขตของกฎให้แคบ ผู้คอมเมนต์บน HN ที่อ้างงานวิจัยบอกว่า 5% ของไฟล์อนุญาตคำสั่งเชลล์ใด ๆ และ 43% มีกฎ interpreter เช่น Bash(python:*) กฎแบบนี้ปล่อยให้ agent รันอะไรก็ได้ผ่าน Python จึงเท่ากับเป็นกฎ allow-everything ที่ยุ่งยากขึ้น

พิจารณาใช้ auto mode และ sandbox Cherny แนะนำ auto mode แทนการเขียนกฎสิทธิ์ด้วยมือ และบอกว่า Anthropic สร้าง sandbox แบบโอเพนซอร์สไว้ มีผู้คอมเมนต์หลายคนชี้ว่า auto mode เป็น classifier ไม่ใช่ขอบเขตด้านความปลอดภัย จึงควรใช้คู่กับนิสัยที่กล่าวมาข้างต้น

เก็บ agent ให้ห่างจากความลับของ production key ที่ปลอดภัยที่สุดคือ key ที่ agent ไม่เคยเห็น เราเคยพูดถึงแนวทางนี้ใน วิธีให้ AI agent ใช้ API key โดยไม่ต้องเห็นมัน และสิ่งที่ผู้โจมตีทำกับ AI key ที่รั่วไหลใน AI API keys ที่ถูกขโมยและ LLMjacking

ให้ coding agent ของคุณเรียก API โดยไม่ต้องพิมพ์ key ด้วย Apidog CLI

วิธีที่พบบ่อยที่ key หลุดเข้าไปในคำสั่งที่ถูกอนุมัติ คือการเรียก API อย่างรวดเร็ว เช่น curl -H "Authorization: Bearer sk-..." เพื่อเช็ก endpoint คุณสามารถมอบงานนี้ให้ Apidog CLI แทนได้ key จะอยู่ในตัวแปร environment ของ Apidog scenario ทดสอบของคุณจะอ้างอิงมันเป็น {{API_KEY}} และคำสั่งที่ agent รันจะมีเพียง project, scenario และ environment ID เท่านั้น ไม่มีความลับใด ๆ ให้ถูกบันทึก

ตั้งค่าครั้งเดียว ใน terminal ของคุณเองแทนที่จะผ่าน agent เพื่อให้ access token ของคุณไม่ผ่านการอนุมัติใด ๆ:

npm install -g apidog-cli@latest
apidog auth login
npx -y skills add https://apidog.com   # pick Claude Code when prompted

แล้วสั่ง Claude Code ด้วย prompt เดียว:

List the environments in Apidog project 123456, then run test scenario 7890
against the staging environment and summarise any failed assertions.
The API key is stored in that environment as {{API_KEY}}. Never pass a key,
token or password on the command line, and never use --env-var for secrets.

Agent จะรันคำสั่งลักษณะนี้ ซึ่งปลอดภัยพอให้อนุมัติด้วย “Don’t Ask Again” ได้:

apidog environment list --project 123456
apidog run -t 7890 --project 123456 -e <envId> -r cli,json

มีข้อควรระวังตรงไปตรงมาสองข้อ ข้อแรก apidog run ใช้ค่าที่แชร์ของตัวแปร ซึ่งถูกซิงก์ไปยัง Apidog และสมาชิกของโปรเจกต์สามารถเห็นได้ จึงควรเก็บ test key ที่จำกัดสิทธิ์ไว้ที่นั่น ไม่ใช่ root key ของ production ถ้าคุณต้องการเก็บค่าไว้บนดิสก์ apidog run รับ --variables <path> ได้เช่นกัน ให้ชี้ไปยังไฟล์นอก repo ข้อที่สอง แฟล็ก --env-var "key=value" มีไว้สำหรับส่งตัวแปรผ่าน command line ซึ่งเป็นรูปแบบที่ทำให้เกิดการรั่วไหลพอดี จึงควรบอก agent ของคุณไม่ให้ใช้กับความลับ

ทีมที่ใช้แพลน Enterprise ยังดึงความลับจาก HashiCorp Vault, Azure Key Vault หรือ AWS Secrets Manager ได้ด้วย Apidog Vault Secrets และ Enterprise SaaS Secret Scanner จะระบุ key ที่ถูกบันทึกใน requests, scripts และตัวแปรของ Apidog มันไม่ได้สแกน repo บน GitHub จึงควรใช้วิธีตรวจสอบข้างต้นควบคู่กันไป ดูคำแนะนำการตั้งค่าแบบเต็มได้ที่ วิธีใช้ Apidog CLI ใน Claude Code และ การจัดการ environment และตัวแปรความลับใน Apidog แพลน Free ของ Apidog รองรับผู้ใช้ได้ถึง 4 คน

button

คำถามที่พบบ่อย

settings.local.json ของ Claude Code ถูก gitignore ไว้โดยค่าเริ่มต้นหรือไม่?

บางส่วน เมื่อ Claude Code สร้างไฟล์นี้ใน git repository มันจะเพิ่ม **/.claude/settings.local.json ลงใน global git excludes ของคุณ ซึ่งป้องกันเฉพาะเครื่องของคุณ และไม่มีผลหากคุณสร้างไฟล์ด้วยตัวเองหรือ force-add มัน ควรเพิ่มบรรทัดนี้ลงใน .gitignore ของ repo เองด้วย

การลบไฟล์ทำให้ key ที่รั่วไหลหายไปหรือไม่?

ไม่ key ยังอยู่ในประวัติ git, ใน fork และในทุก clone ที่สร้างไว้ขณะที่มันเป็นสาธารณะ หมุนเปลี่ยน key ก่อน แล้วจึงถอนการ track ไฟล์และล้างประวัติด้วย git-filter-repo

gitleaks หรือ TruffleHog จับการรั่วไหลแบบนี้ได้หรือไม่?

ไม่ชัวร์ ในตัวอย่างของ Apiiro มีไฟล์ 215 จาก 1,122 ไฟล์ที่มีความลับจริงซึ่งทั้งสองเครื่องมือพลาด รันเครื่องมือสแกน แล้วอ่านกฎ Bash(...) ในไฟล์ด้วยตัวเองด้วย

นี่เป็นปัญหาของโมเดลหรือปัญหาของ Claude Code?

Apiiro ทดสอบซ้ำได้กับ Opus 5.5 และ Fable 5.1 และสรุปว่าเป็นลักษณะของ Claude Code ไม่ใช่โมเดล การอนุมัติจะเก็บข้อความคำสั่ง ไม่ว่าโมเดลใดจะเป็นผู้เขียนคำสั่งนั้น

ฉันจะอนุมัติคำสั่งอย่างปลอดภัยใน Claude Code ได้อย่างไร?

อนุมัติเป็น pattern เช่น Bash(npm run test *) และอ้างอิงความลับเป็นตัวแปร environment เช่น $DATABASE_URL เพิ่มกฎ deny สำหรับ Read(./.env) และ Read(./.env.*) ด้วย

ฝึกการออกแบบ API แบบ Design-first ใน Apidog

ค้นพบวิธีที่ง่ายขึ้นในการสร้างและใช้ API