تصور کنید ابزاری که برای کمک به کدنویسی نصب کردهاید، در واقع یک درِ باز برای هر وبسایتی باشد که از آن بازدید میکنید. اگر یک عامل (Agent) — مانند دستیاری هوشمند که میتواند بهجای شما کد بنویسد و اجرا کند — اجازه دسترسی به خط فرمان (bash) لپتاپ شما را داشته باشد، در واقع یک «شل راه دور» (Remote Shell) روی سیستم شماست.
این معماری، سطح حمله را بهشدت افزایش میدهد. این موضوع شامل تهدیداتی چون حملات Drive-by مرورگر، DNS Rebinding و الگوهای خطرناک curl | bash میشود؛ فارغ از اینکه توسعهدهنده ابزار بهطور عمدی آن را برای مقابله با این تهدیدات طراحی کرده باشد یا خیر. در واقع، این سیستمها میراثدار بیست سال اشتباهات مربوط به دیمونهای محلی (Local Daemons) هستند که پیش از این در دنیای وب مستند شدهاند.
به گزارش وبسایت wren.wtf که هفته گذشته تحلیل دقیقی از opencode منتشر کرد و به کاربران هشدار داد که استفاده از آن را متوقف کنند، این ابزار دارای یک آسیبپذیری واقعی (CVE) بود: یک سرور HTTP پیشفرض با تنظیمات CORS بسیار باز و یک نقطه انتهایی (Endpoint) که دستورات شل دلخواه را اجرا میکرد. این یعنی هر وبسایتی که کاربر از آن بازدید میکرد، میتوانست کنترل کامل ماشین او را در دست بگیرد.
بر اساس مستندات agentproto — محیط اجرای بازمتنی که دیمونی محلی برای اجرای دستورات، خواندن فایلها و باز کردن تونلها فراهم میکند — نویسنده این ابزار از تحلیل opencode بهعنوان یک چکلیست امنیتی استفاده کرد. نتیجه اصلی این گزارش این بود که «فیلتر کردن متنی دستورات، چیزی جز دعا و امید نیست». بیشتر ابزارهای عاملمحور سعی میکنند bash را امن کنند؛ به این صورت که رشته متنی دستور را تجزیه کرده و کلمات «بد» یا خطرناک را مسدود میکنند، اما این روش اساساً یک رویکرد معیوب است. در حالی که بهینهسازی عملکرد این عاملها برای کاهش هزینهها در جریان است، چنانکه در تحلیل سازوکار Headroom AI برای حذف تورم متنی در عاملهای هوشمند مشاهده شد، اما امنیت باید پیشنیاز هرگونه بهینهسازی باشد.

افسانه فیلترهای متنی
حملهکنندگان بهراحتی با استفاده از چندین مکانیسم رایج، از فیلترهای رشتهای عبور میکنند:
- ارسال مستقیم خروجی (Piping) به bash
- استفاده از base64-decode برای مخفی کردن محمولههای مخرب (Payloads)
- بهرهبرداری از
env gitیا heredocs - اجرای دستورات از طریق
python3 -cبرای اجرای کد - استفاده از مسیرهای مطلق (Absolute Paths) برای دور زدن کلمات کلیدی
چون هیچ عبارت منظم (regex) کافی نیست، راهکار واقعی نیازمند دو مرز است که هرگز با یک رشته متنی تماس ندارند: حقوق دسترسی در سطح سیستمعامل (آنچه پروسه اجازه دارد انجام دهد) و وضعیت شبکه (چه کسی اجازه درخواست دارد).
همانطور که در تحلیلهای قبلی ما درباره امنیت مدلهای بازمتن اشاره کردیم، اعتماد به لایههای نرمافزاری بدون داشتن حفاظ سختافزاری یا سیستمی، ریسک بالایی دارد. برای شناسایی مخاطرات فوری، نویسنده چهار پرسش تشخیصی پیشنهاد میکند که میتوان در پنج دقیقه به آنها پاسخ داد:
۱. آیا ابزار به یک پورت TCP متصل شده است؟ (به ۱۲۷.۰.۰.۱ یا ۰.۰.۰.۰؟)
۲. آیا یک وبسایت تصادفی میتواند با fetch() به آن پورت دسترسی پیدا کند و پاسخ را بخواند؟ (این مورد را از طریق devtools مرورگر در هر صفحهای چک کنید).
۳. وقتی ابزار میگوید «bash مجاز است»، چه چیزی را بررسی میکند: رشته متنی دستور را یا خودِ فایل باینری را؟
۴. آیا ابزار پیش از آنکه شما مدلی را انتخاب کنید، به یک مدل راه دور متصل میشود؟
بستن حفرههای مرورگر
یکی از خطرناکترین تهدیدها، اجرای کد از راه دور (RCE) از طریق مرورگر است. در بسیاری از موارد، بررسیهای احرازی برای کلاینتهای محلی حذف میشوند تا دسترسی آسان شود؛ اما درخواستهای مرورگر به ۱۲۷.۰.۰.۱ بهعنوان درخواستهای لوپبک (Loopback) پذیرفته میشوند. اگر سرور از CORS باز (Reflected-Origin) استفاده کند، هر صفحه مخربی میتواند عامل را هدایت کند.
agentproto این مشکل را با پیادهسازی یک درگاه Origin حل کرد. مرورگرها همیشه هدر Origin در درخواستهای cross-origin میفرستند، اما کلاینتهای بومی (مثل CLI، curl یا یک ویرایشگر کد) هیچ هدری نمیفرستند. با افزودن یک بررسی ساده — if (origin && !allowlisted(origin)) return reject(403) — درخواستهای ارسالی از صفحهای در evil.com رد شده و در عین حال کلاینتهای بومی بدون تغییر به کار خود ادامه میدهند.
مقابله با DNS Rebinding و استخراج دادهها
خواندن دادهها به اندازه نوشتن آنها خطرناک است، زیرا اجازه استخراج تاریخچه گفتگوها (Transcript Exfiltration) را میدهد. بررسیها نشان داد دیمونها، تاریخچه گفتگوها و یک جریان رویداد زنده (Live Event Stream) را روی متد GET سرویس میدادند که بدون نیاز به شل، بهصورت cross-origin قابل خواندن بود. راهکار، اعمال درگاه Origin روی تمام مسیرهای خواندن بود؛ اگر یک مسیر باعث نشت وضعیت (State) شود، باید مانند مسیرهای نوشتن، محافظت شود.
برای توقف DNS Rebinding — جایی که یک صفحه مخرب، دامنه evil.com را به ۱۲۷.۰.۰.۱ متصل میکند — مسیر لوپبک اکنون هدر Host را تایید میکند. چون یک درخواست Rebinding همچنان نام میزبان (Hostname) خود را حمل میکند، هر درخواستی که Host آن لوپبک نباشد، رد میشود.
انتقال به محدودیتهای سطح سیستمعامل
به جای فیلتر کردن متن، agentproto اکنون با تنظیم shell: false و استفاده از یک آرایه argv دقیق در برابر یک لیست سفید «پیشفرض-مسدود» (Default-Deny) از باینریها اجرا میشود. این کار تزریق کد را بهطور ساختاری غیرممکن میکند، چون اصلاً شلی برای تزریق وجود ندارد. با این حال، اجازه دادن به مفسرهایی مثل bash یا python3 هنوز اجازه میدهد کدهای دلخواه فایلهای حساس مثل ~/.ssh/id_rsa را بخوانند.
برای حل این مشکل، اجرای دستورات دارای یک سندباکس اختیاری (Opt-in) شد:
- macOS Seatbelt: محدود کردن آنچه پروسه میتواند بخواند و بنویسد.
- Linux bubblewrap: استفاده در کانتینرها برای محدود کردن فضای کاری و استفاده از
--unshare-netبرای مسدود کردن سوکتهای شبکه.
اثبات مرزهای امنیتی
در متدولوژی agentproto، یک سندباکس تنها زمانی یک کنترل امنیتی است که مشاهده شده باشد در یک پروسه واقعی، دسترسی به چیزی را رد کرده است. پیش از نوشتن کد، نویسنده این مرزها را تایید کرد:
- تست Seatbelt: خواندن فضای کاری موفق بود اما دستور
cat ~/.ssh/id_rsaخطایOperation not permittedداد. - تست Bubblewrap: فضای کاری دیده میشد اما مسیر
~/.sshخطایENOENTداد (چون مونت نشده بود). همچنین با شبکه غیرمشترک (network unsharing)، تلاش برای اتصال سوکتی خطایENETUNREACHبازگرداند.
رویکرد محلیمحور
در نهایت، این تحلیل رفتارهای «گزارش به خانه» (phoning home) در ابزارهایی مثل opencode را نقد میکند که بهطور پیشفرض به مدلهای راه دور متصل شده و URLها را از شخص ثالث دریافت میکنند. agentproto رویکردی «بهطور-عمدی-ساده» (Boring-on-purpose) دارد:
- دیمون منحصراً به ۱۲۷.۰.۰.۱ متصل میشود، نه ۰.۰.۰.۰.
- بهطور خودکار با هیچ مدل راه دوری تماس نمیگیرد؛ کاربر باید آداپتور (محلی یا میزبانیشده) را انتخاب کند.
- «عمومی شدن» (Going Public) تنها یک دستور صریح است که یک توکن Bearer ایجاد کرده و تونل را محدود میکند. اگر یک تونل عبوری (Passthrough) نتواند محدود شود، دیمون اکنون این موضوع را صراحتاً در نتیجه اعلام میکند.
خلاصه بهبودهای امنیتی
این بازنگری جامع امنیتی در ۸ درخواست تغییر (PR) عمومی اعمال شد:
- PR #570: محافظت از مسیر
/mcpدر برابر حملات Drive-by مرورگر. - PR #571: مسدود کردن خواندنهای cross-origin، سختسازی CORS و حذف توکنها از لاگها.
- PR #572: رد نصبکنندههای غیرتعاملی
curl | bashدر محیطهای غیرتعاملی. - PR #573: سختسازی سیگنالهای لوپبک و علامتگذاری تونلهای بدون احراز هویت.
- PR #578, #581, #585: رفع خطرات مفسرها از طریق هشدارها و ایزولهسازی (Seatbelt/bubblewrap).
- PR #582: پیادهسازی محافظ Host برای مقابله با DNS-rebinding.
با نگاه به محیط اجرای عاملها بهعنوان یک شل راه دور، توسعهدهندگان میتوانند بار امنیتی را از «حدس زدن پروفایلهای متنی» به «حقوق اثباتشده سیستمعامل» و «وضعیت شبکه» منتقل کنند.
گام بعدی شما
- اگر از عاملهای کدنویسی محلی استفاده میکنید، بررسی کنید آیا به پورت ۰.۰.۰.۰ متصل هستند یا فقط ۱۲۷.۰.۰.۱.
- به جای تکیه بر فیلترهای متنی، از ابزارهایی استفاده کنید که از محیطهای ایزوله مثل Bubblewrap یا Seatbelt پشتیبانی میکنند.
- دسترسیهای فایل سیستم را برای دیمونهای هوش مصنوعی به حداقل (Least Privilege) برسانید.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما درباره تراشههای Blackwell مراجعه کنید.




گفتگو