یک سند مسموم در یک پایگاه داده بازیابیافزا میتواند یک عامل هوش مصنوعی را به یک کنسول دستورات از راه دور تبدیل کند، به شرطی که برنامه به خروجی مدل اعتماد کند. این درس سختگیرانه، نتیجه کشف دو آسیبپذیری بحرانی در Semantic Kernel متعلق به شرکت مایکروسافت در می ۲۰۲۶ است.
برای اکثر توسعهدهندگان، امنیت هوش مصنوعی تاکنون به معنای مهندسی پرامپت (Prompt Engineering) — یعنی هنر سؤال درست پرسیدن، شبیه کسی که میداند چطور از یک مشاور باتجربه بهترین جواب را بگیرد — بوده است تا مدل را فریب دهند دستورات سیستمی را نادیده بگیرد. اما این نقصهای امنیتی (CVEs) ثابت میکنند خطر واقعی فریب خوردن مدل نیست؛ بلکه این است که برنامه هر آنچه مدل تولید میکند را کورکورانه میپذیرد.
تصور کنید یک عامل (Agent) شبیه پذیرشگری است که مجموعهای از کلیدها را در اختیار دارد. تزریق پرامپت (Prompt Injection) مثل این است که پذیرشگر را فریب دهید تا کلیدی به شما بدهد. شکست امنیتی زمانی رخ میدهد که قفلهای ساختمان چنان ضعیف باشند که آن کلید تمام درها، حتی اتاق سرور را باز کند.
همانطور که در تحلیلهای قبلی ما دربارهی امنیت مدلهای بازمتن اشاره کردیم، اعتماد به لایه تولید محتوا بدون داشتن لایه اعتبارسنجی، ریسکهای سیستمی ایجاد میکند. در همین راستا، برای پیادهسازی عملیاتی این مفاهیم، چهار لایه دفاعی برای مهار تزریق پرامپت در عاملهای TypeScript را بررسی کردهایم که ساختاری مشابه برای محدود کردن دسترسیهای مدل ارائه میدهد.
به نقل از تیم تحقیقات امنیتی Microsoft Defender، اولین آسیبپذیری (CVE-2026-26030) در بخش فیلتر کردن ذخیرهساز برداری رخ داد. سیستم عبارات لامبدا را با استفاده از مقادیر تحت تأثیر مدل میساخت و آنها را مستقیماً به تابع eval() در پایتون میفرستاد.
زنجیره حمله به این شکل بود:
- یک سند تحت کنترل مهاجم از طریق تولید بازیابیافزا (RAG) — شبیه دانشآموزی که قبل از جواب دادن، اول کتاب درسی را باز میکند و از آن نقل میآورد — بازیابی میشود.
- مدل زبانی بزرگ (LLM) — مثل کتابخانهداری که میلیاردها صفحه را خوانده و حالا با همان لحن جواب میدهد — این سند را پردازش کرده و دادههای فیلتر را تولید میکند.
- این دادهها به یک عبارت پویا تبدیل میشوند.
- برنامه تابع
eval()را اجرا میکند و منجر به اجرای کامل کد روی سیستم میزبان میشود.

محققان مایکروسافت ثابت کردند که این مسیر خاص میتواند منجر به اجرای کامل کد روی میزبان شود که عامل روی آن در حال اجراست. شکست در نقطهای رخ داد که مدل خروجی خود را تولید کرده بود؛ دادههای تحت کنترل مدل بدون مرزی محکم، وارد عملکردهای مورد اعتماد برنامه شدند.
دومین آسیبپذیری (CVE-2026-25592) نتیجه یک افشای تصادفی بود. Semantic Kernel متدی داخلی به نام DownloadFileAsync داشت که با پلاگین اجرای پایتون آن مرتبط بود. این متد به اشتباه به عنوان یک KernelFunction علامتگذاری شده بود و در نتیجه برای مدل به عنوان یک ابزار قابل فراخوانی بود.
وقتی مدل به این ابزار دسترسی پیدا کرد، توانست مسیر مقصد دانلود را تحت تأثیر قرار دهد. محققان ثابت کردند که یک کد مخرب (Payload) میتواند مستقیماً در پوشه Startup ویندوز نوشته شود تا در اولین ورود کاربر، اجرا گردد. با وجود تفاوت در نوع اشتباهات پیادهسازی بین این دو CVE، ریشه مشکل در تستها یکسان بود: مقداری که مدل کنترل میکرد، به قابلیتی با پیامدهای خطرناک روی میزبان رسید.
این حوادث ثابت میکند که یک LLM مقادیر تولید شده را پاکسازی یا مجوزدهی نمیکند. اگر یک عامل ابزاری مثل def search_hotels(city: str): ... دارد، تستهای معمولی فقط بررسی میکنند که کلمه «پاریس» درست کار کند، نه اینکه اگر مدل یک رشته مخرب فرستاد چه اتفاقی میافتد.
تیمهای مهندسی باید با هر آرگومانی که مدل کنترل میکند، طوری برخورد کنند که انگار از یک API عمومی وارد شده است. هر مقداری که مدل تولید میکند باید تا زمان اعتبارسنجی، «نامعتبر» تلقی شود.
به جای تست اینکه آیا مدل حمله را تشخیص میدهد یا خیر، توسعهدهندگان باید از «تستهای منفی» استفاده کنند تا ثابت کنند خروجی خصمانه نمیتواند اثر جانبی خطرناکی داشته باشد. برای پارامتر شهر، باید مواردی مثل:
- رشتههای خالی (
"") - تلاش برای دسترسی به مسیرهای سیستمی (
"../../../tmp/payload") - دسترسی به کلاسهای پایتون (
"__class__") - وارد کردن ماژولها (
"__import__('os')") - نحوهای غیرمنتظره در عبارات (Expression Syntax)
تست شوند. هدف این است که ثابت شود فارغ از آنچه مدل میفرستد، هیچ پردازشی ایجاد نمیشود، هیچ فایل غیرمنتظرهای نوشته نمیشود و هیچ مفسری فراخوانی نمیگردد.
تست برای تزریق پرامپت ذاتاً غیرقطعی است. مدل ممکن است امروز حمله را رد کند اما فردا به دلیل تغییر اندک در دمای (Temperature) مدل، بهروزرسانی پرامپت، یا تغییر در رفتار نمونهبرداری (Sampling)، تسلیم شود. بنابراین نمیتوان آن را کنترل امنیتی اصلی قرار داد.
در عوض، توسعهدهندگان باید از «تستهای مرزی» استفاده کنند که مدل را کاملاً دور میزنند. با تزریق مستقیم آرگومانهای خصمانه به لایه ابزار — با استفاده از یک تابع کمکی مانند invoke_as_model(tool, arguments) — تیمها میتوانند تستهای CI/CD قطعی ایجاد کنند.
برای مثال، اگر شرط امنیتی این است که مقادیر مدل هرگز نباید کد اجرا کنند، نیازی نیست مدل را متقاعد کنید حمله تولید کند؛ فقط یک آرگومان مخرب را از طریق لایه ابزار عبور دهید و بررسی کنید که برنامه خطای InvalidToolArgument بدهد. این روش پوششی قطعی از مرزهای برنامه فراهم میکند که به «خلقوخوی» یا نسخه فعلی مدل وابسته نیست.
آسیبپذیری CVE-2026-25592 بر یک نکته حیاتی تأکید دارد: تأیید دقیق توابعی که مدل اجازه فراخوانی آنها را دارد. تابعی مثل download_file(remote_path, local_path) وقتی توسط منطق مورد اعتماد برنامه فراخوانی شود امن است، اما لحظهای که در دسترس LLM قرار گیرد، به یک حفره امنیتی بحرانی تبدیل میشود.
برای جلوگیری از این اتفاق، تیمها باید تستهای قابلیت را در خط لوله CI اجرا کنند:
- ممیزی رجیستری: استفاده از تستها برای اطمینان از اینکه توابع خطرناک (مانند
download_file) در لیستget_model_callable_tools()حضور ندارند. - تستهای محصورسازی: اگر نوشتن فایل ضروری است، ثابت کنید عامل نمیتواند از فضای کاری خود خارج شود. برای مثال، یک تست باید تأیید کند که تلاش برای نوشتن در
../../startup/payload.pyخطایInvalidPathایجاد میکند.
برای اجرای درست این مورد، نباید صرفاً رشتههای حاوی .. را رد کرد. در عوض، توسعهدهندگان باید ابتدا مسیر نهایی را تحلیل (Resolve) کنند و سپس با استفاده از یک تابع اعتبارسنجی که target.parents را با ریشه تعیینشده مقایسه میکند، بررسی کنند که مقصد نهایی همچنان درون دایرکتوری مجاز باشد.
برای ایمنسازی یک عامل، توسعهدهندگان باید از «مقاصد خطرناک» (Dangerous Sinks) به عقب حرکت کنند. اینها عملیاتی هستند که واقعاً میتوانند به سیستم آسیب بزنند. تیمها باید در کل پشتهی عامل خود به دنبال موارد زیر بگردند:
- توابع
eval()وexec() - دستورات
subprocessوos.system() - خواندن و نوشتن در سیستم فایل
- اجرای دستورات پایگاهداده
- درخواستهای HTTP و APIهای ابری
- دسترسی به اعتبارنامهها (Credentials)
- عملیات ایمیل، پیامرسانی و استقرار (Deployment)
با ردیابی جریان داده از این مقاصد به عقب، میتوان هر مسیری را که خروجی مدل بر آن اثر میگذارد شناسایی کرد. این همان تحلیل «ورودی آلوده» (Tainted-Input Analysis) است. حضور LLM در وسط این جریان، داده را قابل اعتماد نمیکند. در مورد Semantic Kernel، یک سند مخرب مستقیماً eval() را صدا نزد؛ بلکه مدل را تحت تأثیر قرار داد، مدل دادههای برنامه را تحت تأثیر قرار داد و برنامه هم به آن اعتماد کرد.
این یک استراتژی دفاع لایهای ایجاد میکند:
۱. دفاعات پرامپت: متوقف کردن حمله در مراحل اولیه (احتمالاتی).
۲. اعتبارسنجی ابزار: مسدود کردن آرگومانهای خصمانه (قطعی).
۳. مجوزدهی: جلوگیری از عملیات حساس (قطعی).
۴. محدودیت قابلیتها: محدود کردن دسترسیهای مدل (قطعی).
۵. سندباکسینگ: محدود کردن شعاع تخریب در صورت شکست تمام لایهها (قطعی).
طراحی تستها بر اساس ناورداهای (Invariants) برنامه، مشکل مهاجرت مدل را نیز حل میکند. اگر تیمی از GPT-4 به Claude 3.5 کوچ کند، مجموعه تستهای تزریق پرامپت احتمالاً رفتار متفاوتی خواهد داشت. اما تأییدات مبتنی بر مرزهای برنامه ثابت میمانند:
assert model_cannot_invoke(forbidden_tool)assert hostile_argument_cannot_trigger(code_execution)assert file_write_remains_inside(allowed_directory)assert sensitive_operation_requires_authorization()
این تستها متعلق به برنامه هستند، نه یک مدل خاص. تزریق پرامپت مسیر را باز میکند، اما مرز ابزار است که میزان اثرگذاری را تعیین میکند. برای هر عاملی با قابلیتهای واقعی، شالوده CI باید تأیید رجیستری ابزارها، تلقی کردن تمام آرگومانهای مدل به عنوان ورودی خصمانه و اثبات غیرممکن بودن اثرات جانبی خطرناک باشد.
تحقیقات مایکروسافت بر روی Semantic Kernel اهمیت دارد چون با آسیبپذیریهای واقعی در یک فریمورک واقعی سروکار داشت، نه نمودارهای فرضی. CVE-2026-26030 نشان داد دادههای تحت تأثیر مدل به eval() میرسند و CVE-2026-25592 خطر افشای تصادفی قابلیتهای سمت میزبان را نشان داد.
درس مهندسی ساده است: مدل را به عنوان مرز امنیتی نبینید. برنامه را طوری تست کنید که انگار مدل همین حالا هک شده است، سپس ثابت کنید قابلیتهای آن همچنان محدود است. این تنها تستی است که به شما میگوید آیا بقیه سیستم واقعاً از شما محافظت میکند یا خیر.
گام بعدی شما
- تمام توابعی که در دسترس مدل قرار دادهاید را ممیزی کنید و توابع با دسترسی سیستمی (مانند نوشتن فایل یا اجرای دستور) را حذف یا محدود کنید.
- تستهای CI/CD خود را از حالت «تلاش برای فریب دادن مدل» به «تزریق مستقیم ورودی مخرب به ابزار» تغییر دهید.
- برای هر ابزاری که مسیر فایل میگیرد، از اعتبارسنجی مسیرهای کانونی (Canonical Path) استفاده کنید تا از خروج از دایرکتوری مجاز جلوگیری شود.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو