يتلقى روبوت محادثة للدعم الفني خاص بالمستأجر acme تذكرة تطلب استرداد مبلغ مالي. يرسل المتصل نص محادثة فقط، ومع ذلك تسمح واجهة برمجة تطبيقات المساعدة (assist-api) للنموذج بإنشاء طلب payments.refund (استرداد مدفوعات) وإرسال هذا الطلب باستخدام صلاحيات الدفع الواسعة الممنوحة للخدمة. ونتيجة لذلك، يُصدر النظام الخلفي مقترحاً لاسترداد مبلغ لم يكن المستخدم u_123 يملك الصلاحية لطلبه أصلاً. لم يتطلب الأمر سيناريوهات معقدة؛ فقد انتقل نص غير موثوق من رسالة المتصل ليتحول إلى إجراء فعلي، في حين لم يكن النموذج يملك الصلاحية لتقرير ما إذا كان هذا الإجراء مسموحاً به أم لا.
تُعد ضوابط الحماية (Guardrail) نقطة تحكم تفرض قيوداً على ما يقبله تطبيق النماذج اللغوية الكبيرة (LLM) أو ينفقه أو يعيده أو ينفذه. في حالة الفشل هذه، يتمثل أبسط ضابط حماية مفيد في رفض طلب الاسترداد ما لم يكن الطرف المُصادق عليه يمتلك النطاق (scope) المطلوب، وما لم تقبل بوابة الموافقة من جانب الخادم معايير الاسترداد الفعلية. لا يمكن لصياغة “المطالبة” (prompt) توفير هذه الحماية لأن النموذج يتبع النص الذي يصله؛ فهو لا يقوم بمصادقة المتصلين، ولا يدير الميزانيات، ولا يمنح صلاحيات استخدام الأدوات.
يحتوي النظام قيد التشغيل على مسار واحد سنبقيه دون تغيير. ينتمي المستخدم النهائي u_123 إلى المستأجر acme ويقوم باستدعاء assist-api عبر بوابة النماذج اللغوية (llm-gateway). تقوم خدمة FastAPI بتجميع المطالبة (prompt)، واستدعاء المزود providerA عبر مسار المحادثة (chat) باستخدام النموذج $CHAT_MODEL؛ وقد تطلب الخدمة تنفيذ إجراء بواسطة أداة ما. يمتلك المستخدم u_123 صلاحيات chat:invoke و payments:refund:propose فقط، ولا يمتلك صلاحيات دفع غير مقيدة.
تظل اتفاقية الدفع محددة وواضحة؛ فالأداة الوحيدة المتعلقة بالدفع هي payments.refund، وتتطلب المعاملات التالية: invoice_id (مثل inv_987)، و amount_cents كعدد صحيح (مثل 1299)، و reason (السبب) كنص (string). إن مجرد اقتراح استرداد المبلغ لا يعني الحصول على إذن بتنفيذه فعلياً؛ إذ يتحقق الخادم من ملكية المستأجر، والنطاق، والمعاملات، والموافقة قبل تنفيذ أي إجراء دفع لا يمكن التراجع عنه.
تُعتبر أي نقطة تداول للنصوص غير موثوقة، بما في ذلك رسالة المتصل، والمستندات المسترجعة، ونتائج الأدوات، ومخرجات النموذج. فقد يحتوي مستند الدعم المسترجع على تعليمات تتعارض مع سياسة التطبيق، كما قد تحتوي مخرجات النموذج على حقول تصبح غير آمنة إذا مُررت إلى واجهة برمجة تطبيقات الدفع دون التحقق من صحتها. تندرج هذه الحالة تحت ثغرة “حقن المطالبات” (Prompt Injection) المصنفة بـ LLM01 ضمن قائمة OWASP لأهم 10 مخاطر أمنية لتطبيقات LLM لعام 2025، والتي نشرها مشروع أمان الذكاء الاصطناعي التوليدي (GenAI Security Project) التابع لـ OWASP في نوفمبر 2024. والقاعدة الثابتة هنا واضحة: لا يجوز تنفيذ أي استدعاء لأداة بصلاحيات تفوق تلك التي منحها المستخدم u_123 لهذا الاستدعاء.
يضع المسار الثابت المدخلات غير الموثوقة وحدود الإنفاذ في نطاق رؤية واحد.
تحدد البوابة هوية الجهة المستدعية، بينما تتولى assist-api فرض قيود المستأجر (tenant) ونطاقات الصلاحية (scopes) وعقد الأداة ومتطلبات الموافقة الخاصة بالمستخدم. يقوم المزود providerA بتوليد المخرجات باستخدام بيانات اعتماده الخاصة، ولكن لا يجوز بأي حال أن تمنحه بيانات الاعتماد هذه صلاحية إجراء استرداد مالي (refund) نيابة عن المستخدم u_123. إن استخدام الصلاحيات الأوسع الممنوحة للخدمة لتنفيذ إجراء لمستخدم لا يملك تلك الصلاحيات يؤدي إلى ظهور ثغرة “الوكيل المرتبك” (Confused Deputy).
قاعدة الحدود
قد يقترح النموذج إجراء
payments.refund(استرداد مالي)، ولكن عمليات التحقق التي تتم من جانب الخادم (server-side) هي وحدها التي يمكنها التصريح بهذا الإجراء أو تنفيذه.
نظراً لأن لكل حدّ (boundary) وظيفة مختلفة، يجب أن يحدد الرفض المرحلة التي تعذر استمرار العمل فيها بأمان. تُرجع البوابة llm-gateway الرمز 401 Unauthorized (غير مصرح به) في حال كانت بيانات الاعتماد مفقودة أو غير صالحة أو ملغاة أو مخترقة. وبعد إتمام المصادقة، تُرجع البوابة أو التطبيق الرمز 403 Forbidden (ممنوع) إذا كان المستدعي يفتقر إلى نطاق صلاحية مطلوب. كما يتم إرجاع الرمز 403 Forbidden عند محاولة جلب أداة من وجهة محظورة، وفي هذه الحالة لا يتم الاتصال بتلك الوجهة المحظورة مطلقاً.
بعد استلام الرد من providerA، تقوم assist-api بالتحقق من صحة مخرجات النموذج قبل أن يتلقاها المحلل (parser) أو واجهة برمجة تطبيقات الدفع أو أي وجهة معالجة لاحقة. تؤدي المخرجات غير المتوافقة مع المخطط (schema) إلى إرجاع الرمز 422 Unprocessable Content (محتوى غير قابل للمعالجة)، وهي العبارة المعتمدة في معيار RFC 9110 والتي كانت تُعرف في الوثائق القديمة باسم “Unprocessable Entity” (كيان غير قابل للمعالجة). كما تؤدي إعادة استخدام مفتاح ضمان التكرار الآمن (idempotency key) مع معاملات استرداد مختلفة إلى إرجاع الرمز 422 Unprocessable Content؛ بينما تؤدي إعادة استخدام المفتاح نفسه مع بقاء الطلب الأول نشطاً إلى إرجاع الرمز 409 Conflict (تعارض).
تصف النتائج المتبقية حدوداً تشغيلية بدلاً من كونها قراراً صادراً عن النموذج.
202 Accepted (مقبول) عند تعليق عملية استرداد غير قابلة للتراجع بانتظار الموافقة، مع توفير مُعرِّف لحالة “بانتظار الموافقة”.429 Too Many Requests (طلبات كثيرة جداً) مرفقاً بترويسة Retry-After عند استنفاد الحصة المشتركة أو تجاوز حد معدل الطلبات.503 Service Unavailable (الخدمة غير متاحة) عندما يكون مخزن قواعد الإنفاذ غير متاح ولا يستطيع التطبيق فرض السياسة بأمان.504 Gateway Timeout (انقضاء مهلة البوابة) عندما يتجاوز providerA المهلة الزمنية المحددة لاستدعاء المزود.تمنع هذه النتائج العملاء من اعتبار الرفض مجرد فشل غامض في النموذج. كما أنها توضح مكان إجراء التحقيق، سواء كان الخلل يتعلق بالتحقق من الهوية عند llm-gateway، أو عملية التحقق من الصحة في assist-api، أو استدعاء للمزود لم يكتمل.
في حالة الفشل الأولية، لا يملك المهاجم سوى رسالة دردشة، ومع ذلك يتسبب في طرح مقترح لإجراء استرداد مالي غير قابل للتراجع. أي مرحلة ينبغي أن ترفض الطلب أولاً: أ) مصادقة المُستدعي وربط المستأجر (tenant binding) عند llm-gateway؛ ب) تخويل الأداة والموافقة عليها عند assist-api؛ أم ج) التحقق من المخرجات بعد معالجة النموذج؟
[المصادر][/المصادر]