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

Betterleaks

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

التثبيت

استخدام Go

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

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

# تحميل أحدث إصدار من 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

docker pull ghcr.io/zricorp/betterleaks:latest
docker run ghcr.io/zricorp/betterleaks:latest --help

Homebrew (macOS)

brew install betterleaks

المسح الأساسي

مسح مستودع Git

# مسح الدليل الحالي (بافتراض وجود .git)
betterleaks scan

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

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

# إظهار ملخص عدد النتائج
betterleaks scan --report

مسح الدليل (غير git)

# مسح الدليل كنظام ملفات (ليس سجل git)
betterleaks scan --no-git --directory /path/to/directory

# مسح دلائل متعددة
betterleaks scan --no-git --directory /src --directory /config

مسح Stdin

# توصيل المحتوى عبر 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

[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

مسح مستودع Git

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

# مسح من بداية سجل repo
betterleaks scan --repo /path/to/repo

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

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

# مسح الالتزامات بين رافتين
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

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

# مسح التغييرات المرحلية فقط
betterleaks scan --repo /path/to/repo --no-history

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

تكامل CI/CD

إجراءات GitHub

إنشاء .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

إنشاء .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

خطاف Pre-commit

إنشاء .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

إنشاء ملف قاعدة مخصصة

إنشاء 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

# توليد تقرير 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 (نتائج الأمان)

# توليد تقرير SARIF
betterleaks scan --format sarif --file results.sarif

# SARIF متوافق مع علامة تبويب أمان GitHub

إخراج CSV

# توليد تقرير CSV
betterleaks scan --format csv --file secrets.csv

# الإخراج يتضمن: rule_id, file, line, secret_hash, severity, commit

إخراج الجدول (CLI)

# جدول قابل للقراءة من قبل الإنسان الافتراضي
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

الترحيل من Gitleaks

التوافق

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

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

# تحويل إلى 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

أفضل الممارسات

1. تشغيل قبل الالتزام

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

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

# تحديد الأسرار الموجودة
betterleaks scan --repo . --report

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

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

# استخدام قوائم السماح في .betterleaks.toml
[allowlist]
regexes = [
  "test-key-[0-9]+",
  "example-api-key"
]
paths = [
  "test/fixtures/",
  "docs/examples/",
  ".github/"
]
commits = [
  "abc123def456"  # التزام محدد بأسرار معروفة
]

4. فرض في CI/CD

# تعيين كود الخروج لفرض المسح
betterleaks scan --exit-code 1

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

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

# إذا وجدت Betterleaks بيانات اعتماد معرضة:
# 1. تحديد السر ونطاقه
# 2. تدوير بيانات الاعتماد على الفور
# 3. إزالة من سجل git باستخدام git-filter-repo
# 4. إعادة المسح للتأكد من الإزالة

6. قواعس مخصصة للمنظمة

# إنشاء قواعس خاصة بـ 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. استبعاد المسارات غير الضرورية

[allowlist]
paths = [
  "vendor/",
  "node_modules/",
  ".git/",
  "dist/",
  "build/",
  "test/fixtures/secrets/"
]

8. المراقبة بمرور الوقت

# توليد التقارير لتتبع الاتجاهات
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

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

# تفعيل الإخراج المفصل
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"]

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

# تقليل عمال المتوازي
betterleaks scan --parallel 2

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

# زيادة ذاكرة النظام أو استخدام نطاق repo أصغر

الأدوات ذات الصلة

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