Kod yazarken bulunan bir güvenlik açığını düzeltmek geliştiriciye dakikalar alır. Aynı güvenlik açığı production'da yakalanırsa bir sprint'e mal olur. Ve bir saldırgan önce bulursa, maliyeti milyonlarca olur. Shift-left security'nin temel argümanı budur - güvenlik kontrollerini geliştirme yaşam döngüsünde mümkün olduğunca erken aşamaya taşımak.
DevSecOps bu fikri bir uygulamaya dönüştürür: güvenlik, sonunda ayrı bir aşama değil, kodun ilk satırından production dağıtımına kadar geliştirmenin her aşamasına örülmüş sürekli bir süreçtir.
Geç Güvenliğin Maliyeti
IBM'in Veri İhlali Maliyeti Raporu, güvenlik sorunlarını düzeltme maliyetinin ne kadar geç yakalanırsa o kadar katlanarak arttığını sürekli olarak göstermiştir:
| Aşama | Düzeltme Maliyeti | Düzeltme Süresi |
|---|---|---|
| IDE / Local Dev | Dakikalar | Saniyeler - dakikalar |
| Code Review / PR | Saatler | Dakikalar - saatler |
| CI/CD Pipeline | Günler | Saatler - günler |
| Staging / QA | Haftalar | Günler |
| Production | Aylar | Haftalar - aylar |
| Post-breach | Milyonlar ($) | Aylar - yıllar |
Sonuç açıktır: güvenliği ne kadar erken aşamaya taşırsanız, maliyet ve zamandan o kadar fazla tasarruf edersiniz.
DevSecOps Pipeline
Olgun bir DevSecOps pipeline her aşamada güvenlik kontrollerini entegre eder:
Her aşamayı somut araçlar ve yapılandırmalarla inceleyelim.
Aşama 1: IDE'de Güvenlik
En hızlı geri bildirim döngüsü. Dosyayı kaydetmeden önce güvenlik açıklarını yakalayın.
Önerilen Araçlar
- Semgrep: OWASP güvenlik açıkları için topluluk kurallarıyla hafif statik analiz
- Snyk IDE Extension: gerçek zamanlı bağımlılık güvenlik açığı taraması
- GitLens + GitLeaks: düzenleyicinizde secrets tespit edin
- ESLint Security Plugins: Node.js için
eslint-plugin-security, DOM XSS içineslint-plugin-no-unsanitized
Örnek: ESLint Security Yapılandırması
{ "extends": ["eslint:recommended"], "plugins": ["security", "no-unsanitized"], "rules": { "security/detect-object-injection": "warn", "security/detect-non-literal-regexp": "warn", "security/detect-unsafe-regex": "error", "security/detect-buffer-noassert": "error", "security/detect-eval-with-expression": "error", "security/detect-no-csrf-before-method-override": "error", "security/detect-possible-timing-attacks": "warn", "no-unsanitized/method": "error", "no-unsanitized/property": "error" } }
Aşama 2: Pre-commit Hooks
İkinci savunma hattı. Her commit'ten önce otomatik olarak çalışır ve tehlikeli kodun depoya girmesini engeller.
Gitleaks: Secrets'ı Git'e Ulaşmadan Yakalayın
Kod tabanlarındaki en yaygın güvenlik hatası secrets commit etmektir - API keys, database passwords, tokens. Bir secret git history'ye girdiğinde, tamamen kaldırmak son derece zordur (force push'lardan sonra bile, fork'lar ve cache'ler onu tutabilir).
# .pre-commit-config.yaml repos: - repo: https://github.com/gitleaks/gitleaks rev: v8.21.0 hooks: - id: gitleaks - repo: https://github.com/semgrep/semgrep rev: v1.90.0 hooks: - id: semgrep args: ['--config', 'auto']
Kurulum ve aktivasyon:
pip install pre-commit pre-commit install
Artık her git commit otomatik olarak sızan secrets ve yaygın güvenlik açıkları için tarama yapar. Bir şey bulunursa, commit engellenir.
Özel Gitleaks Kuralları
Kuruluşunuzun secrets'ları için özel kalıplar ekleyebilirsiniz:
# .gitleaks.toml title = "Custom Gitleaks Config" [[rules]] id = "internal-api-key" description = "Internal API key detected" regex = '''INTERNAL_KEY_[A-Za-z0-9]{32}''' tags = ["key", "internal"]
Aşama 3: CI/CD Pipeline Güvenliği
Ağır işin yapıldığı yer burasıdır. CI pipeline'ınız her pull request'te birden fazla güvenlik taraması çalıştırmalıdır.
SAST (Static Application Security Testing)
SAST araçları kaynak kodu çalıştırmadan analiz eder ve güvenlik açığına işaret eden kalıpları arar.
# .github/workflows/security.yml name: Security Scan on: pull_request: branches: [main] jobs: sast: name: Static Analysis runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run Semgrep uses: semgrep/semgrep-action@v1 with: config: >- p/owasp-top-ten p/typescript p/nodejs p/react generateSarif: true - name: Upload SARIF uses: github/codeql-action/upload-sarif@v3 with: sarif_file: semgrep.sarif
Semgrep'in p/owasp-top-ten kural seti en yaygın güvenlik açıklarını yakalar: SQL injection, XSS, SSRF, path traversal, insecure deserialization ve daha fazlası.
SCA (Software Composition Analysis)
SCA, bağımlılıklarınızı bilinen güvenlik açıkları için tarar. Bu kritik öneme sahiptir - modern uygulama kodunun %80'inden fazlası open-source bağımlılıklardan gelir.
dependency-scan: name: Dependency Audit runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run Snyk uses: snyk/actions/node@master env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: args: --severity-threshold=high - name: npm audit run: npm audit --audit-level=high
Trivy ile Container Security
Docker images oluşturuyorsanız, bunları güvenlik açıkları için taramak şarttır. Trivy en popüler open-source container scanner'dır.
container-scan: name: Container Security runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Build image run: docker build -t my-app:${{ github.sha }} . - name: Run Trivy uses: aquasecurity/trivy-action@master with: image-ref: my-app:${{ github.sha }} format: 'sarif' output: 'trivy-results.sarif' severity: 'CRITICAL,HIGH' exit-code: '1' - name: Upload Trivy SARIF uses: github/codeql-action/upload-sarif@v3 with: sarif_file: trivy-results.sarif
SBOM Oluşturma
Software Bill of Materials (SBOM) uygulamanızdaki her bileşenin tam envanteridır. Uyumluluk çerçeveleri ve devlet düzenlemeleri tarafından giderek daha fazla gerekli kılınmaktadır (ABD Siber Güvenlik Başkanlık Kararnamesi federal yazılım için SBOM'u zorunlu kılmaktadır).
sbom: name: Generate SBOM runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Generate SBOM with Syft uses: anchore/sbom-action@v0 with: format: spdx-json output-file: sbom.spdx.json - name: Upload SBOM uses: actions/upload-artifact@v4 with: name: sbom path: sbom.spdx.json
Aşama 4: Güvenli Docker Images
Production Docker image'ı en az yetki ilkesini izlemelidir. Güçlendirilmiş bir Dockerfile şöyle görünür:
# Build stage FROM node:22-alpine AS builder WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci COPY . . RUN npm run build # Production stage FROM node:22-alpine AS runner WORKDIR /app # Install dumb-init before dropping root RUN apk add --no-cache dumb-init # Don't run as root RUN addgroup -S app && adduser -S app -G app # Copy only what's needed COPY /app/dist ./dist COPY /app/node_modules ./node_modules COPY /app/package.json ./ # Drop to non-root user USER app ENTRYPOINT ["dumb-init", "--"] # Health check HEALTHCHECK \ CMD wget -qO- http://localhost:3000/health || exit 1 EXPOSE 3000 CMD ["node", "dist/server.js"]
Temel uygulamalar:
- Multi-stage builds kullanın: builder aşaması dev dependencies içerir; runner aşaması sadece production kodu içerir
- Root olarak çalıştırmayın: root olmayan bir kullanıcı oluşturun ve ona geçin
- Alpine images kullanın: daha küçük saldırı yüzeyi (varsayılan olarak daha az paket yüklü)
- Image sürümlerini sabitleyin: supply chain saldırılarından kaçınmak için
node:latestyerinenode:22-alpine npm cikullanın: lock dosyasından deterministik kurulumlar,npm installdeğil
Aşama 5: Secret Management
Hard-coded secrets, geliştirici kaynaklı olaylarda ihlallerin bir numaralı nedenidir.
Yapılmaması Gereken
// NEVER do this const API_KEY = "sk-1234567890abcdef"; const DB_PASSWORD = "supersecret123"; const client = new Client({ connectionString: `postgres://admin:${DB_PASSWORD}@db.example.com/prod` });
Bunun Yerine Yapılması Gereken
// Use environment variables const client = new Client({ connectionString: process.env.DATABASE_URL }); // Or use a secret manager import { SecretManagerServiceClient } from '@google-cloud/secret-manager'; const client = new SecretManagerServiceClient(); const [version] = await client.accessSecretVersion({ name: 'projects/my-project/secrets/db-password/versions/latest', }); const dbPassword = version.payload?.data?.toString();
Secret Management Hiyerarşisi
OWASP Top 10: Hızlı Başvuru
Her geliştiricinin OWASP Top 10'u bilmesi gerekir. Özet versiyon:
| # | Güvenlik Açığı | Ne Olduğu | Önleme |
|---|---|---|---|
| 1 | Broken Access Control | Kullanıcıların erişmemesi gereken kaynaklara erişmesi | Varsayılan olarak reddet, sunucu tarafında doğrula |
| 2 | Cryptographic Failures | Zayıf şifreleme, düz metin veriler | Güçlü algoritmalar kullan (AES-256, bcrypt), her yerde TLS |
| 3 | Injection | SQL, NoSQL, OS command injection | Parameterized queries, girdi doğrulama |
| 4 | Insecure Design | Kusurlu mimari | Threat modeling, güvenli tasarım kalıpları |
| 5 | Security Misconfiguration | Varsayılan kimlik bilgileri, açık cloud buckets | Güçlendirilmiş varsayılanlar, otomatik yapılandırma denetimleri |
| 6 | Vulnerable Components | Bağımlılıklardaki bilinen CVE'ler | SCA taraması, düzenli güncellemeler |
| 7 | Auth Failures | Zayıf parolalar, bozuk oturumlar | MFA, hız sınırlama, güvenli oturum yönetimi |
| 8 | Data Integrity Failures | İmzasız güncellemeler, güvenilmeyen CI/CD | Kod imzalama, SBOM, pipeline bütünlüğü |
| 9 | Logging Failures | Denetim izi yok | Yapılandırılmış loglama, anomalilerde uyarı |
| 10 | SSRF | Server-side request forgery | Giden URL'leri beyaz listeye al, girdileri doğrula |
Tam GitHub Actions Security Workflow
Yukarıdakilerin tümünü birleştiren tam, production'a hazır bir workflow:
# .github/workflows/security.yml name: Security Pipeline on: pull_request: branches: [main] push: branches: [main] permissions: contents: read security-events: write jobs: secrets-scan: name: Secret Detection runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: gitleaks/gitleaks-action@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} sast: name: Static Analysis (SAST) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: semgrep/semgrep-action@v1 with: config: p/owasp-top-ten p/typescript p/nodejs dependency-audit: name: Dependency Scan (SCA) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 - run: npm ci - run: npm audit --audit-level=high - uses: snyk/actions/node@master env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: args: --severity-threshold=high continue-on-error: true container-scan: name: Container Scan runs-on: ubuntu-latest needs: [sast, dependency-audit] steps: - uses: actions/checkout@v4 - run: docker build -t app:${{ github.sha }} . - uses: aquasecurity/trivy-action@master with: image-ref: app:${{ github.sha }} severity: CRITICAL,HIGH exit-code: '1' sbom: name: SBOM Generation runs-on: ubuntu-latest needs: [container-scan] steps: - uses: actions/checkout@v4 - uses: anchore/sbom-action@v0 with: format: spdx-json output-file: sbom.spdx.json
Takip Edilecek Metrikler
DevSecOps programınızın çalışıp çalışmadığını nasıl anlarsınız? Bu metrikleri takip edin:
- Mean time to remediate (MTTR): tespit sonrası güvenlik açıklarını ne kadar hızlı düzelttiğiniz
- Vulnerability escape rate: production'a ulaşan güvenlik açıklarının yüzdesi
- False positive rate: çok fazla yanlış pozitif, uyarı yorgunluğuna ve görmezden gelinen uyarılara yol açar
- Dependency freshness: bağımlılıklarınızın ortalama yaşı (eski = bilinen CVE olasılığı daha yüksek)
- SBOM coverage: güncel SBOM'lara sahip projelerin yüzdesi
Başlarken: Pratik Bir Yol Haritası
Her şeyi bir anda uygulamaya çalışmayın. Aşamalı yaklaşım daha iyi çalışır:
Sonuç
DevSecOps, pipeline'ınıza daha fazla araç eklemekle ilgili değildir - güvenliği yazılım oluşturma şeklinizin doğal bir parçası yapmakla ilgilidir. Amaç her PR'yi güvenlik uyarılarıyla engellemek değil, geliştiricilere hızlı geri bildirim vermektir, böylece kod hala zihinlerinde tazeyken sorunları düzeltebilirler.
Temel konularla başlayın: secrets için pre-commit hooks, CI'da dependency scanning ve Docker images için container scanning. Ardından ekibinizin ihtiyaçlarına göre iterasyon yapın.
Güvenlik bir kez gönderdiğiniz bir özellik değildir. Her commit'e inşa ettiğiniz bir pratiktir.
DevSecOps Starter Checklist:
- Gitleaks pre-commit hooks kuruldu
- .env ve secret dosyaları .gitignore'da
- CI pipeline'da Semgrep SAST
- Bağımlılık taraması için Snyk veya npm audit
- Container image taraması için Trivy
- Dockerfiles'da root olmayan kullanıcı
- Environment variables veya secret manager'da secrets
- Her sürümde SBOM oluşturma
- Ekip genelinde OWASP Top 10 farkındalığı