الأمان والأداء
أمان خطوط أنابيب CI/CD
أمان خطوط أنابيب CI/CD
خطوط أنابيب CI/CD هي نقطة هجوم حرجة. اختراق خط أنابيب يمكن أن يمنح المهاجمين الوصول لأنظمة الإنتاج والبيانات السرية والقدرة على حقن كود خبيث في الإصدارات.
تهديدات CI/CD الشائعة
- كشف الأسرار - مفاتيح API، كلمات المرور، الرموز المسربة في السجلات أو الكود
- تسميم التبعيات - حزم خبيثة في npm، pip، composer
- هجمات سلسلة التوريد - إجراءات/إضافات طرف ثالث مخترقة
- تصعيد الامتيازات - أذونات خط أنابيب مفرطة التساهل
- حقن الكود - إدخال غير موثوق في سكريبتات خط الأنابيب
حرج: خط أنابيب CI/CD مخترق يمكن أن ينشر أبوابًا خلفية للإنتاج بدون أي مراجعة للكود. عامل أمان خط الأنابيب بجدية مثل أمان الإنتاج.
إدارة الأسرار
لا تكتب الأسرار بشكل ثابت أبدًا. استخدم إدارة آمنة للأسرار:
<!-- سيء: أسرار في الكود -->
const API_KEY = 'sk_live_abc123xyz789';
const DB_PASSWORD = 'MyP@ssw0rd123';
<!-- جيد: استخدم متغيرات البيئة -->
const API_KEY = process.env.STRIPE_API_KEY;
const DB_PASSWORD = process.env.DB_PASSWORD;
<!-- GitHub Actions: استخدم أسرار مشفرة -->
# .github/workflows/deploy.yml
name: النشر
on: push
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: النشر للإنتاج
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
aws s3 sync ./dist s3://my-bucket
<!-- GitLab CI: استخدم متغيرات محمية -->
# .gitlab-ci.yml
deploy:
script:
- echo "$SSH_PRIVATE_KEY" | ssh-add -
- ssh user@server "deploy.sh"
only:
- main
const API_KEY = 'sk_live_abc123xyz789';
const DB_PASSWORD = 'MyP@ssw0rd123';
<!-- جيد: استخدم متغيرات البيئة -->
const API_KEY = process.env.STRIPE_API_KEY;
const DB_PASSWORD = process.env.DB_PASSWORD;
<!-- GitHub Actions: استخدم أسرار مشفرة -->
# .github/workflows/deploy.yml
name: النشر
on: push
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: النشر للإنتاج
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
aws s3 sync ./dist s3://my-bucket
<!-- GitLab CI: استخدم متغيرات محمية -->
# .gitlab-ci.yml
deploy:
script:
- echo "$SSH_PRIVATE_KEY" | ssh-add -
- ssh user@server "deploy.sh"
only:
- main
أفضل الممارسات: دوّر الأسرار بانتظام، استخدم أسرار منفصلة للتطوير/التجهيز/الإنتاج، قيّد وصول الأسرار لفروع محددة، فعّل فحص الأسرار في مستودعك.
اختبار أمان التطبيق الثابت (SAST)
SAST يفحص الكود المصدري للثغرات قبل النشر:
<!-- GitHub Actions: CodeQL SAST -->
# .github/workflows/security.yml
name: فحص الأمان
on: [push, pull_request]
jobs:
analyze:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- uses: actions/checkout@v3
- name: تهيئة CodeQL
uses: github/codeql-action/init@v2
with:
languages: javascript, python
- name: تنفيذ تحليل CodeQL
uses: github/codeql-action/analyze@v2
<!-- تكامل SonarCloud -->
- name: فحص SonarCloud
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
<!-- Semgrep للقواعد المخصصة -->
- name: فحص Semgrep
uses: returntocorp/semgrep-action@v1
with:
config: p/security-audit
# .github/workflows/security.yml
name: فحص الأمان
on: [push, pull_request]
jobs:
analyze:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- uses: actions/checkout@v3
- name: تهيئة CodeQL
uses: github/codeql-action/init@v2
with:
languages: javascript, python
- name: تنفيذ تحليل CodeQL
uses: github/codeql-action/analyze@v2
<!-- تكامل SonarCloud -->
- name: فحص SonarCloud
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
<!-- Semgrep للقواعد المخصصة -->
- name: فحص Semgrep
uses: returntocorp/semgrep-action@v1
with:
config: p/security-audit
اختبار أمان التطبيق الديناميكي (DAST)
DAST يختبر التطبيقات العاملة للثغرات:
<!-- فحص OWASP ZAP -->
# .github/workflows/dast.yml
name: فحص DAST
on:
schedule:
- cron: '0 2 * * *' # يوميًا الساعة 2 صباحًا
jobs:
zap_scan:
runs-on: ubuntu-latest
steps:
- name: فحص ZAP الأساسي
uses: zaproxy/action-baseline@v0.7.0
with:
target: 'https://staging.example.com'
rules_file_name: '.zap/rules.tsv'
cmd_options: '-a'
<!-- ماسح ثغرات Nuclei -->
- name: فحص Nuclei
uses: projectdiscovery/nuclei-action@main
with:
target: https://staging.example.com
templates: cves,vulnerabilities
# .github/workflows/dast.yml
name: فحص DAST
on:
schedule:
- cron: '0 2 * * *' # يوميًا الساعة 2 صباحًا
jobs:
zap_scan:
runs-on: ubuntu-latest
steps:
- name: فحص ZAP الأساسي
uses: zaproxy/action-baseline@v0.7.0
with:
target: 'https://staging.example.com'
rules_file_name: '.zap/rules.tsv'
cmd_options: '-a'
<!-- ماسح ثغرات Nuclei -->
- name: فحص Nuclei
uses: projectdiscovery/nuclei-action@main
with:
target: https://staging.example.com
templates: cves,vulnerabilities
SAST مقابل DAST: SAST يحلل الكود بدون تشغيله (سريع، يجد أخطاء البرمجة). DAST يختبر التطبيقات العاملة (أبطأ، يجد ثغرات وقت التشغيل). استخدم كليهما لأمان شامل.
فحص التبعيات
افحص التبعيات للثغرات المعروفة:
<!-- npm audit في CI -->
# .github/workflows/audit.yml
name: تدقيق التبعيات
on: [push, pull_request]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: تشغيل npm audit
run: |
npm audit --audit-level=moderate
npm audit fix
<!-- تكوين Dependabot -->
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
<!-- فحص أمان Snyk -->
- name: فحص أمان Snyk
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
command: test
args: --severity-threshold=high
# .github/workflows/audit.yml
name: تدقيق التبعيات
on: [push, pull_request]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: تشغيل npm audit
run: |
npm audit --audit-level=moderate
npm audit fix
<!-- تكوين Dependabot -->
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
<!-- فحص أمان Snyk -->
- name: فحص أمان Snyk
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
command: test
args: --severity-threshold=high
فحص أمان الحاويات
افحص صور Docker للثغرات قبل النشر:
<!-- فحص حاويات Trivy -->
# .github/workflows/container-scan.yml
name: أمان الحاويات
on: push
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: بناء الصورة
run: docker build -t myapp:${{ github.sha }} .
- name: تشغيل فحص Trivy
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:${{ github.sha }}'
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'
- name: رفع النتائج
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
<!-- فشل البناء عند الثغرات الحرجة -->
- name: فحص مع Grype
run: |
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh
./grype myapp:${{ github.sha }} --fail-on critical
# .github/workflows/container-scan.yml
name: أمان الحاويات
on: push
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: بناء الصورة
run: docker build -t myapp:${{ github.sha }} .
- name: تشغيل فحص Trivy
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:${{ github.sha }}'
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'
- name: رفع النتائج
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
<!-- فشل البناء عند الثغرات الحرجة -->
- name: فحص مع Grype
run: |
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh
./grype myapp:${{ github.sha }} --fail-on critical
تحذير: افحص الصور دائمًا قبل دفعها لسجلات الإنتاج. ثغرة حرجة واحدة يمكن أن تخترق بنيتك التحتية بأكملها.
أمان البنية التحتية كرمز (IaC)
افحص تكوينات Terraform، CloudFormation، و Kubernetes للأخطاء:
<!-- Checkov لفحص IaC -->
# .github/workflows/iac-scan.yml
name: أمان IaC
on: [push, pull_request]
jobs:
checkov:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: تشغيل Checkov
uses: bridgecrewio/checkov-action@master
with:
directory: ./terraform
framework: terraform
soft_fail: false
<!-- tfsec لـ Terraform -->
- name: تشغيل tfsec
uses: aquasecurity/tfsec-action@v1.0.0
with:
working_directory: ./terraform
soft_fail: false
<!-- kubesec لبيانات Kubernetes -->
- name: فحص بيانات K8s
run: |
docker run -i kubesec/kubesec:512c5e0 scan /dev/stdin < k8s/deployment.yaml
# .github/workflows/iac-scan.yml
name: أمان IaC
on: [push, pull_request]
jobs:
checkov:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: تشغيل Checkov
uses: bridgecrewio/checkov-action@master
with:
directory: ./terraform
framework: terraform
soft_fail: false
<!-- tfsec لـ Terraform -->
- name: تشغيل tfsec
uses: aquasecurity/tfsec-action@v1.0.0
with:
working_directory: ./terraform
soft_fail: false
<!-- kubesec لبيانات Kubernetes -->
- name: فحص بيانات K8s
run: |
docker run -i kubesec/kubesec:512c5e0 scan /dev/stdin < k8s/deployment.yaml
أمان GitHub Actions
أمّن سير عمل GitHub Actions الخاص بك:
<!-- ثبّت الإجراءات على SHA كامل (ليس الوسوم) -->
# سيء: يمكن تغيير الوسوم
- uses: actions/checkout@v3
# جيد: SHA الالتزام غير قابل للتغيير
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
<!-- قيّد الأذونات بأقل امتياز -->
name: النشر
on: push
permissions:
contents: read
id-token: write # فقط لـ OIDC
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e5e7e5
with:
persist-credentials: false # لا تحتفظ برمز GitHub
<!-- منع حقن السكريبت -->
# سيء: إدخال المستخدم في أمر run
- name: تعليق
run: echo "${{ github.event.comment.body }}"
# جيد: مرر كمتغير بيئة
- name: تعليق
env:
COMMENT_BODY: ${{ github.event.comment.body }}
run: echo "$COMMENT_BODY"
# سيء: يمكن تغيير الوسوم
- uses: actions/checkout@v3
# جيد: SHA الالتزام غير قابل للتغيير
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
<!-- قيّد الأذونات بأقل امتياز -->
name: النشر
on: push
permissions:
contents: read
id-token: write # فقط لـ OIDC
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e5e7e5
with:
persist-credentials: false # لا تحتفظ برمز GitHub
<!-- منع حقن السكريبت -->
# سيء: إدخال المستخدم في أمر run
- name: تعليق
run: echo "${{ github.event.comment.body }}"
# جيد: مرر كمتغير بيئة
- name: تعليق
env:
COMMENT_BODY: ${{ github.event.comment.body }}
run: echo "$COMMENT_BODY"
أمان GitHub: فعّل قواعد حماية الفروع، اطلب فحوصات الحالة، فعّل فحص الأسرار، استخدم قواعد حماية البيئة لنشر الإنتاج.
قائمة تقوية خط الأنابيب
<!-- قائمة أمان CI/CD الكاملة -->
✓ إدارة الأسرار:
- لا أسرار ثابتة في الكود
- استخدم مخازن أسرار مشفرة
- دوّر الأسرار بانتظام
- دقق وصول الأسرار
✓ فحص الكود:
- SAST مفعّل (CodeQL, SonarCloud, Semgrep)
- DAST مجدول (OWASP ZAP, Nuclei)
- فحص التبعيات (npm audit, Snyk)
- فحوصات امتثال الترخيص
✓ أمان الحاويات:
- فحص الصور (Trivy, Grype)
- تحديثات الصورة الأساسية تلقائية
- بناءات متعددة المراحل للصور الصغيرة
- حاويات بدون روت
✓ البنية التحتية:
- فحص IaC (Checkov, tfsec)
- سياسات الشبكة مطبقة
- حدود الموارد مكونة
- التسجيل والمراقبة مفعلة
✓ التحكم في الوصول:
- أقل أذونات الامتياز
- حماية الفرع مفعلة
- المراجعات المطلوبة مكونة
- موافقات خاصة بالبيئة
✓ إدارة الأسرار:
- لا أسرار ثابتة في الكود
- استخدم مخازن أسرار مشفرة
- دوّر الأسرار بانتظام
- دقق وصول الأسرار
✓ فحص الكود:
- SAST مفعّل (CodeQL, SonarCloud, Semgrep)
- DAST مجدول (OWASP ZAP, Nuclei)
- فحص التبعيات (npm audit, Snyk)
- فحوصات امتثال الترخيص
✓ أمان الحاويات:
- فحص الصور (Trivy, Grype)
- تحديثات الصورة الأساسية تلقائية
- بناءات متعددة المراحل للصور الصغيرة
- حاويات بدون روت
✓ البنية التحتية:
- فحص IaC (Checkov, tfsec)
- سياسات الشبكة مطبقة
- حدود الموارد مكونة
- التسجيل والمراقبة مفعلة
✓ التحكم في الوصول:
- أقل أذونات الامتياز
- حماية الفرع مفعلة
- المراجعات المطلوبة مكونة
- موافقات خاصة بالبيئة
تمرين: أضف فحص الأمان لخط أنابيب CI/CD الخاص بك. نفّذ على الأقل: (1) npm audit أو Snyk للتبعيات، (2) أداة SAST مثل CodeQL أو Semgrep، (3) فحص صورة Docker مع Trivy. أصلح ثغرة واحدة على الأقل عالية الخطورة اكتشفتها الفحوصات.