لو حطيت مفتاح AWS_SECRET_ACCESS_KEY في ملف .env وعملتله commit بالغلط، خلاص — حتى لو مسحته في commit تاني، هو موجود للأبد في الـ Git history. الـ bots اللي بتمشّط GitHub بتلاقيه في أقل من 30 ثانية حسب تقرير GitGuardian 2024. المقال ده بيوريك إزاي تمنع التسريب ده من الأساس، قبل ما يوصل حتى للمستودع المحلي.
أتمتة منع تسريب الأسرار: خط دفاع بيشتغل قبل ما تعمل push
المشكلة باختصار
الطريقة الشائعة اللي بتفشل: المطور بيحط API keys في ملف config، بيعمل git add . من غير ما يشوف إيه بالظبط بيتضاف، بيعمل push، وبعد أسبوعين بيوصله إيميل من AWS إن حد استخدم المفتاح بتاعه علشان يشغّل EC2 instances بـ 40 ألف دولار. التصحيح بعد كده معناه: إلغاء المفتاح، توليد واحد جديد، و git filter-repo على كل تاريخ الـ repo. مش لعبة.
مثال مبدئي بسيط: الحارس اللي بيفتّش قبل الدخول
تخيّل مدخل عمارة فيه حارس. كل حد داخل، الحارس بيفتّش شنطته بسرعة. لو لقي حاجة ممنوعة (سكينة، مثلاً)، بيرجّعه من غير ما يدخل أصلًا. الـ pre-commit hook هو نفس الحارس ده، بس بدل السكينة، بيدوّر على patterns زي مفاتيح AWS، tokens بتاعة GitHub، كلمات سر قواعد بيانات. ولو لقاها، بيرفض الـ commit قبل ما يخش المستودع.
التعريف العلمي الدقيق: pre-commit hook
الـ Git hooks هي سكربتات بتشتغل أوتوماتيكيًا عند أحداث معينة في Git. الـ pre-commit هو hook بيشتغل قبل تسجيل الـ commit محليًا، وبياخد صلاحية إنه يوقف العملية كلها لو رجّع exit code ≠ 0. مكتبة pre-commit (بـ Python) بتدير الـ hooks دي بصيغة .pre-commit-config.yaml قابلة للمشاركة بين الفريق.
Gitleaks أداة مفتوحة المصدر مكتوبة بـ Go، بتفحص الفرق (diff) أو كل الـ repo بالبحث عن أكثر من 150 pattern جاهز (AWS, GCP, Stripe, Slack tokens، إلخ). بترجع ناتج JSON أو stdout، وبتوقف الـ commit لو لقت match.
التركيب خطوة بخطوة
1) تثبيت المكتبات
# macOS / Linux
brew install gitleaks pre-commit
# أو عبر pip و go
pip install pre-commit
go install github.com/gitleaks/gitleaks/v8@latest2) ملف الإعداد .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.21.2
hooks:
- id: gitleaks
name: Detect hardcoded secrets
stages: [pre-commit]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: detect-private-key
- id: check-added-large-files
args: ['--maxkb=500']