درس Snowflake في GitHub Actions: عندما تصبح issue عامة مدخلاً إلى CI/CD
قضية Wiz Red Agent لا تثبت حدوث اختراق لعملاء Snowflake. إنها تنبيه هادئ إلى أن أحداث المستودعات العامة وأتمتة YAML والرموز الداخلية طويلة العمر تحتاج إلى ضوابط بمستوى الإنتاج.
لا ينبغي قراءة قضية Wiz و Snowflake كاختراق جديد لبيانات العملاء، ولا كدليل على أن أدوات البرمجة المعتمدة على AI خطرة بطبيعتها. الدرس العملي أضيق: يمكن أن تصبح issue عامة في GitHub مدخلاً لأتمتة داخلية، وإذا أُدرج هذا المدخل مباشرة داخل أمر shell في GitHub Actions فإنه لا يبقى نصاً فقط. تقول Wiz Research إن أداة Red Agent المستقلة وجدت workflow injection في المستودع العام snowflakedb/snowflake-connector-net، وفتحت issue معدّة بعناية، وتلقت callback من GitHub Actions runner، وحصلت على Jira API token. أصلحت Snowflake سير العمل، ودوّرت الرمز، ووفق المواد المنشورة لم تجد دليلاً على وصول غير مصرح به خارج البحث المصرح.

ما الذي حدث
البداية كانت أتمتة مألوفة. مستودع عام يربط GitHub issues بعمليات Jira داخلية عبر GitHub Actions. تستخدم فرق كثيرة هذا النوع من الربط لإنشاء تذكرة، أو مزامنة حالة، أو إرسال إشعار إلى Slack. يظهر الخطر عندما يعامل workflow النص القادم من مستخدم خارجي كأنه موثوق. عنوان issue، النص، اسم الفرع، عنوان pull request أو التعليق يمكن أن تكون كلها مدخلات غير موثوقة.
بحسب Wiz، وجد Red Agent مشكلة script injection في .github/workflows/jira_issue.yml. كان workflow يعمل عند issues: opened. وتقول Wiz إن عنوان issue الخاضع للمهاجم أُدخل مباشرة في كتلة shell من نوع run:. المحاولة الأولى أعطت خطأ bash، ثم عدّل agent طريقته وتلقى استجابة خارجية من runner تتضمن credentials مرمزة. كان Jira token يسجل الدخول باسم [email protected] إلى بيئة Atlassian الخاصة بـ Snowflake ويمنح قراءة لمشاريع هندسية ومشاريع امتثال أمني وتتبع bug bounty.
الخط الزمني مهم. تم دمج PR #1218 في 18 يونيو 2026. تقول Wiz إن Red Agent وجد المشكلة واختبرها وأبلغ عنها في 23 يونيو. تم دمج PR #1402 للتصحيح في اليوم نفسه، وتم تدوير الرمز في 24 يونيو. نُشر تحليل Wiz في 17 أغسطس، وغطته The Hacker News في 18 أغسطس مع توضيح النطاق: لم يُحدد إصدار متأثر من Snowflake Connector for .NET، ولم يظهر CVE أو إدراج CISA KEV، ولا يوجد دليل عام على اختراق عملاء.
لماذا يهم الأمر الآن
تجمع القصة اتجاهين. أصبحت code assistants جزءاً من العمل اليومي، وأصبحت المراجعات الأمنية الآلية تظهر في pull requests كثيرة. في الوقت نفسه تستطيع agents أمنية مستقلة قراءة مستودعات عامة، والتعرف إلى فئات أخطاء معروفة، وتجربة مسار، وملاحظة الفشل ثم التكيف. هذا لا يجعل كل agent مهاجماً خارقاً، لكنه يختصر الزمن بين الخطأ والدليل العملي.
الرد الناضج ليس منع Copilot ولا الثقة العمياء به. أي تغيير يمس .github/workflows أو scripts النشر أو cloud credentials أو Jira tokens أو توقيع الإصدارات أو نشر الحزم يجب أن يعامل ككود حساس أمنياً. تعليق bot لا يساوي مراجعة أمنية كاملة.
شرح workflow injection بلا وصف هجومي
يبقى النص الخارجي آمناً ما دام يعامل كنص. عنوان issue يصبح خطيراً عندما يوسعه workflow مباشرة داخل أمر shell. إذا احتوى النص على رموز تفسرها shell، فقد ينفذ runner شيئاً لم يقصده الكاتب.
النمط الآمن هو إبقاء القيم غير الموثوقة خارج نص الأمر. توضع في environment variables، وتُقتبس بشكل صحيح، وتمرر إلى الأدوات كبيانات، ويستخدم بناء منظم مثل jq --arg عند إنشاء JSON. وقد حذرت GitHub من أن contexts مثل عناوين issues وأسماء الفروع لا ينبغي توسيعها مباشرة داخل run:. هذه ليست مشكلة خاصة بـ Snowflake أو Jira؛ تظهر كلما خلط YAML الخاص بـ CI/CD بين metadata عامة و shell و secrets.
المستودعات العامة كسطح هجوم
المستودع العام ليس مكاناً لعرض الكود فقط. قد يكون باباً للأتمتة. issue جديدة أو تعليق أو label أو اسم فرع يمكن أن يشغل workflow على runner مستضاف أو داخلي. وقد يحمل هذا workflow رموزاً لـ Jira أو Slack أو سجلات الحزم أو خدمات cloud أو أدوات release.
لذلك فإن issues: opened ليس إشعاراً بسيطاً، بل مسار إدخال غير موثوق من الإنترنت. إذا لمس workflow رمز خدمة داخلياً، يصبح المستودع العام متصلاً ببنية الشركة. وحتى الرمز المخصص للقراءة فقط ليس بلا قيمة: قد يكشف Jira حالة الثغرات، وملاحظات triage، وأسماء داخلية، ومعلومات امتثال، وخريطة للأنظمة. بالنسبة لمهاجم حقيقي، هذه معلومات تشغيلية.
أين تدخل AI في القصة
زاوية AI حقيقية لكنها تحتاج دقة. ربطت Wiz القصة في البداية بـ pull request ساعد فيه Copilot وبأداة Red Agent المستقلة. ثم أوضحت أن Copilot كان co-author أو checker في PR المدمج واعتبره سليماً، لكن الأدلة العامة لا تثبت أن Copilot كتب الأسطر الضعيفة نفسها. الخلاصة المسؤولة ليست “Copilot صنع الثغرة”، بل أن المساعدة الآلية لم تمنع فئة معروفة من أخطاء CI/CD.
Red Agent يوضح الجانب الآخر. الأدوات المستقلة المصرح بها تستطيع تطبيق فئات قديمة من الأخطاء على مستودعات جديدة بسرعة. على المدافعين أن يتوقعوا فحص الأتمتة العامة بشكل أسرع وأكثر استمراراً.
ليست قصة اختراق عملاء، لكنها مهمة
لا تظهر المواد العامة اختراقاً لبيانات عملاء Snowflake. ذكرت THN أن الضعف كان محصوراً في أتمتة CI/CD للمستودع، وأنه لم يُحدد إصدار متأثر من connector. تقول Wiz إن Snowflake راجعت logs وإن Wiz كان الفاعل الوحيد أثناء نافذة التعرض. وتم تدوير token.
هذا يحدد النطاق ولا يلغي الدرس. انكشاف secret في CI/CD مهم حتى إذا وجده باحث مصرح وتم إصلاحه بسرعة. قراءة Jira الداخلي قد تكشف أولويات هندسية، وحالة ثغرات، وسياق امتثال، ومسارات لهجمات لاحقة.
ضوابط عملية
ابدأوا بجرد workflows، خصوصاً تلك التي تعمل عند issues و issue_comment و pull_request و pull_request_target و discussion أو عند إدخال يدوي. سجلوا أي secrets تراها، وأي أنظمة تستدعيها، وأين تعمل. ابحثوا عن توسيع مباشر لقيم GitHub context داخل run: مثل عنوان issue، نص issue، اسم branch، عنوان PR والتعليقات.
قللوا الصلاحيات. اضبطوا permissions صراحة. لا تمنحوا secrets ل workflows triggered by public events إلا عند الضرورة. استخدموا OIDC و credentials قصيرة العمر وحسابات خدمة محدودة النطاق. ضعوا الخطوات ذات الامتياز وراء موافقة maintainer أو خدمة وسيطة تتحقق من البيانات. اطلبوا code-owner review لكل .github/workflows/** و release scripts و deployment scripts. احتفظوا بسجلات كافية لربط استخدام token بتشغيل workflow.
Governance للتغييرات بمساعدة AI
التغييرات التي تولدها أو تراجعها AI تحتاج سياسة مبنية على المخاطر. وضع label يساعد في التدقيق، لكنه لا يكفي. إذا لمس التغيير CI/CD أو الهوية أو secrets أو release أو مسارات بيانات العملاء، فيجب أن يراجعه إنسان مسؤول عن هذه المنطقة، مع checks آلية مناسبة لنوع الملف.
الخلاصة هادئة: AI لا يلغي أساسيات AppSec، بل يسرع الطرفين. قد يصبح الزمن بين merge ضعيف ودليل عملي أياماً أو ساعات. YAML الخاص بـ CI/CD هو كود إنتاج يحمل secrets. Public issues هي user input. والمدخلات تحتاج حدوداً، والرموز تحتاج نطاقاً، والأتمتة تحتاج مالكاً واضحاً.
Comments
Sign in to comment.
No comments yet.