رسم توضيحي تجريدي مُولَّد على مساحة داكنة بلون الأردواز: يمتد شريط أفقي طويل من خطوط ضوء رفيعة بلون سماوي شاحب وكهرماني من الحافة إلى الحافة، وينقطع عند نقطة واحدة محددة قرب المركز، وتنفلت شظية كهرمانية ساطعة واحدة نحو الأعلى داخل قناة داكنة فارغة فوقه؛ وتوحي دوائر باهتة متحدة المركز وخطوط شبكة مسطّرة بوجود خط أنابيب. لا تظهر أي نصوص أو أشخاص أو شعارات مؤسسات. شعار OrcaRouter مركّب في الزاوية السفلية اليمنى.
AI Safety Incidents

رمز Jira الخاص بـ Snowflake: ثغرة شارك Copilot في التوقيع عليها، ويقول GitHub إن الإنسان كتبها

الكاتب

Gideon Frost

تاريخ النشر

أحدث النماذج · 20عرض جميع النماذج →
المعايير: Artificial Analysis · يُحدَّث يوميًا
العودة إلى جميع المقالات

في 23 يونيو 2026، فتح Red Agent، وهو وكيل أمني مستقل طوّرته Wiz، بلاغًا على مستودع GitHub عام مملوك لـ Snowflake وعاد حاملًا بيانات اعتماد. كان المستودع snowflakedb/snowflake-connector-net، وكان سير العمل المسؤول .github/workflows/jira_issue.yml موجودًا لإنشاء تذكرة Jira كلما فتح أي شخص بلاغًا — فقد أدرج عنوان التذكرة داخل أمر shell بدلًا من تمريره عبر متغير بيئة، لذا نُفّذ عنوان مُصمَّم على نحو خبيث كشيفرة على مشغّل GitHub Actions. وكان الرمز الذي استعاد Red Agent يصادق بصفته qa@snowflake.net أمام snowflakecomputing.atlassian.net، ويمنح صلاحية قراءة إلى مشاريع Jira الخاصة بالهندسة والامتثال الأمني ومكافآت الثغرات لدى Snowflake. ظلت الثغرة قائمة لمدة خمسة أيام. نشرت Wiz تحليلها الكامل في 17 أغسطس 2026. صُنّفت هذه الحادثة ضمن السجل 2026-08-17-snowflake-jira-zhao-dao-can في Orca AI Incident Archive، الذي يضم مجموعة السجلات الكاملة بدرجات الثقة والمصادر المستشهد بها.

الاستيفاء، والحارس الذي لم يُنفَّذ قط

تم تشغيل سير العمل عند حدث GitHub "issues: opened". كان بإمكان أي شخص لديه حساب GitHub تشغيله عبر فتح issue على مستودع عام — دون دعوة، أو دور maintainer، أو fork. قرأت الخطوة المعرّضة للثغرة عنوان الـ issue إلى متغير shell: TITLE=$(echo '${{ github.event.issue.title }}' | sed ...)، مع مرشّحين اثنين كانا يهدفان إلى تهريب علامتَي الاقتباس المزدوجة والمفردة قبل تجميع السلسلة.

الخلل في ترتيب العمليات، وليس في التهريب. يستبدل GitHub محتويات التعبير في نص السكربت قبل أن يحلّل bash ذلك إطلاقًا، لذا فإن علامة اقتباس مفردة داخل عنوان issue تغلق السلسلة المقتبسة التي يبقيها echo مفتوحة. ويعمل مرشحا sed داخل السكربت نفسه، بعد الاستبدال، ولا يستطيعان إصلاح اقتباس غيّر بالفعل كيفية تحليل السطر. ويوضح تقرير Wiz صراحةً أن التهريب يأتي متأخرًا جدًا لمنع الاختراق، وأن عنوانًا مصنوعًا باستخدام علامة اقتباس إغلاق وفاصلة منقوطة يلحق أوامر من اختيار المهاجم بخطوة التشغيل.

كان من المفترض أن يضيّق ضابط تحكم ثانٍ نطاق الجمهور المستهدف، لكنه لم يفعل. كانت المهمة تحمل شرط if يقارن github.event.pull_request.user.login باسم تسجيل الدخول الخاص ببوت whitesource-for-github-com، على ما يبدو لمنع طلبات السحب الآلية الخاصة بالتبعيات من إنشاء تذاكر. في حدث issues لا يوجد كائن طلب سحب على الإطلاق، لذا تتم المقارنة مع خاصية null. وثّق GitHub نفسه، في نص اقتبسته The Hacker News، أن فك الإشارة إلى خاصية غير موجودة يُقيَّم إلى سلسلة نصية فارغة؛ ويصل تحليل Wiz إلى النتيجة نفسها عبر قيمة null. وفي كلتا الحالتين قُيِّم الشرط بأنه صحيح لكل مستخدم، فتحوَّل الاستثناء الخاص بالبوت إلى ممر عبور للإنترنت.

ما جعل هذا الحقن جديرًا بالإبلاغ بدلًا من أن يُعدّ أمرًا روتينيًا هو ما صاحبه. فقد احتُفظ في الخطوة نفسها بـ JIRA_BASE_URL وJIRA_USER_EMAIL وJIRA_API_TOKEN كمتغيّرات بيئية، فكان تنفيذ أوامر عشوائية على مشغّل التشغيل يضع بيانات اعتماد في متناول اليد بدلًا من أن يكون على أرضية خالية. ولم يُحدَّد أي إصدار من Snowflake Connector for .NET بوصفه متأثرًا: إذ كان الضعف كامنًا في أتمتة CI/CD الخاصة بالمستودع، لا في شيفرة الموصل المُسلَّمة.

ما الذي أخذته Red Agent، وما تقول إنها تخلصت منه

رواية Wiz عن الاستغلال هي ما يميّز هذا عن مجرد نتيجة ماسح ضوئي. استخدمت الحمولة الأولى محرف #، الذي حوّل قوس الإغلاق في الإسناد TITLE=$(...) إلى تعليق وأنتج خطأ نحويًا في bash بدلًا من استدعاء عكسي. قرأ الوكيل الخطأ وأعاد كتابة الحمولة لإغلاق كتلة shell بفاصلة منقوطة وعلامة اقتباس جديدة لأمر echo، ثم تلقّى استدعاءً خارج النطاق. استخدمت الحمولة curl للوصول إلى نطاق فرعي من oast.me بقيم مشفرة بـ base64 للمتغيرات الثلاثة لبيانات الاعتماد، ووصل الاستدعاء العكسي من عنوان IP الخاص بـ Azure 20.106.182.197، وهو عنوان تنسبه Wiz إلى منفّذ GitHub Actions.

الرمز الذي أعاده كان رمز API خاصًا بـ Jira للحساب qa@snowflake.net، ويصف Wiz مدى وصوله بأنه وصول قراءة يشمل مشاريع الهندسة والامتثال الأمني وتتبّع مكافآت الثغرات على نسخة Atlassian السحابية الخاصة بـ Snowflake. هذا هو الضرر الذي يوثّقه الأرشيف: ليس تنفيذ شيفرة على آلة بناء لمدة خمسة أيام، بل بيانات اعتماد كانت تستطيع قراءة قوائم انتظار التذاكر التي تُسجّل فيها الثغرات الهندسية والأمنية غير المُصلحة — بما في ذلك، بحسب وصف Wiz، متعقّب مكافآت الثغرات.

A self-built HTML card titled 'What the run step could reach', badged 'snowflakedb/snowflake-connector-net · .github/workflows/jira_issue.yml · 18-23 June 2026'. A left panel lists the environment variables held by the step: JIRA_BASE_URL, JIRA_USER_EMAIL, JIRA_API_TOKEN. A right panel reads: identity qa@snowflake.net; Jira host snowflakecomputing.atlassian.net; access, read across engineering, security-compliance and bug-bounty Jira projects. Three tiles read: trigger 'issues: opened'; account required 'any GitHub user'; token rotated '24 June 2026'. A footer cites Wiz Research, published 17 August 2026, and notes no CVE identifier accompanies the flaw.

تقول Wiz إنها حذفت بأمان كل ما وصلت إليه أثناء إثبات المفهوم. وقالت Snowflake، في بيان إلى CSO Online، إن التقرير «تم التحقيق فيه ومعالجته على الفور» وإن «تحقيقنا لم يجد أي دليل على وصول غير مصرح به»؛ وتضيف مدونة Wiz أن Snowflake راجعت سجلات التدقيق لنافذة الخمسة أيام ولم تجد أي استخدام من طرف ثالث يتجاوز عناوين الاختبار الخاصة بـ Wiz. ولم تنشر Snowflake تلك السجلات، لذا فإن الاستنتاج القائل بعدم وجود فاعل آخر يعتمد على روايتها وعلى ملخص Wiz لها، لا على وثائق يستطيع أي شخص خارج المؤسستين قراءتها.

من كتب السطر المعرّض للثغرة؟

أنتج ذلك السؤال القصة الثانية الأكبر. دُمج طلب السحب PR #1218، المعنون "SNOW-2069227: Update jira workflows"، دمجًا سحقيًا (squash) في 18 يونيو 2026 بصفته commit 4a1b8ce، ويُدرج commit الدمج السحقي Copilot Autofix powered by AI ضمن مؤلفيه المشاركين. استند عنوان Wiz الأصلي إلى ذلك تحديدًا، إذ وصف العيب بأنه كامن في طلب سحب مدعوم من GitHub Copilot، وسارت التغطية الصحفية المتخصصة المبكرة على المنوال نفسه — جاء عنوان SC Media على النحو التالي: "Wiz agent finds Snowflake repo flaw in code co-authored by GitHub Copilot Autofix".

موقف GitHub، كما أوردته The Next Web ولخّصته مذكرة بحثية صادرة عن Cloud Security Alliance، هو أن مراجعته الداخلية وجدت أن «إنسانًا كتب المساهمات التي أدت إلى الثغرة»، وأن Copilot Autofix «لم يراجعها ولم يسهم فيها». والأساس التقني لذلك التفنيد موجود في تاريخ git. فالدمج بنمط squash يطوي طلب pull request في commit واحد وينقل كل trailer خاص بالمؤلفين المشاركين إلى الأمام بصرف النظر عن الأسطر التي لمسها ذلك المؤلف، لذا فإن سطر المؤلف المشارك يوثّق المشاركة في طلب pull request، لا تأليف قطعة تغييرات معينة (hunk). وقد غيّر الـcommit الذي شارك Copilot في تأليفه ضمن طلب pull request نفسه، 6d0e2fa، الملف jira_close.yml — وهو workflow مختلف عن jira_issue.yml المعرّض للخطر. ويُنسب الإدراج غير الآمن إلى commit 094038e، المؤرخ 25 أغسطس 2025 والذي تنسبه GitHub إلى مهندس في Snowflake يُدعى sfc-ghpathak؛ وقد أدخل PR #1218 ذلك النمط إلى الفرع الافتراضي في يونيو 2026.

لم تسحب Wiz الاكتشاف، وغيّرت الإطار في يوم النشر. وتحتوي مدونتها على تحديث نُشر في الساعة 19:57 بتوقيت UTC يوم 17 أغسطس، يصف Copilot بأنه "مؤلف مشارك فحص طلب السحب المدمج وتغيير الشيفرة" و"اعتبره سليمًا تمامًا" من دون ملاحظة الثغرات، ويعترف بأنه "من غير الواضح ما إذا كان تغيير الشيفرة قد تم بمساعدة الذكاء الاصطناعي". في ذلك السرد، يُعد فشل الذكاء الاصطناعي فشلًا في المراجعة لا في التأليف: فقد كان طلب السحب المدمج يحمل توقيعًا مشاركًا من Copilot، وقد نجا الحقن من تلك المراجعة. وتنقل CSO Online عن أمي لوتواك، المدير التنفيذي للتقنية في Wiz، قوله إن الإسناد الواضح بين البشر والذكاء الاصطناعي "أصبح من الصعب قليلًا إثباته"، وإن "مجرد النظر إلى المؤلفين المشاركين في طلب السحب لا يكفي".

A self-built HTML card titled 'Two accounts of one commit', badged 'PR #1218 · SNOW-2069227 · squash-merged 18 June 2026 as commit 4a1b8ce'. A cyan-headed left panel, 'GitHub, internal review', reads: a human wrote the contributions that led to the vulnerability; Copilot Autofix neither reviewed nor contributed to them; Copilot's co-authored commit 6d0e2fa changed jira_close.yml, not the vulnerable file; the unsafe pattern traces to commit 094038e of 25 August 2025; squash-merging carries each co-author trailer forward regardless of which lines that author touched. An amber-headed right panel, 'Wiz, blog update, 17 August 2026, 19:57 UTC', reads: Copilot was a co-author that checked the merged PR and code change; it identified it as all-clear without noticing the vulnerabilities; it is unclear whether the code-change was AI-assisted; Copilot Autofix is listed among the squash commit's co-authors; the post was revised on the evening of publication without retracting the finding. Below, an open-question strip asks whether Copilot reviewed jira_issue.yml inside PR #1218, and a dashed band lists what is not in dispute.

ما تشترك فيه الروايتان يستحق الفصل عمّا تختلفان عليه. تتفق الروايتان على أن كومِت الدمج squash commit يحمل سطر المُشارك في التأليف الخاص بـ Copilot Autofix، وعلى أن سير العمل كان قابلًا للاستغلال. ولا يجادل أيٌّ منهما في أن GitHub Advanced Security فحص المراجعة النهائية لطلب السحب، واستخرج jira_issue.yml، ولم ينبّه إلى الحقن — إذ تُبلّغ Wiz عن ذلك باعتباره خطأً فائتًا، بينما يتناول رد GitHub مسألة التأليف لا مسألة الفحص. وما يبقى غير محسوم هو ما إذا كان Copilot قد راجع الأسطر القابلة للاستغلال أصلًا: تقول Wiz إن مراجعةً قد جرى تنفيذها واجتازتها، ويقول GitHub إن الأداة لم يكن لها دور فيها، والسجلات التي كانت ستحسم الأمر موجودة لدى إحدى الشركتين. ويسجّل السجل الروايتين معًا بدلًا من الاختيار بينهما.

خمسة أيام، وما الذي تغيّر بعدها.

كان الإصلاح سريعًا بمجرد وصول التقرير. أرسلت Wiz التقرير عبر برنامج HackerOne الخاص بـ Snowflake تحت رقم التقرير #3819931 في 23 يونيو، وأبلغت فريق الأمن لدى Snowflake عبر Slack في اليوم نفسه؛ ثم دمجت Snowflake طلب السحب PR #1402، الالتزام 1dc7766، الذي استبدل توسيع التعبير المباشر بمتغيرات بيئة تُمرَّر إلى jq كوسائط. يضع الجدول الزمني لدى Wiz تدوير رمز Jira في 24 يونيو، ويورد The Hacker News التقسيم نفسه. في المقابل، تقول مقدمة Wiz نفسها إن Snowflake عالجت الثغرة ودوّرت بيانات الاعتماد "في اليوم نفسه" — وهو تناقض داخل المصدر الأساسي لا ينبغي للسجل أن يتجاهله. وقع الإصلاح في 23 يونيو؛ بينما يؤرخ التدوير في 24 يونيو في جدول Wiz.

جرى الإفصاح وفق توقيت Snowflake: تحدد Wiz موعدًا نهائيًا للإفصاح العلني هو 25 يوليو 2026، أي بعد ثلاثين يومًا من تسوية جرى التوصل إليها في 25 يونيو بموجب سياسة البرنامج، ونشرت التحليل في 17 أغسطس. وقال بيان Snowflake إلى CSO Online إن الشركة «تقدّر إبلاغ Wiz المسؤول» وإنها كانت تعمل مع Wiz لمشاركة الدروس مع القطاع. ولا يحمل تحليل Wiz ولا تقرير The Hacker News معرّف CVE أو درجة CVSS أو مدخلًا في كتالوج CISA للمثغرات المعروفة الاستغلال؛ فالعيب كان إعدادًا لسير عمل في مستودع عام، لا مكتبة مُصدَرة، لذا لم يدخل قاعدة بيانات للمثغرات بالطريقة المعتادة.

A self-built HTML card titled 'Five days live, five weeks to publication', subtitled 'Every date below is day-precision, as reported by Wiz Research and The Hacker News'. A vertical timeline lists six entries: 25 August 2025, commit 094038e introduces the unsafe jira_issue.yml refactor, attributed by GitHub to a Snowflake engineer; 18 June 2026, PR #1218 squash-merged as 4a1b8ce and the flaw goes live on the default branch; 23 June 2026, Wiz reports via HackerOne #3819931 and Snowflake merges fix PR #1402 as 1dc7766; 24 June 2026, Jira API token rotated, the fix having landed a day earlier; 25 July 2026, public disclosure deadline under Snowflake's HackerOne policy; 17 August 2026, Wiz publishes the full analysis, blog updated at 19:57 UTC. An amber band reads 'Exposure window: five days, 18 to 23 June 2026'. A footer notes no CVE identifier, CVSS score or known-exploited entry accompanies the record.

ما يثبته السجل، وما لا يثبته

تصنّف الأرشيف هذا على أنه نتيجة بحثية لا حدث نشر، بدرجة خطورة عالية، وتقييم ثقة A، وتأكيد على مشاركة الذكاء الاصطناعي وتسجيل ضرر حقيقي؛ تاريخه، 17 أغسطس 2026، هو يوم نشر Wiz، بينما يمتد الحادث نفسه من 18 إلى 23 يونيو. أمّا النواة الراسخة فهي ضيقة وقابلة للتحقق: سير عمل عام أدرج نصًا يتحكم فيه المهاجم داخل أمر shell، وقُورن شرط الحماية الخاص به بخاصية تكون null في ذلك الحدث، وكان رمز Jira موجودًا في الخطوة نفسها، واستغلها وكيل مستقل، ودمجت Snowflake إصلاحًا ودوّرت بيانات الاعتماد خلال يوم واحد.

الأجزاء التي هي استنتاج لا سجل هي التي تميل السرديات العابرة إلى تسطيحها. فـ Copilot Autofix موثّق كمؤلف مشارك في طلب السحب، وليس موثّقًا كمؤلف الأسطر القابلة للاستغلال؛ أما الإطار القائم على «الذكاء الاصطناعي في مواجهة الذكاء الاصطناعي» الذي حمل دورة الأخبار الأولى فقد سحبته المؤسسة الصحفية جزئيًا في غضون ساعات، ودحضته GitHub. وما إذا كانت مراجعة الذكاء الاصطناعي لطلب السحب المدموج قد اطّلعت على jira_issue.yml يظل سؤالًا واقعيًا مفتوحًا، لا مسألة محسومة. ومدى الوصول، رغم أن Wiz وصفته بالتفصيل، لم يخضع لتدقيق مستقل: فلم يُنشر أي سجل لأذونات Jira أو لتشغيل سير العمل أو لسجل التدقيق.

نمط الإصلاح هو النمط الذي كانت إرشادات GitHub نفسها قد أوصت به منذ يوليو 2025 — تمرير بيانات القضايا غير الموثوقة إلى متغير بيئة وتسليمها إلى jq كوسيط، بدلًا من توسيعها داخل كتلة run. والالتزام المدمج من Snowflake يفعل ذلك بالضبط، ويظل التعامل المصحح موجودًا على الفرع الافتراضي. وبالنسبة لأي شخص يقرأ السجل على أنه سابقة، فإن الخلاصة الراسخة تتعلق بالإسناد لا بالحقن: فعندما يحمل طلب سحب عدة أشخاص وعدة وكلاء، لا يستطيع سطر المؤلف المشارك أن يخبرك من كتب سطرًا معينًا، وانتهى كل من Wiz وGitHub إلى قول ذلك بكلمات مختلفة.