دليل عملي

عزل وكلاء البرمجة بالذكاء الاصطناعي على VPS: AGENTS.md ملغّم

الذكاء الاصطناعي12 دقيقةً للقراءةعدد الخطوات: 9

في 25 أكتوبر 2026 نقل موقع BleepingComputer أن ملف AGENTS.md ملغّمًا، يُحمَّل تلقائيًا عند تشغيل الوكيل في المجلد الخطأ، كان كافيًا لجعل Codex ينفّذ أوامر. وبالنسبة إلى الوكالة، يُقاس الخطر بما يستطيع الوكيل الوصول إليه: مفاتيح النشر والرموز ومستودعات عملاء آخرين. يبني هذا الدليل خادم VPS مخصصًا للتطوير بمستخدم بلا صلاحيات، ودليل مشروع ضيق، ولا أسرار إنتاج، وخروج شبكي مقيّد، ثم مراجعة لملفات التعليمات قبل كل جلسة.

المحتويات· ما يكشفه بحث Forever Security1/13
  1. 01ما يكشفه بحث Forever Security
  2. 02ما تثبته الدراسة وما لا تقوله
  3. 03تشغيل الوكيل في المجلد الصحيح والموافقة على الأوامر: فلماذا خادم منفصل؟
  4. 04المتطلبات: ما تحتاجه لبناء الـ VPS
  5. 05بناء الـ VPS في تسع خطوات
  6. 06كل ضمانة تحدّ من شيء محدد
  7. 07مراجعة ملفات التعليمات قبل أن يتبعها الوكيل
  8. 08حالة الحزمة function-color: ما يغيّره الترشيح وما لا يغيّره
  9. 09عدّ الرفض وقطع سكربتات التثبيت
  10. 10استكشاف الأخطاء: ما ستصادفه من أخطاء
  11. 11ما لا يحلّه هذا الخادم
  12. 12للوكالة: خادم VPS لكل عميل
  13. 13الوثائق الرسمية

ما يكشفه بحث Forever Security

في 25 أكتوبر 2026 نقل موقع BleepingComputer أعمال Forever Security. وجد الباحثون في مجلد ~/Downloads لدى أحد العملاء ملف AGENTS.md ملغّمًا يطلب من وكيل برمجة تثبيت حزمة npm اسمها «function-color». وكان ذلك المجلد هو نفسه دليل عمل الوكيل، والوكلاء يحمّلون تلقائيًا ملفات التعليمات الموجودة في دليل عملهم. والسيناريو المعاد بناؤه كالتالي: صفحة ويب تضع الملف بصمت في مجلد التنزيلات، ثم يشغّل المستخدم وكيله في ذلك المجلد، فيتبع الوكيل التعليمات بالأدوات والصلاحيات التي يملكها أصلًا.

مع Codex من OpenAI نجحت السلسلة الكاملة، بحمولة غير ضارة (فتح الحاسبة)، في 90 % من الاختبارات. ومع Claude Code كان ملف CLAUDE.md ملغّم يعيد توجيه حركة واجهة البرمجة إلى خادم يملكه الباحثون، فينكشف رمز OAuth ويمكن تنفيذ شيفرة في نحو 50 % من الاختبارات. ويرى الباحثون أنه لا شيء يستدعي الإصلاح لدى OpenAI أو Anthropic: فالوكيل يعمل كما صُمّم.

ما تثبته الدراسة وما لا تقوله

  • المثبت — يكفي ملف تعليمات في دليل العمل لتوجيه الوكيل، دون استغلال أي ثغرة برمجية.
  • الشرط — يتطلب الهجوم أن يشغّل المستخدم الوكيل في المجلد المعني. ووفق BleepingComputer توصي OpenAI وAnthropic أصلًا بتشغيل الوكيل في دليل المشروع.
  • حمولات غير ضارة — نسبتا 90 % ونحو 50 % مصدرهما اختبارات بحمولة غير خطرة؛ فهما لا تقيسان هجمات حقيقية ولا تنطبقان على كل الأدوات.
  • طريقة التسليم مجهولة — لم يتمكن الباحثون من تحديد كيف وصل ملف العميل إلى تنزيلاته: وتبقى صفحة الويب مجرد فرضية.
  • Cursor CLI — ذُكرت أداة شُغّلت من ذلك المجلد، لكنها لم تُوصف بأنها اختُبرت.
  • قراءتنا — قد يحتوي مستودع مستنسخ على ملف تعليماته الخاص. هذا استنتاج منا وليس نتيجة من الدراسة.

تشغيل الوكيل في المجلد الصحيح والموافقة على الأوامر: فلماذا خادم منفصل؟

الموافقة البشرية وصندوق الحماية في الأداة ضمانتان حقيقيتان ويجب إبقاؤهما مفعّلتين، وهذا ما يوصي به المقال المصدر أيضًا. لكنهما تقومان على انتباه دائم وأداة مضبوطة جيدًا وتشغيل في المجلد الصحيح. وحين يختل أحد الثلاثة يصبح السؤال: ما الذي يستطيع الوكيل المخترَق الوصول إليه؟

على جهاز العمل الجواب طويل: مفاتيح SSH ورموز السحابة ومستودعات عملاء آخرين ومتصفح مسجَّل الدخول. وعلى VPS مخصص الجواب قصير وأنت من يحدده. لا يحوي الخادم إلا المشروع ورمزًا بأقل نطاق ممكن ومستخدمًا بلا صلاحيات. ويمكن حذفه وإعادة إنشائه دون المساس بجهازك. لا يجعل VPS الوكيل آمنًا: إنه يحدّ من نطاق ضرره، وهذا هو الوعد الوحيد لهذا الدليل.

المتطلبات: ما تحتاجه لبناء الـ VPS

تستدعي وكلاء البرمجة واجهة برمجة لدى مزوّد: لا يجري حساب النموذج على خادمك، ولذلك يبقى الـ VPS متواضعًا. خصّص نواتين افتراضيتين و4 غيغابايت من الذاكرة و40 غيغابايت من القرص لمشروع Node أو PHP عادي، وأكثر إن كنت تبني أو تشغّل حاويات. تحتاج إلى وصول root وإلى Debian أو Ubuntu LTS وعنوان IPv4 مخصص ومفتاح SSH للاتصال.

من جهة الشبكة يُفتح منفذ واحد للدخول: المنفذ 22 لـ SSH. وفي الخروج لا يصل مستخدم الوكيل إلا إلى المنفذ 8888 على الواجهة المحلية، حيث يستمع وكيل وسيط يمرّر الطلبات إلى قائمة قصيرة من المضيفين. دوّن إذن قبل البدء المضيفين الذين تحتاجهم أداتك: سجل npm وواجهة المزوّد ومستودع Git للمشروع. الأوامر أدناه مكتوبة لـ Debian وUbuntu باستخدام apt وufw وnftables، وتفترض حساب إدارة يملك sudo، منفصلًا عن مستخدم الوكيل.

بناء الـ VPS في تسع خطوات

  1. إنشاء مستخدم بلا صلاحيات

    sudo adduser --disabled-password --gecos "" agent
    id agent
    sudo -l -U agent
    يجب ألا يعرض الأمر الثاني المجموعة sudo، ويجب أن يجيب الثالث بأن المستخدم غير مخوَّل بتنفيذ sudo. الحساب بلا كلمة مرور: تدخل إليه بالأمر sudo -iu agent من حساب الإدارة. خصّص VPS لكل عميل حتى لا يرى المستخدم agent في خادم إلا مشاريع ذلك العميل.

  2. تخصيص دليل لكل مشروع

    sudo install -d -o agent -g agent -m 700 /srv/agents/projet-a
    شغّل الوكيل دائمًا من هذا الجذر، وليس من / أو ~ أو مجلد تنزيلات: فالدليل الأب الواسع يحمّل ملفات تعليمات لم تراجعها. ولجلب الشيفرة ادخل جلسة الوكيل ثم استنسخ:
    sudo -iu agent
    git clone <url-du-dépôt> /srv/agents/projet-a
    استخدم مفتاح نشر للقراءة فقط، يُولَّد على هذه الآلة ويخص مستودع المشروع.

  3. قطع الوصول إلى مفاتيحك

    sudo -iu agent printenv SSH_AUTH_SOCK
    echo 'AllowAgentForwarding no' | sudo tee /etc/ssh/sshd_config.d/10-agents.conf
    sudo sshd -t && sudo systemctl reload ssh
    يجب ألا يعرض الأمر الأول شيئًا: لا يُمرَّر أي وكيل SSH إلى جلسة وكيل البرمجة. اتصل بالآلة عبر ssh -o ForwardAgent=no. لا تضع أي مفتاح نشر للإنتاج على هذا الخادم، ولا أي ملف إعدادات يخص عميلًا آخر.

  4. حصر متغيرات البيئة في المشروع

    sudo -iu agent
    install -m 600 /dev/null ~/.agent-env
    ثم حرّر ~/.agent-env ليحوي رمز المزوّد فقط، بأقل نطاق ممكن، مخصصًا لهذه الآلة وقابلًا للإلغاء. شغّل الوكيل ببيئة مفرَّغة حتى لا يرث أي متغير من جلستك:
    env -i HOME="$HOME" PATH="$PATH" TERM="$TERM" HTTPS_PROXY=http://127.0.0.1:8888 bash -c 'set -a; . ~/.agent-env; cd /srv/agents/projet-a && exec claude'
    استبدل claude بأمر أداتك. وإن كانت الأداة تتصل بحساب (OAuth) بدل مفتاح واجهة برمجة، فإن الرمز يوجد في الدليل الشخصي للمستخدم: وهو الرمز الذي رأت الدراسة أنه انكشف مع Claude Code. فضّل مفتاح واجهة برمجة مخصصًا تلغيه عند حذف الخادم.

  5. إغلاق الدخول بـ ufw

    sudo ufw default deny incoming
    sudo ufw limit 22/tcp
    sudo ufw enable
    أبقِ جلسة SSH ثانية مفتوحة أثناء التفعيل. يرشّح ufw بالعنوان والمنفذ، لا باسم المضيف ولا بالمستخدم: ولهذا يُضبط الخروج في الخطوتين التاليتين بوكيل وسيط وnftables.

  6. تثبيت وكيل خروج بقائمة سماح

    sudo apt install tinyproxy
    في /etc/tinyproxy/tinyproxy.conf اضبط Listen 127.0.0.1, Port 8888, FilterDefaultDeny Yes, Filter "/etc/tinyproxy/allowlist" ثم اكتب القائمة:
    printf '%s\n' '^registry\.npmjs\.org$' '^api\.anthropic\.com$' | sudo tee /etc/tinyproxy/allowlist
    sudo systemctl restart tinyproxy
    كل سطر تعبير نمطي على اسم المضيف. استبدل واجهة المثال بواجهة مزوّدك المأخوذة من وثائقه، ولا تضف ^github\.com$ إلا إذا طلبها المشروع. تصف وثائق tinyproxy ترشيحًا بحسب النطاق، لكنها لا تذكر أنه يُطبَّق على مضيف أنفاق HTTPS (CONNECT): فهذا غير موثَّق ويجب اختباره. لا تعتبر هذا الترشيح مسلَّمًا به قبل اختبار الخطوة 8.

  7. منع الوكيل من أي خروج آخر بـ nftables

    أضف في نهاية /etc/nftables.conf، بعد السطر flush ruleset:
    table inet agent_egress {
    chain output {
    type filter hook output priority 0; policy accept;
    meta skuid "agent" oifname "lo" tcp dport 8888 accept
    meta skuid "agent" limit rate 5/minute log prefix "agent-egress-drop: "
    meta skuid "agent" counter drop
    }
    }
    لم يعد المستخدم agent يصل إلا إلى الوكيل المحلي؛ وما عداه يُسجَّل ثم يُسقَط. افحص الصياغة قبل التفعيل:
    sudo nft -c -f /etc/nftables.conf
    sudo systemctl enable --now nftables

  8. اختبار صمود الترشيح

    sudo -u agent curl -sS --max-time 5 https://example.com
    sudo -u agent curl -sS -x http://127.0.0.1:8888 https://example.com
    sudo -u agent curl -sS -x http://127.0.0.1:8888 -o /dev/null -w '%{http_code}\n' https://registry.npmjs.org/-/ping
    يجب أن ينتهي الأمر الأول بانتهاء المهلة لأن جدار الحماية يُسقط الاتصال المباشر. ويجب أن يفشل الثاني برفض من الوكيل الوسيط (مع curl، رسالة من نوع CONNECT tunnel failed؛ والرمز الدقيق في سجل tinyproxy). ويجب أن يجيب الثالث بالرمز 200. هذه النتائج هي المتوقعة: عاينها بنفسك على آلتك. وإن نجح الأمر الثاني فالترشيح لا يغطي أنفاق HTTPS: فانتقل إلى وكيل وسيط تغطي وثائقه CONNECT، وصحّح ذلك قبل تشغيل الوكيل.

  9. التخطيط لحذف الخادم

    احفظ هذه الأوامر في سكربت خاضع للإصدارات. يُحذف الـ VPS المشبوه ويُعاد إنشاؤه من الصورة الأصلية، وتلغي رمز المزوّد. أما وصولك أنت إلى الخادم فمرّره عبر مضيف بوابة (bastion) بدل التعريض المباشر: ويغطي دليل bastion host المرتبط أسفل الصفحة هذه النقطة.

كل ضمانة تحدّ من شيء محدد

مرّر الجدول أفقيًا

الضمانةما تحدّ منهما تتركه يمر
الموافقة البشرية على الأوامركل أمر يُنفَّذأمر يبدو عاديًا تُوافَق عليه بحكم العادة
صندوق حماية الأداةإجراءات الوكيل بحسب إعدادهما يتوقف على إعداد منسيّ أو يخص الأداة
مستخدم بلا صلاحياتصلاحيات root وملفات النظام والحسابات الأخرىملفات المستخدم نفسه، ومنها رمزه
دليل مشروع ضيقملفات التعليمات المحمّلة بالخطأمحتوى المشروع نفسه
خروج شبكي مرشَّحتثبيت من مضيف غير متوقَّع، أو إرسال إلى مضيف مجهول (بعد التحقق من الترشيح)كل ما يمر عبر مضيف مسموح، سجلًا كان أو واجهة برمجة
لا مفتاح إنتاج على الآلةالوصول إلى خوادم الإنتاج وإلى عملاء آخرينما يكشفه رمز المزوّد ومستودع المشروع
VPS مخصص وقابل لإعادة الإنشاءبقاء الاختراق واستمراره، وجهاز العملبيانات العميل الموجودة على الآلة

مراجعة ملفات التعليمات قبل أن يتبعها الوكيل

يعمل ملف التعليمات مثل الشيفرة، عبر الوكيل: فراجعه على هذا الأساس. لإعداد الجرد نفّذ find /srv/agents -type f \( -name AGENTS.md -o -name CLAUDE.md \) -not -path '*/node_modules/*' . وللكشف عن أي تغيير احتفظ ببصمة:
find /srv/agents -type f \( -name AGENTS.md -o -name CLAUDE.md \) -not -path '*/node_modules/*' -exec sha256sum {} + | sort -k2 > ~/instructions.sha256
ثم قارن قبل كل جلسة بالأمر find /srv/agents -type f \( -name AGENTS.md -o -name CLAUDE.md \) -not -path '*/node_modules/*' -exec sha256sum {} + | sort -k2 | diff ~/instructions.sha256 - . وفي مستودع Git يعرض git log -p -- AGENTS.md CLAUDE.md ما تغيّر منذ مراجعتك الأخيرة.

لا تبحث الأدوات كلها عن ملفاتها في المكان نفسه (الدليل الحالي، المجلدات الأم، المجلد الشخصي): اقرأ وثائق أداتك وأبقِ هذه المواضع فارغة أو معروفة. لا تشغّل وكيلًا أبدًا في ~/Downloads ولا في مجلد أب واسع: فهذا أول تخفيف توصي به الدراسة.

حالة الحزمة function-color: ما يغيّره الترشيح وما لا يغيّره

في الحالة الموثقة كان الملف الملغّم يطلب تثبيت حزمة npm باسم «function-color». ولا يذكر التقرير من أي سجل. قراءتنا، وهي تخفيف وليست نتيجة من البحث: خروج مقيّد بقائمة مضيفين ينبغي أن يمنع أو ينبّه (متى تحقّقتَ من الترشيح في الخطوة 8) إلى تثبيت من سجل أو خادم غير متوقَّع، ويُظهر ذلك سجلّ الوكيل الوسيط.

لكنه لا يمنع حزمة منشورة على السجل المسموح به، لأن registry.npmjs.org ضمن القائمة. وفي هذه الحالة اعتمد على مراجعة ملف التعليمات وعلى قائمة حزم معتمدة، وقبل ذلك كله على ألا يوجد ما يُسرَق من أسرار. ويفصّل دليل سلسلة التوريد في npm، المرتبط أدناه، هذا الجزء.

عدّ الرفض وقطع سكربتات التثبيت

اقرأ حالات الرفض كل يوم: sudo journalctl -k --since today | grep agent-egress-drop
sudo grep -i filtered /var/log/tinyproxy/tinyproxy.log
الرفض المتكرر تجاه مضيف مجهول إشارة يجب فهمها قبل إضافة المضيف إلى القائمة: دوّن الاسم، وابحث عن سبب استدعاء الأداة له، ثم قرّر. وفي npm يمنع الأمر npm config set ignore-scripts true (يُنفَّذ بصفة agent) التشغيل التلقائي لسكربتات تثبيت الاعتماديات.

استكشاف الأخطاء: ما ستصادفه من أخطاء

الرسائل أدناه هي التي تنتجها مكونات هذا التركيب. ولكل منها علاج لا يمر أبدًا بإضعاف الترشيح.

  • رفض sudo للمستخدم agent — سلوك متوقَّع: المستخدم بلا أي صلاحية، ويتوقف نص الرفض الدقيق على إصدار sudo. نفّذ العملية بحساب الإدارة، ولا تضف agent إلى المجموعة sudo أبدًا.
  • فشل نفق CONNECT (مع curl، رسالة من نوع CONNECT tunnel failed) — الأرجح أن الوكيل الوسيط رفض المضيف؛ والرمز الدقيق يتوقف على tinyproxy ويظهر في سجله. اقرأ اسمه في /var/log/tinyproxy/tinyproxy.log ثم أضفه إلى القائمة فقط إذا احتاجته الأداة.
  • بحسب الأداة، انتهاء مهلة أو فشل في الشبكة (مثل ETIMEDOUT أو fetch failed) — تحاول الأداة اتصالًا مباشرًا يُسقطه nftables. تحقق من أن HTTPS_PROXY مُصدَّر في جلسة الوكيل. بعض العملاء يتجاهلون هذا المتغير: فيفشلون فشلًا مغلقًا، وتبيّن وثائقهم إن كانوا يقبلون وكيلًا وسيطًا.
  • Permission denied عند قراءة مجلد مستخدم آخر — هذا هو العزل يؤدي عمله. وإن احتاج الوكيل إلى ملف فانسخه إلى دليل المشروع.
  • انقطاع اتصال SSH بعد ufw enable — كانت قاعدة المنفذ 22 ناقصة، أو يستمع SSH على منفذ آخر. من وحدة تحكم الـ VPS نفّذ sudo ufw status ثم sudo ufw allow <المنفذ>/tcp.

ما لا يحلّه هذا الخادم

يحدّ الـ VPS من نطاق الضرر ولا يزيل الخطر. رمز المزوّد موجود على الآلة: ويستطيع الوكيل المخترَق استخدامه ما لم تلغه. وشيفرة العميل موجودة أيضًا، وتبقى التسريبات ممكنة عبر مضيف مسموح، لأن السجل أو مستودع Git يقبل بيانات واردة كذلك. ويوصي الباحثون بإبقاء طلبات الموافقة وصندوق حماية الأداة: وهذا التركيب يضاف إليهما ولا يحل محلهما. وأخيرًا، يحتاج خادم التطوير الذي يقدّم حركة عامة إلى تقسية خاصة به، تعالجها قائمة التحقق المرتبطة أدناه.

للوكالة: خادم VPS لكل عميل

أسهل عزل يمكن شرحه لعميل هو العزل المادي: خادم VPS لكل عميل، بمستخدمه ورمزه وجدار حمايته. لا يوجد فيه مفتاح إنتاج ولا عميل آخر، فلا يتجاوز الوكيل المخترَق ذلك النطاق. احتفظ بسكربت إعداد واحد لكل الخوادم: فأي قاعدة خروج تتغير تُعاد في كل مكان. وفي نهاية المهمة تحذف الـ VPS وتلغي الرمز وتنتقل إلى ما بعده دون أي أثر على جهازك. يوفر VPS من ServOrbit.com وصول root وعنوان IPv4 مخصصًا واختيار نظام التشغيل: وهذا أساس هذا التصميم.

الوثائق الرسمية

تقرير BleepingComputer عن بحث Forever Security: https://www.bleepingcomputer.com/news/security/ai-coding-agents-hijacked-using-agentsmd-file-in-downloads-folder/

وثائق nftables: https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes

وثائق tinyproxy: https://tinyproxy.github.io/

صفحة دليل adduser (Debian): https://manpages.debian.org/stable/adduser/adduser.8.en.html

إعدادات npm: https://docs.npmjs.com/cli/using-npm/config

خادم VPS لكل عميل، معزول وقابل لإعادة الإنشاء

الوكالة التي تعزل وكلاء البرمجة تمنح كل عميل خادم VPS خاصًا به: وصول root وعنوان IPv4 مخصص واختيار نظام التشغيل. وهكذا يبقى الوكيل المخترَق داخل نطاق عميل واحد. يتوفر خيار إدارة VPS لمن لا يريد تشغيل الخادم بنفسه، أما هذا الدليل فيُقدَّم دون دعم من ServOrbit.com لعملية الإعداد.

بحاجة إلى مساعدة؟

تصفّح مركز المساعدة والأسئلة الشائعة، أو تواصل مع فريقنا — معاودة اتصال أو WhatsApp أو بريد إلكتروني. الدعم بـالعربية والفرنسية والإنجليزية.

راسلنا على WhatsAppيُفتح في علامة تبويب جديدة