كيف تتسرب الأسرار عبر السجلات، وقطع البناء، وتاريخ Git

لقد انتهيت للتو من إعداد خط أنابيب CI/CD الخاص بك لجلب الأسرار بأمان من خزنة. يعمل خط الأنابيب، وينتشر التطبيق، ويبدو كل شيء أخضر. بعد أسبوع، يجد أحد أعضاء الفريق كلمة مرور قاعدة بيانات مطبوعة في سجل خط أنابيب من ثلاثة أيام مضت. لا أحد يعرف من رآها. لا أحد يعرف إذا تم نسخها. أصبحت كلمة المرور الآن عامة فعليًا.

يحدث هذا السيناريو أكثر مما تتوقع الفرق. الخزنة نفسها آمنة. تكامل خط الأنابيب يعمل. لكن الأسرار لا تتسرب دائمًا عبر نظام التخزين. إنها تتسرب عبر الأماكن التي ينتهي بها المطاف عن طريق الخطأ: السجلات، وقطع البناء، وتاريخ Git.

لماذا تعتبر سجلات خط الأنابيب نقطة تسرب

سجلات خط الأنابيب هي أول مكان تهرب منه الأسرار. أثناء التطوير أو التصحيح، غالبًا ما تطبع الفرق متغيرات البيئة لمعرفة ما يحدث. عندما يفشل تطبيق في الاتصال بقاعدة بيانات، يضيف شخص ما عبارة طباعة سريعة تُفرغ سلسلة الاتصال بأكملها بما في ذلك كلمة المرور. يتم تخزين إدخال السجل هذا على خادم CI/CD، ويمكن الوصول إليه من قبل أي شخص لديه صلاحية الوصول إلى السجلات.

المشكلة هي أن السجلات لا يتم تدويرها أو تنظيفها تلقائيًا في معظم الإعدادات. السر الذي يظهر في سجل اليوم يبقى هناك إلى أجل غير مسمى. أي شخص ينضم إلى الفريق لاحقًا، أي شخص يدقق في خط الأنابيب، أي شخص لديه صلاحية قراءة السجلات يمكنه رؤيته. بمجرد أن يدخل السر إلى سجل، تفقد السيطرة على من يراه.

على سبيل المثال، ضع في اعتبارك نص نشر يطبع متغيرات البيئة لتصحيح الأخطاء:

#!/bin/bash
# Debug: print connection details
echo "Connecting to database..."
echo "DB_PASSWORD=$DB_PASSWORD"  # Accidentally prints the secret
# Actual connection command
psql "host=$DB_HOST user=$DB_USER password=$DB_PASSWORD dbname=$DB_NAME"

سيظهر سجل خط الأنابيب:

Connecting to database...
DB_PASSWORD=supersecret123

هذا السطر الواحد يعيش الآن في تخزين سجل خادم CI/CD، ويمكن الوصول إليه من قبل أي شخص لديه صلاحية الوصول إلى السجلات.

تتم مشاركة السجلات أيضًا. يلصق مطور مقتطف سجل في قناة دردشة لطلب المساعدة. يحتوي المقتطف على كلمة المرور. الآن السر موجود في سجل الدردشة أيضًا. حتى إذا قمت بحذف الرسالة، فقد تبقى نسخ مخبأة.

قطع البناء تحمل الأسرار دون سابق إنذار

قطع البناء هي نقطة تسرب أقل وضوحًا، لكنها بنفس الخطورة. عندما تقوم ببناء JAR أو صورة Docker أو ملف ZIP، تقوم عملية البناء بنسخ الملفات من دليل المصدر الخاص بك إلى القطعة. يمكن أن تنتهي ملفات التكوين التي تحتوي على أسرار داخل القطعة دون أن يلاحظها أحد.

مثال شائع هو ملف .env المستخدم أثناء التطوير المحلي. الملف موجود في دليل المشروع، وتقوم سكريبت البناء بنسخ كل شيء إلى مجلد الإخراج. ينتهي ملف .env داخل صورة Docker أو JAR. يتم دفع القطعة إلى سجل. الآن أي شخص يسحب تلك الصورة أو ينزل تلك القطعة يمكنه استخراج ملف التكوين وقراءة الأسرار.

الجزء الخطير هو أن إصلاح الملف المصدر لا يصلح القطعة. إذا قمت بإزالة ملف .env من المصدر وأعدت البناء، ستكون القطعة الجديدة نظيفة. لكن القطعة القديمة في السجل لا تزال تحتوي على السر. ما لم تقم بحذف القطعة القديمة صراحةً، يظل السر متاحًا لأي شخص يعرف العلامة أو التجزئة.

تاريخ Git يكاد يكون من المستحيل تنظيفه

تاريخ Git هو أخطر نقطة تسرب لأنه مصمم ليكون دائمًا. عندما تقوم بإيداع ملف يحتوي على سر، يتم تسجيل هذا السر في الإيداع. حتى إذا قمت بحذف الملف في إيداع لاحق، لا يزال السر موجودًا في تاريخ الإيداعات. أي شخص يستنسخ المستودع بالسجل الكامل يمكنه التحقق من الإيداع القديم وقراءة السر.

تكتشف العديد من الفرق هذا بعد أشهر أو سنوات. يبحث شخص ما في قاعدة الكود عن ملف تكوين ويجد إيداعًا قديمًا يحتوي على بيانات اعتماد قاعدة بيانات الإنتاج. لقد تم كشف السر لأشهر. ليس لدى الفريق أي فكرة عمن استنسخ المستودع خلال تلك الفترة أو ما إذا كان السر قد تم استخراجه.

يمكن للدفع القسري لإعادة كتابة التاريخ إزالة السر من المستودع البعيد، لكنه لا يساعد مع النسخ الموجودة. أي شخص قام بالفعل باستنساخ المستودع لا يزال لديه السر في تاريخه المحلي. لا يمكنك إجباره على حذف نسخته المحلية. الاستجابة الآمنة الوحيدة هي تدوير السر فورًا.

كيفية منع تسرب الأسرار تلقائيًا

يتطلب منع تسرب الأسرار طبقات متعددة من الدفاع. لا توجد أداة أو ممارسة واحدة تلتقط كل شيء. الهدف هو اكتشاف الأسرار مبكرًا، قبل أن تصل إلى السجلات أو القطع أو تاريخ Git.

يُظهر الرسم البياني أدناه كل مسار تسرب مع عنصر التحكم الأساسي في المنع والاستجابة النهائية.

flowchart TD A[Secret in Source Code] --> B{Leak Path} B --> C[Pipeline Logs] B --> D[Build Artifacts] B --> E[Git History] C --> F[Pipeline Scanning] D --> G[Ignore Files + Pipeline Scanning] E --> H[Pre-commit Scanning] F --> I[Rotate Immediately] G --> I H --> I I[Rotate Secret & Revoke Old]

المسح قبل الإيداع

قم بتثبيت ماسح أسرار كخطاف قبل الإيداع لجميع المستودعات. تقوم أدوات مثل git-secrets و truffleHog و Gitleaks بمسح الملفات المعلقة بحثًا عن أنماط تشبه مفاتيح API أو الرموز أو كلمات المرور أو غيرها من الأسرار. إذا اكتشف الماسح نمطًا مشبوهًا، يتم حظر الإيداع ويتلقى المطور رسالة تشرح ما تم العثور عليه.

يمسك المسح قبل الإيداع بالأسرار قبل أن تدخل تاريخ Git. هذه هي النقطة الأكثر فعالية لوقف التسرب لأن السر لا يصل أبدًا إلى المستودع. يمكن للمطور إزالة السر، وإضافة الملف إلى .gitignore، والإيداع مرة أخرى.

المسح في خط الأنابيب

يمكن تجاوز خطافات ما قبل الإيداع. يمكن للمطورين تخطي الخطافات، أو تثبيتها بشكل غير صحيح، أو العمل على أجهزة لا تحتوي على الخطافات مهيأة. لهذا السبب تحتاج إلى طبقة ثانية من المسح في خط الأنابيب.

تقدم العديد من منصات CI/CD مسحًا مدمجًا أو إضافات تتحقق من مخرجات السجل وقطع البناء بحثًا عن أسرار. يحتوي GitHub Actions على مسح الأسرار. يتضمن GitLab CI اكتشاف الأسرار في أدوات SAST الخاصة به. يحتوي Jenkins على إضافات لمسح بيانات الاعتماد. عندما يكتشف الماسح سرًا في سطر سجل أو ملف قطعة، يمكن لخط الأنابيب أن يفشل أو يرسل تحذيرًا.

يمسك المسح في خط الأنابيب بالأسرار التي تتسلل عبر خطافات ما قبل الإيداع. كما يمسك بالأسرار التي تدخل خط الأنابيب عبر وسائل أخرى، مثل متغيرات البيئة التي تتم طباعتها عن طريق الخطأ أثناء خطوة بناء.

استخدام ملفات التجاهل بانضباط

.gitignore و .dockerignore أدوات بسيطة لكنها فعالة. يجب إدراج ملفات التكوين التي تحتوي على أسرار في كلا الملفين حتى لا تدخل أبدًا إلى مستودع Git أو سياق بناء Docker. لكن ملفات التجاهل ليست حلاً كاملاً. يمكن للمطورين نسيان تحديثها، أو يمكنهم تجاوزها عن طريق الخطأ بإضافات قسرية.

تعامل مع ملفات التجاهل كدفاع أساسي، وليس دفاعًا رئيسيًا. ادمجها مع المسح الآلي لالتقاط الحالات التي يفشل فيها ملف التجاهل.

التدوير الفوري عند اكتشاف تسرب

إذا تسرب سر إلى تاريخ Git، لا تحاول تنظيف التاريخ. حذف الإيداع أو إعادة كتابة التاريخ ليس كافيًا لأن النسخ الموجودة لا تزال تحتوي على السر. الإجراء الآمن الوحيد هو تدوير السر فورًا.

قم بإنشاء كلمة مرور أو رمز أو مفتاح جديد. قم بتحديث جميع الأنظمة التي تستخدم السر القديم. قم بإلغاء السر القديم بحيث لا يمكن استخدامه بعد الآن للمصادقة. ثم تأكد من تخزين السر الجديد في خزنتك والوصول إليه عبر خط الأنابيب، وليس مشفرًا في أي مكان.

قائمة مراجعة عملية لمنع تسرب الأسرار

  • قم بتثبيت ماسح أسرار كخطاف قبل الإيداع لجميع المستودعات.
  • قم بتمكين مسح الأسرار في خط أنابيب CI/CD للسجلات والقطع.
  • أضف ملفات التكوين التي تحتوي على أسرار إلى .gitignore و .dockerignore.
  • راجع سجلات خط الأنابيب بشكل دوري للكشف عن التعرض العرضي للأسرار.
  • قم بتدوير أي سر تم كشفه، حتى لو كنت تعتقد أن الكشف كان بسيطًا.

الخلاصة

إدارة الأسرار لا تنتهي عندما تدمج خزنة مع خط الأنابيب الخاص بك. تحافظ الخزنة على الأسرار آمنة في حالة السكون، لكن خط الأنابيب لا يزال بإمكانه تسريبها عبر السجلات والقطع وتاريخ Git. الطريقة الوحيدة لمنع التسرب هي المسح في كل مرحلة: قبل الإيداع، وأثناء البناء، وبعد النشر. وعندما يحدث تسرب، لا تحاول محو الأدلة. قم بتدوير السر. هذا هو الإجراء الوحيد الذي يصلح المشكلة بالفعل.