تخطَّ إلى المحتوى

Betterleaks

Betterleaks هو ماسح أسرار حديث مكتوب بلغة Go وخليفة Gitleaks. ينسخ مستودعات git والدلائل وstdin بحثاً عن بيانات اعتماد مسربة باستخدام توكنة BPE ومنطق التحقق القائم على CEL.

go install github.com/zricorp/betterleaks/v2/cmd/betterleaks@latest

تحميل البرنامج الثنائي

Section titled “تحميل البرنامج الثنائي”
# تحميل أحدث إصدار من GitHub
wget https://github.com/zricorp/betterleaks/releases/download/v2.0.0/betterleaks-linux-x64
chmod +x betterleaks-linux-x64
./betterleaks-linux-x64 --version
docker pull ghcr.io/zricorp/betterleaks:latest
docker run ghcr.io/zricorp/betterleaks:latest --help
brew install betterleaks
# مسح الدليل الحالي (بافتراض وجود .git)
betterleaks scan

# مسح مستودع محدد
betterleaks scan --repo /path/to/repo

# مسح مع الإخراج المفصل
betterleaks scan --verbose

# إظهار ملخص عدد النتائج
betterleaks scan --report
# مسح الدليل كنظام ملفات (ليس سجل git)
betterleaks scan --no-git --directory /path/to/directory

# مسح دلائل متعددة
betterleaks scan --no-git --directory /src --directory /config
# توصيل المحتوى عبر stdin
echo "aws_access_key_id=AKIAIOSFODNN7EXAMPLE" | betterleaks scan --stdin

# مسح محتوى الملف
cat secrets.txt | betterleaks scan --stdin
# استنساخ ومسح مستودع بعيد (ينشئ دليل مؤقت)
betterleaks scan --repo https://github.com/user/repo.git

# مسح فرع محدد
betterleaks scan --repo https://github.com/user/repo.git --branch main

إنشاء .betterleaks.toml في جذر المشروع:

# مسار .betterleaks.toml
title = "Betterleaks Config"

# الإخراج المفصل
verbose = false

# كود الخروج عند النتائج
exit-code = 1

# قائمة معرفات القواعد المراد استخدامها (الافتراضي: الكل)
rules = ["aws", "github", "gcp", "api-keys"]

# تعطيل القواعس المدمجة
no-builtin-rules = false

# قائمة السماح المخصصة
allowlist = {
  regexes = [
    "example-test-key",
    "fake-credential"
  ],
  paths = [
    "vendor/",
    "test/",
    ".git/"
  ],
  commits = [
    "abc123def456"
  ]
}
[git]
# مسح السجل الكامل
scan-history = true

# الحد الأقصى للالتزامات للمسح
max-commits = 1000

# استبعاد الفروع
exclude-branches = ["develop", "staging"]

# تضمين الفروع
include-branches = ["main", "production"]

# أقصى عمق التزام
commit-depth = 50
[output]
# صيغة الإخراج: json, sarif, csv, table
format = "json"

# مسار ملف الإخراج
file = "secrets-report.json"

# طباعة JSON بشكل لطيف
pretty = true

# تضمين فقط النص المطابق وليس السطر الكامل
redact = true

مسح سجل الالتزام الكامل

Section titled “مسح سجل الالتزام الكامل”
# مسح من بداية سجل repo
betterleaks scan --repo /path/to/repo

# الإخراج المفصل مع تفاصيل الالتزام
betterleaks scan --repo /path/to/repo --verbose

مسح الالتزامات المحددة

Section titled “مسح الالتزامات المحددة”
# مسح الالتزامات بين رافتين
betterleaks scan --repo /path/to/repo --commit-since abc123 --commit-until def456

# مسح آخر N commits
betterleaks scan --repo /path/to/repo --max-commits 50
# مسح فرع محدد
betterleaks scan --repo /path/to/repo --branch main

# مسح فروع متعددة
betterleaks scan --repo /path/to/repo --branch main --branch develop

التحقق من التغييرات غير الملتزمة فقط

Section titled “التحقق من التغييرات غير الملتزمة فقط”
# مسح التغييرات المرحلية فقط
betterleaks scan --repo /path/to/repo --no-history

# مسح تغييرات دليل العمل
betterleaks scan --repo /path/to/repo --staged-only

إنشاء .github/workflows/betterleaks.yml:

name: Betterleaks Scan
on: [push, pull_request]

jobs:
  betterleaks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Install Betterleaks
        run: go install github.com/zricorp/betterleaks/v2/cmd/betterleaks@latest

      - name: Scan for secrets
        run: betterleaks scan --report --exit-code 1

      - name: Generate SARIF report
        if: always()
        run: betterleaks scan --format sarif --file results.sarif

      - name: Upload SARIF to GitHub Security
        uses: github/codeql-action/upload-sarif@v2
        if: always()
        with:
          sarif_file: results.sarif

إنشاء .gitlab-ci.yml:

secret_scan:
  image: golang:1.22
  script:
    - go install github.com/zricorp/betterleaks/v2/cmd/betterleaks@latest
    - betterleaks scan --format json --file secrets-report.json
  artifacts:
    reports:
      sast: secrets-report.json
  allow_failure: false

إنشاء .git/hooks/pre-commit:

#!/bin/bash
set -e

echo "Running Betterleaks scan..."
betterleaks scan --no-history --exit-code 1

if [ $? -ne 0 ]; then
  echo "Secrets found! Commit blocked."
  exit 1
fi

echo "No secrets detected. Proceeding with commit."

ثم اجعلها قابلة للتنفيذ:

chmod +x .git/hooks/pre-commit

قواعس مخصصة مع التحقق من CEL

Section titled “قواعس مخصصة مع التحقق من CEL”

إنشاء betterleaks-rules.toml:

[[rules]]
id = "custom-api-key"
description = "Custom API key pattern"
regex = '''api[_-]?key[_-]?["\s:=]+[A-Za-z0-9]{32,}'''

# تعبير التحقق من CEL
entropy = 3.0
keywords = ["api", "key"]

# منطق التحقق باستخدام CEL
filter = '''
  len(secret) > 30 &&
  secret.matches("[A-Za-z0-9]{32,}") &&
  !secret.contains("example")
'''

allowlist = {
  regexes = ["test-key", "fake-"]
}
# استخدام ملف القواعس المخصصة
betterleaks scan --rules betterleaks-rules.toml

# تضمين القواعس المدمجة والمخصصة
betterleaks scan --rules betterleaks-rules.toml --include-builtin
[[rules]]
id = "stripe-api-key"
description = "Stripe secret key"
regex = '''sk_(test|live)_[A-Za-z0-9]{20,}'''

# حد الإنتروبيا لتوكنة BPE
entropy = 2.5

# كلمات رئيسية تشير إلى سر حقيقي
keywords = ["stripe", "sk_live", "sk_test"]

# تعبير CEL للتحقق
filter = '''
  secret.matches("^sk_(test|live)_") &&
  len(secret) > 20 &&
  secret != "sk_test_placeholder"
'''

# قائمة السماح بأسرار محددة
allowlist = {
  regexes = ["sk_test_4eC39HqLyjWDarhtT1234"],
  paths = ["test/", "docs/examples/"]
}
# توليد تقرير JSON
betterleaks scan --format json --file report.json

# JSON مع طباعة جميلة
betterleaks scan --format json --pretty

بنية JSON:

{
  "findings": [
    {
      "rule_id": "aws-access-key",
      "rule_name": "AWS Access Key",
      "file": "config/aws.env",
      "secret": "AKIAIOSFODNN7EXAMPLE",
      "entropy": 4.2,
      "line": 5,
      "commit": "abc123def456",
      "commit_author": "user@example.com",
      "committed_date": "2025-12-01T10:30:00Z"
    }
  ],
  "summary": {
    "total_findings": 1,
    "total_commits_scanned": 150,
    "scan_duration_ms": 5230
  }
}

إخراج SARIF (نتائج الأمان)

Section titled “إخراج SARIF (نتائج الأمان)”
# توليد تقرير SARIF
betterleaks scan --format sarif --file results.sarif

# SARIF متوافق مع علامة تبويب أمان GitHub
# توليد تقرير CSV
betterleaks scan --format csv --file secrets.csv

# الإخراج يتضمن: rule_id, file, line, secret_hash, severity, commit
# جدول قابل للقراءة من قبل الإنسان الافتراضي
betterleaks scan --format table

# مثال الإخراج:
# RuleID          File              Line  Secret                Entropy
# aws-key         config/aws.env    5     AKIA...EXAMPLE        4.2
# github-token    .env              12    ghp_...               3.8

Betterleaks هو بديل drop-in لـ Gitleaks:

  • نفس أعلام CLI والحجج
  • صيغة ملف تشكيل متوافقة (.gitleaks.toml → .betterleaks.toml)
  • نفس صيغ الإخراج (JSON و SARIF و CSV)
# إعادة تسمية تشكيل Gitleaks إلى Betterleaks
cp .gitleaks.toml .betterleaks.toml

# معظم الإعدادات تعمل بدون تغيير
# الاختلافات الرئيسية: توكنة BPE هي الافتراضية (ليست إنتروبيا Shannon)
# Betterleaks عادة ما تكون 3-5 مرات أسرع من Gitleaks
# مسح git موازي مع روتينات Go
betterleaks scan --parallel 4  # الافتراضي: كشف CPU التلقائي

Betterleaks تكتشف الأسرار في صيغ مشفرة:

# تتعامل تلقائياً مع:
# - أسرار مشفرة بـ Base64
# - بيانات اعتماد مشفرة بـ URL
# - قيم مشفرة بـ Hex
# - ترميز مزدوج/ثلاثي

betterleaks scan --detect-encoding

# مثال: يكتشف السر في "QUtJQUlPU0ZPRK5ON0VYQU1QTEUt" (base64)
# كشف تلقائي لعدد CPUs واستخدام جميع النوى
betterleaks scan

# حدد عدد الخيوط
betterleaks scan --parallel 8

# تعطيل المعالجة المتوازية
betterleaks scan --parallel 1

توصيل الإخراج إلى أدوات أخرى

Section titled “توصيل الإخراج إلى أدوات أخرى”
# تحويل إلى SARIF والمعالجة باستخدام أدوات أخرى
betterleaks scan --format sarif | jq '.runs[0].results'

# حساب النتائج حسب القاعدة
betterleaks scan --format json | jq '.findings | group_by(.rule_id)'

# استخراج مسارات الملفات فقط مع النتائج
betterleaks scan --format json | jq -r '.findings[].file' | sort -u
# زيادة عمق مسح الالتزام
betterleaks scan --max-commits 5000

# تعيين حد الإنتروبيا (أقل = أكثر حساسية)
# تشكيل في .betterleaks.toml مع قيم الإنتروبيا لكل قاعدة

# تخطي الملفات الكبيرة
betterleaks scan --max-file-size 10MB
# إضافة إلى خطاف pre-commit
# مسح التغييرات المرحلية فقط
betterleaks scan --staged-only --exit-code 1

2. مسح السجل الكامل عند التنفيذ الأول

Section titled “2. مسح السجل الكامل عند التنفيذ الأول”
# تحديد الأسرار الموجودة
betterleaks scan --repo . --report

# استعراض النتائج قبل المعالجة
betterleaks scan --format json | jq '.findings | length'

3. إدارة الإيجابيات الكاذبة

Section titled “3. إدارة الإيجابيات الكاذبة”
# استخدام قوائم السماح في .betterleaks.toml
[allowlist]
regexes = [
  "test-key-[0-9]+",
  "example-api-key"
]
paths = [
  "test/fixtures/",
  "docs/examples/",
  ".github/"
]
commits = [
  "abc123def456"  # التزام محدد بأسرار معروفة
]
# تعيين كود الخروج لفرض المسح
betterleaks scan --exit-code 1

# فشل CI/CD في أي نتائج
# تشكيل في GitHub Actions و GitLab CI و Jenkins وما إلى ذلك

5. تدوير بيانات الاعتماد المعرضة

Section titled “5. تدوير بيانات الاعتماد المعرضة”
# إذا وجدت Betterleaks بيانات اعتماد معرضة:
# 1. تحديد السر ونطاقه
# 2. تدوير بيانات الاعتماد على الفور
# 3. إزالة من سجل git باستخدام git-filter-repo
# 4. إعادة المسح للتأكد من الإزالة
# إنشاء قواعس خاصة بـ org للأنماط المملوكة
[[rules]]
id = "acme-internal-api-key"
description = "ACME Corp internal API key"
regex = '''api_key[_\s:=]+[A-Z]{4}_[a-z0-9]{32}'''
entropy = 3.0
keywords = ["api_key", "acme"]

7. استبعاد المسارات غير الضرورية

Section titled “7. استبعاد المسارات غير الضرورية”
[allowlist]
paths = [
  "vendor/",
  "node_modules/",
  ".git/",
  "dist/",
  "build/",
  "test/fixtures/secrets/"
]
# توليد التقارير لتتبع الاتجاهات
betterleaks scan --format json > scans/$(date +%Y-%m-%d).json

# قارن النتائج بمرور الوقت
jq '.summary.total_findings' scans/*.json
# التحقق من تثبيت Go (1.20+)
go version

# امسح ذاكرة التخزين المؤقت Go إذا لزم الأمر
go clean -cache
go install github.com/zricorp/betterleaks/v2/cmd/betterleaks@latest

لا توجد نتائج عند التوقع

Section titled “لا توجد نتائج عند التوقع”
# تفعيل الإخراج المفصل
betterleaks scan --verbose

# التحقق من القواعس النشطة
betterleaks scan --rules all

# تحقق مما إذا كانت أنماط regex متطابقة
# اختبر regex: echo "secret" | grep -E 'pattern'
# زيادة حد الإنتروبيا في .betterleaks.toml
entropy = 4.0  # الافتراضي يختلف حسب القاعدة

# استخدم مرشحات CEL للتحقق الأكثر صرامة
filter = '''secret.matches("^[A-Z0-9]{32,}$")'''

# إضافة أنماط قائمة السماح
[allowlist]
regexes = ["test", "example", "placeholder"]

نقص الذاكرة على المستودعات الكبيرة

Section titled “نقص الذاكرة على المستودعات الكبيرة”
# تقليل عمال المتوازي
betterleaks scan --parallel 2

# حد عمق الالتزام
betterleaks scan --max-commits 1000

# زيادة ذاكرة النظام أو استخدام نطاق repo أصغر
  • git-secrets: خطاف git بسيط لمطابقة النمط
  • TruffleHog: كشف السري الذي يعتمد على الذكاء الاصطناعي
  • detect-secrets: كشف PII والأسرار
  • GitGuardian CLI: مسح سري للمؤسسات