كيف تسرب ميزة "لا تسألني مجددًا" في Claude Code مفاتيح API إلى GitHub: طريقة الفحص والإصلاح

عند الموافقة على أمر مع خيار "لا تسألني مرة أخرى"، يُحفظ الأمر حرفياً كاملاً، بما في ذلك كلمات المرور. إليك فحصًا بأمر واحد لمستودعاتك، وترتيب التنظيف الصحيح، وكيفية إبقاء المفاتيح بعيدة عن موافقات الوكيل الذكي.

Ahmed Waheed

Ahmed Waheed

12 نوفمبر 2026

كيف تسرب ميزة "لا تسألني مجددًا" في Claude Code مفاتيح API إلى GitHub: طريقة الفحص والإصلاح

Apidog للمؤسسات

النشر على الخوادم المحلية

SSO و RBAC

متوافق مع SOC 2

استكشف Apidog للمؤسسات

يحفظ زر «Don’t Ask Again» (لا تسألني مرة أخرى) في Claude Code الأمر الذي وافقت عليه حرفيًا كقاعدة سماح في ملف .claude/settings.local.json. إذا كان ذلك الأمر يحتوي على كلمة مرور أو مفتاح API، فأصبح السر الآن موجودًا كنص صريح في مجلد مشروعك، وإذا تم رفع الملف إلى المستودع، فقد أصبح متاحًا للعامة. اكتشفت شركة الأمن Apiiro عدد 1,122 ملفًا من هذا النوع على GitHub العام تحتوي على 1,379 سرًا حقيقيًا. إليك كيفية فحص مستودعاتك بأمر واحد، وتنظيفها، ومنع تكرار الأمر.

ماذا حدث: نتائج Apiiro بالأرقام

بحثت Apiiro في GitHub العام عن نسخ من ملف .claude/settings.local.json، وهو الملف الخاص بكل مشروع حيث يخزّن Claude Code موافقاتك الشخصية على الأذونات. ووجدت 104,185 نسخة موزعة على 103,617 مستودعًا. وفي 1,122 منها كان هناك سر حقيقي واحد على الأقل، بإجمالي 1,379 سرًا مميزًا، وفقًا لتقرير iTnews عن البحث.

نوع السر العدد
كلمات مرور قواعد البيانات 379
مفاتيح service-role الخاصة بـ Supabase 122
تسجيلات دخول SSH لخوادم عامة 43
رموز GitHub وGitLab وnpm 42
مفاتيح AWS 23

عندما وسّعت Apiiro البحث ليشمل النسخ القديمة من الملف في git، والملف المشترك .claude/settings.json وسجلات محادثات الوكلاء المحفوظة، ارتفع العدد إلى 2,539 سرًا موزعة على 1,994 مستودعًا. لم تختبر Apiiro ما إذا كانت بيانات الاعتماد ما زالت تعمل، لكن إحدى المؤسسات التي أبلغتها أكدت أن أحد المفاتيح كان فعّالًا.

أرقام الفاحصات (Scanners) هي الجزء الذي يجب أن يقلقك أكثر من غيره. من بين الملفات الـ 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، كما هو موضح في وثيقة الإعدادات الخاصة بـ Anthropic. تسجّل القاعدة نص الأمر. إذا كان الأمر كما يلي:

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

فسيحتوي ملف الإعدادات لديك الآن على شيء من هذا القبيل:

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

كلمة المرور موجودة في القاعدة لأنها كانت موجودة في الأمر. يوفّر Claude Code ما وافقت عليه حرفيًا، كلمة بكلمة.

مخطط يوضح كيفية انتقال موافقة Claude Code التي تحتوي على كلمة مرور مضمنة إلى settings.local.json ثم إلى مستودع GitHub عام

لماذا ينتهي الأمر على GitHub

يحاول Claude Code إبقاء هذا الملف خارج git. عند أول كتابة لـ .claude/settings.local.json في مستودع لم يتجاهله مسبقًا، يضيف **/.claude/settings.local.json إلى ملف الاستبعادات العام (global excludes) الخاص بـ git. لكن هذه الحماية بها ثغرات:

افحص مستودعاتك بأمر واحد

ابدأ بالمستودع الذي تعمل فيه. يوضح لك هذا ما إذا كان الملف متتبعًا حاليًا وما إذا كان قد رُفع إلى المستودع من قبل:

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

إذا طبع السطر الأول أي شيء، فالملف موجود في شجرتك الحالية. وإذا طبع الثاني أي شيء، فهو في سجلّك، حتى لو حذفته لاحقًا.

لمسح جميع المستودعات تحت مجلد واحد دفعة واحدة:

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|://[^/]*:[^@]*@'

أي سلسلة اتصال تحتوي على user:password@، أو ترويسة Authorization: Bearer، أو -p متبوعة بكلمة مرور صريحة، أو أي شيء يبدأ بـ sk- أو ghp_ أو AKIA أو eyJ هو بيانات اعتماد. شغّل gitleaks على المستودع كفحص إضافي، لا كفحص وحيد.

كيف تصلح ملف إعدادات متسربًا

الترتيب مهم. تدوير المفاتيح (Rotation) يأتي أولًا، لأن حذف الملف لا يفعل شيئًا حيال النسخة الموجودة بالفعل في الشوكات (forks) والاستنساخات (clones) وذاكرة التخزين المؤقت.

  1. دوّر (Rotate) كل بيانات اعتماد وردت في الملف. اطّلع على السجل الكامل للملف باستخدام git log -p --all -- .claude/settings.local.json، وأدرج كل سر فيه، وألغِ كل واحد منها لدى مزوّده. تضع إرشادات Apiiro هذه الخطوة أولًا.
  2. أوقف تتبع الملف وتجاهله في المستودع نفسه:
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 المطابق. القاعدة في المستودع تحمي كل عملية استنساخ.

  1. نظّف السجل إذا كان المستودع عامًا أو متشاركًا على نطاق واسع. يقوم git-filter-repo بإزالة الملف من كل التزام (commit):
git filter-repo --invert-paths --path .claude/settings.local.json
git push --force --all

هذا يعيد كتابة السجل للجميع، لذا حذّر فريقك أولًا. كما أنه لا يصل إلى الشوكات، فهو إجراء تنظيف وليس بديلًا عن الخطوة 1.

  1. نظّف الملف المحلي أيضًا. افتح .claude/settings.local.json، واحذف أي قاعدة تحتوي على سر صريح، واستبدلها بنمط (القسم التالي).
  2. فعّل حماية الدفع (Push Protection). حماية الدفع في فحص أسرار GitHub تحجب عمليات الدفع التي تحتوي على تنسيقات أسرار معروفة. لن تلتقط كل شيء، كما تُظهر الملفات الـ 215 التي فاتت الفاحصات، لكنها توقف تنسيقات الرموز الشائعة.

منع تكرار الأمر

الحل بسيط في القول: لا تضع أبدًا سرًا صريحًا في أمر ينفّذه وكيلك، ووافق على الأنماط (patterns) بدلًا من الأوامر الحرفية.

مقارنة جنبًا إلى جنب بين قاعدة سماح خطرة في Claude Code تحتوي على كلمة مرور صريحة وقاعدة آمنة تشير إلى متغير بيئة

أشر إلى الأسرار، ولا تكتبها. توسّع الصدفة (shell) المتغير في وقت التشغيل، لكن قاعدة السماح تخزّن النص كما هو مكتوب. لذا فإن psql "$DATABASE_URL" يخزّن $DATABASE_URL في القاعدة، وليس كلمة المرور:

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

قواعد deny منقولة مباشرة من وثيقة إعدادات Anthropic؛ فهي تمنع Claude Code من قراءة ملفات .env لديك، بحيث لا يمكن لصق مفتاح من هناك في أمر أيضًا.

حافظ على ضيق القواعد. ذكر معلّقون على HN عند الاقتباس من البحث أن 5% من الملفات سمحت بأي أمر في الصدفة، وأن 43% احتوت على قواعد للمفسّرات (interpreters) مثل Bash(python:*). قاعدة كهذه تتيح للوكيل تشغيل أي شيء عبر Python، فهي ببساطة قاعدة «اسمح بكل شيء» مع خطوات إضافية.

فكّر في الوضع التلقائي وصندوق الحماية. أوصى Cherny بالوضع التلقائي بدلًا من قواعد الأذونات المكتوبة يدويًا، وقال إن Anthropic بنت صندوق حماية مفتوح المصدر. وأشار عدة معلّقين إلى أن الوضع التلقائي مصنّف (classifier) وليس حدودًا أمنية، فاجمعه مع العادات المذكورة أعلاه.

أبقِ الوكلاء بعيدين عن أسرار الإنتاج. أكثر المفاتيح أمانًا هو الذي لا يراه الوكيل أبدًا. تناولنا الأنماط الخاصة بذلك في كيفية تمكين وكلاء الذكاء الاصطناعي من استخدام مفاتيح API دون رؤيتها، وما يفعله المهاجمون بمفاتيح الذكاء الاصطناعي المتسربة في مفاتيح AI API المسروقة وLLMJacking.

تمكين وكيل البرمجة لديك من استدعاء واجهات API دون كتابة المفاتيح باستخدام Apidog CLI

إحدى الطرق الشائعة التي يصل بها المفتاح إلى أمر تمت الموافقة عليه هي استدعاء سريع لـ API: مثل curl -H "Authorization: Bearer sk-..." للتحقق من نقطة نهاية. يمكنك تسليم هذه المهمة إلى Apidog CLI بدلًا من ذلك. يوجد المفتاح في متغير بيئة Apidog، ويشير سيناريو الاختبار الخاص بك إليه كـ {{API_KEY}}، والأمر الذي ينفّذه وكيلك لا يحتوي إلا على معرّفات المشروع والسيناريو والبيئة. لا يوجد فيه سر ليُحفظ.

اضبطه مرة واحدة، من نافذة الأوامر الخاصة بك وليس عبر الوكيل، حتى لا يمر رمز الوصول الخاص بك أبدًا عبر موافقة:

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

ثم قدّم لـ Claude Code توجيهًا واحدًا:

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.

ينفّذ الوكيل أوامر مثل هذه، والتي يمكن الموافقة عليها بأمان باستخدام «Don’t Ask Again»:

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

تنبيهان صادقان. أولًا، يستخدم apidog run القيمة المشتركة للمتغير، وهي متزامنة مع Apidog ومرئية لأعضاء المشروع، لذا خزّن هناك مفتاح اختبار محدود النطاق، لا مفتاح جذر للإنتاج. وإذا كنت تفضّل الاحتفاظ بالقيم على القرص، فإن apidog run يقبل أيضًا --variables <path>؛ وأشره إلى ملف خارج المستودع. ثانيًا، الخيار --env-var "key=value" موجود لتمرير المتغيرات في سطر الأوامر، وهذا بالضبط النمط الذي يتسبب في التسريب، فأخبر وكيلك بعدم استخدامه للأسرار.

يمكن للفرق المشتركة في خطة Enterprise أيضًا سحب الأسرار من HashiCorp Vault أو Azure Key Vault أو AWS Secrets Manager باستخدام Apidog Vault Secrets، ويحدد Enterprise SaaS Secret Scanner المفاتيح المحفوظة في طلبات Apidog والبرامج النصية والمتغيرات. لا يفحص مستودعات GitHub، لذا حافظ على الفحوصات المذكورة أعلاه أيضًا. للاطلاع على شرح كامل للإعداد، راجع كيفية استخدام Apidog CLI في Claude Code وإدارة البيئات ومتغيرات الأسرار في Apidog. تغطي خطة Apidog المجانية (Free) ما يصل إلى 4 مستخدمين.

button

الأسئلة الشائعة

هل يتم تجاهل settings.local.json في Claude Code بواسطة git افتراضيًا؟

جزئيًا. عندما ينشئ Claude Code الملف في مستودع git، يضيف **/.claude/settings.local.json إلى استبعادات git العامة لديك. هذا يحمي جهازك فقط، ولا ينطبق إذا أنشأت الملف يدويًا أو أضفته قسرًا. أضف السطر أيضًا إلى ملف .gitignore الخاص بالمستودع نفسه.

هل حذف الملف يزيل المفتاح المتسرب؟

لا. يبقى المفتاح في سجل git، وفي الشوكات وفي كل نسخة استُنسخت بينما كان عامًا. دوّر المفتاح أولًا، ثم أوقف تتبع الملف ونظّف السجل باستخدام git-filter-repo.

هل سترصد gitleaks أو TruffleHog هذه التسريبات؟

ليس بشكل موثوق. في عيّنة Apiiro، فاتت كلتا الأداتين 215 ملفًا من أصل 1,122 ملفًا يحتوي على سر حقيقي. شغّل فاحصًا، ثم اقرأ قواعد Bash(...) في الملف بنفسك.

هل هذه مشكلة في النموذج أم في Claude Code؟

أعادت Apiiro إنتاج المشكلة مع Opus 5.5 وFable 5.1 ووصفتها بأنها سمة من سمات Claude Code، لا من سمات النموذج. الموافقة تخزّن نص الأمر، أياً كان النموذج الذي كتبه.

كيف أوافق على الأوامر بأمان في Claude Code؟

وافق على الأنماط مثل Bash(npm run test *) وأشر إلى الأسرار كمتغيرات بيئة مثل $DATABASE_URL. أضف قواعد deny للأنماط Read(./.env) وRead(./.env.*).

ممارسة تصميم API في Apidog

اكتشف طريقة أسهل لبناء واستخدام واجهات برمجة التطبيقات