DevSecOps & Security Tools: Kod Güvenliğini Otomatikleştirmek
Giriş
DevSecOps’un temel felsefesi basit ama güçlü: Güvenliği geliştirme sürecinin sonuna bırakma, en başından itibaren entegre et.
Production’a ulaşmış bir güvenlik açığını düzeltmek, development aşamasında bulup düzeltmekten kat kat daha maliyetli. Bu yazıda pipeline’ınıza entegre edebileceğiniz araçları ve teknikleri inceleyeceğiz.
1. Static Application Security Testing (SAST)
1.1 Python: Bandit
# Kurulum
pip install bandit
# Tarama
bandit -r ./src
# Detailed report
bandit -r ./src -f json > security_report.json
# Spesifik kuralları ignore et
bandit -r ./src -s B101,B601
Bandit Konfigurasyonu:
# .bandit
exclude_dirs:
- /tests
- /venv
tests:
- B101 # assert_used
- B601 # parametrized_sql_query
- B602 # shell_injection
severity_level: MEDIUM
1.2 Python: Semgrep
# Kurulum
pip install semgrep
# Tarama
semgrep --config=p/security-audit ./src
# Spesifik rule'larla
semgrep --config=p/owasp-top-ten ./src
# JSON output
semgrep --config=p/security-audit --json ./src > findings.json
Semgrep Konfigurasyonu:
# .semgrep.yml
rules:
- id: hardcoded-secrets
pattern-either:
- patterns:
- pattern: password = "..."
- pattern: api_key = "..."
- pattern: secret = "..."
message: "Sabit şifre/anahtar bulundu"
severity: ERROR
- id: sql-injection
patterns:
- pattern: $DB.query($STR % $VAR)
message: "SQL injection riski"
severity: ERROR
- id: insecure-deserialization
patterns:
- pattern: pickle.loads(...)
- pattern: json.loads($VAR, object_hook=...)
message: "Güvenli olmayan deserialization"
severity: ERROR
1.3 JavaScript/TypeScript: ESLint Security Plugin
# Kurulum
npm install eslint-plugin-security --save-dev
# Konfigürasyon
cat > .eslintrc.json << EOF
{
"plugins": ["security"],
"extends": ["plugin:security/recommended"],
"rules": {
"security/detect-eval-with-expression": "error",
"security/detect-non-literal-regexp": "warn",
"security/detect-unsafe-regex": "error"
}
}
EOF
# Çalıştırma
eslint --ext .js,.ts src/
2. Dependency Vulnerability Scanning
2.1 Python: Safety
# Kurulum
pip install safety
# Tarama
safety check
# Detailed report
safety check --json > dependencies.json
# Spesifik dosyayı kontrol et
safety check -r requirements.txt
2.2 Python: pip-audit
# Kurulum
pip install pip-audit
# Tarama
pip-audit
# Detaylı çıktı
pip-audit --desc
# Requirements dosyası
pip-audit -r requirements.txt
2.3 JavaScript: npm audit
# Yerleşik audit
npm audit
# Fix recommendations
npm audit --audit-level=moderate
# Otomatik fix
npm audit fix
# JSON output
npm audit --json > audit.json
2.4 Node.js: Snyk
# Kurulum
npm install -g snyk
# Giriş yap
snyk auth
# Tarama
snyk test
# Detaylı rapor
snyk test --json
# Sürekli monitoring
snyk monitor
3. Secret Management
3.1 Git: Detect Secrets
# Kurulum
pip install detect-secrets
# Başlat
detect-secrets scan > .secrets.baseline
# Yeni scan
detect-secrets scan --baseline .secrets.baseline
# Pre-commit hook
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
detect-secrets scan --baseline .secrets.baseline
EOF
chmod +x .git/hooks/pre-commit
3.2 Git: TruffleHog
# Kurulum
pip install trufflehog
# Git repository'de ara
trufflehog git file://.
# Dosya sistemde ara
trufflehog filesystem ./
# Regex ile custom pattern
trufflehog regex --regex '(password|api_key)\s*=\s*["\']([^"\']+)["\']' ./
3.3 Environment Variables & .env
# ❌ YANLIŞ: Hardcoded secrets
DATABASE_URL = "postgresql://user:password@localhost/db"
API_KEY = "sk-1234567890abcdef"
# ✅ DOĞRU: Environment variables
import os
from dotenv import load_dotenv
load_dotenv() # .env dosyasını yükle
DATABASE_URL = os.getenv("DATABASE_URL")
API_KEY = os.getenv("API_KEY")
# Validation
if not DATABASE_URL:
raise ValueError("DATABASE_URL environment variable required")
.env dosyası (Never commit to git):
# .env
DATABASE_URL=postgresql://user:password@localhost/db
API_KEY=sk-1234567890abcdef
SECRET_KEY=your-secret-key-here
# .gitignore
.env
.env.local
*.key
*.pem
4. Container Security
4.1 Docker Image Scanning: Trivy
# Kurulum
# macOS
brew install aquasecurity/trivy/trivy
# Linux
wget https://github.com/aquasecurity/trivy/releases/download/v0.45.0/trivy_0.45.0_Linux-64bit.tar.gz
# Image tarama
trivy image python:3.11
# JSON output
trivy image --format json python:3.11 > scan.json
# High severity göster
trivy image --severity HIGH,CRITICAL python:3.11
4.2 Docker Security Best Practices
# ❌ YANLIŞ
FROM ubuntu:latest
RUN apt-get update && apt-get install -y python3 pip
RUN pip install requests flask
COPY . /app
WORKDIR /app
CMD ["python3", "app.py"]
# ✅ DOĞRU
FROM python:3.11-slim
# Güvenli olmayan paketleri kaldır
RUN apt-get update && \
apt-get remove -y --purge sudo && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Non-root kullanıcı oluştur
RUN useradd -m -u 1000 appuser
# Bağımlılıkları belirt
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Uygulamayı kopyala
COPY --chown=appuser:appuser . /app
WORKDIR /app
# Non-root olarak çalıştır
USER appuser
# Health check ekle
HEALTHCHECK --interval=30s --timeout=3s \
CMD python -c "import socket; s = socket.socket(); s.connect(('localhost', 8000))"
CMD ["python", "-u", "app.py"]
4.3 Kubernetes Security: kubesec
# Kurulum
brew install kubesec
# Manifest kontrolü
kubesec scan deployment.yaml
# JSON output
kubesec scan deployment.yaml -o json
# Pod Security Policy kontrolü
kubesc scan --kubeconfig ~/.kube/config
5. SAST Integration: CI/CD Pipeline
5.1 GitHub Actions
# .github/workflows/security.yml
name: Security Scan
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install bandit safety semgrep
- name: Bandit Security Check
run: bandit -r ./src -f json -o bandit.json
continue-on-error: true
- name: Safety Check
run: safety check --json > safety.json
continue-on-error: true
- name: Semgrep Scan
run: semgrep --config=p/security-audit --json ./src > semgrep.json
continue-on-error: true
- name: Upload reports
uses: actions/upload-artifact@v3
if: always()
with:
name: security-reports
path: |
bandit.json
safety.json
semgrep.json
- name: Comment PR with results
if: github.event_name == 'pull_request'
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');
const bandit = JSON.parse(fs.readFileSync('bandit.json'));
let comment = '## Security Scan Results\n\n';
comment += `- **Bandit Issues**: ${bandit.metrics.total_lines_of_code} LOC scanned\n`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
5.2 GitLab CI
# .gitlab-ci.yml
stages:
- scan
- test
- build
security-scan:
stage: scan
image: python:3.11
script:
- pip install bandit safety semgrep
- bandit -r ./src -f json -o bandit.json
- safety check --json > safety.json
- semgrep --config=p/security-audit --json ./src > semgrep.json
artifacts:
reports:
sast: bandit.json
paths:
- safety.json
- semgrep.json
allow_failure: true
container-scan:
stage: scan
image: aquasec/trivy
script:
- trivy image --format json --output trivy.json my-image:latest
artifacts:
paths:
- trivy.json
allow_failure: true
6. Code Quality & Security Metrics
6.1 SonarQube Integration
# Docker ile çalıştırma
docker run -d --name sonarqube -e SONAR_JDBC_URL=jdbc:h2:tcp://localhost:9092/sonarqube -e SONAR_JDBC_DRIVER=org.h2.Driver -p 9000:9000 sonarqube:latest
# Tarama
sonar-scanner \
-Dsonar.projectKey=my-project \
-Dsonar.sources=./src \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.login=YOUR_TOKEN
SonarQube Konfigurasyonu:
# sonar-project.properties
sonar.projectKey=my-project
sonar.projectName=My Project
sonar.sources=src
sonar.exclusions=tests/**,venv/**
sonar.python.coverage.reportPaths=coverage.xml
sonar.python.pylint_config=.pylintrc
# Quality gates
sonar.qualitygate.wait=true
6.2 OWASP Dependency Check
# Kurulum (macOS)
brew install dependency-check
# Tarama
dependency-check --project "My Project" --scan ./src
# JSON report
dependency-check --project "My Project" --scan ./src --format JSON --out ./reports
# Supression (False Positives)
cat > dependency-check-suppression.xml << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<suppressions>
<suppress>
<packageUrl>pkg:npm/express@4.17.1</packageUrl>
<cve>CVE-2021-12345</cve>
</suppress>
</suppressions>
EOF
# Suppression ile çalıştırma
dependency-check --scan . --suppression dependency-check-suppression.xml
7. Runtime Security Monitoring
7.1 Falco (Container Runtime Security)
# falco-rules.yaml
- rule: Unauthorized Process
desc: Detect unauthorized process execution
condition: >
spawned_process and
container and
proc.name not in (allowed_processes)
output: >
Unauthorized process started
(user=%user.name command=%proc.cmdline container=%container.name)
priority: WARNING
- rule: Suspicious File Access
desc: Detect suspicious file access
condition: >
open and
container and
fd.name in (/etc/shadow, /etc/passwd) and
proc.name not in (ls, cat, grep)
output: >
Suspicious file access
(file=%fd.name process=%proc.name user=%user.name)
priority: CRITICAL
7.2 Application Security Monitoring
# Aplicação
import logging
import json
from datetime import datetime
class SecurityEventLogger:
"""Güvenlik olaylarını kayıt et"""
def __init__(self):
self.logger = logging.getLogger("security")
handler = logging.FileHandler("/var/log/security.log")
self.logger.addHandler(handler)
def log_security_event(self,
event_type: str,
severity: str,
user_id: str,
details: dict):
"""Güvenlik olayını kayıt et"""
event = {
"timestamp": datetime.utcnow().isoformat(),
"event_type": event_type,
"severity": severity,
"user_id": user_id,
"details": details
}
self.logger.log(
logging.WARNING if severity == "HIGH" else logging.INFO,
json.dumps(event)
)
# Örnek olaylar
def log_failed_auth(self, username: str, ip_address: str):
self.log_security_event(
event_type="FAILED_AUTHENTICATION",
severity="MEDIUM",
user_id=username,
details={"ip_address": ip_address}
)
def log_unauthorized_access(self, user_id: str, resource: str):
self.log_security_event(
event_type="UNAUTHORIZED_ACCESS_ATTEMPT",
severity="HIGH",
user_id=user_id,
details={"resource": resource}
)
def log_privilege_escalation(self, user_id: str, old_role: str, new_role: str):
self.log_security_event(
event_type="PRIVILEGE_ESCALATION",
severity="CRITICAL",
user_id=user_id,
details={"old_role": old_role, "new_role": new_role}
)
8. Security Checklist & Automation
8.1 Pre-Commit Hooks
# .git/hooks/pre-commit
#!/bin/bash
echo "🔒 Running security checks..."
# Bandit check
bandit -r ./src -q
if [ $? -ne 0 ]; then
echo "❌ Bandit failed"
exit 1
fi
# Secret detection
detect-secrets scan --baseline .secrets.baseline
if [ $? -ne 0 ]; then
echo "❌ Secrets detected"
exit 1
fi
# Unit tests
pytest --cov=./src
if [ $? -ne 0 ]; then
echo "❌ Tests failed"
exit 1
fi
echo "✅ All checks passed"
exit 0
8.2 Security Policy YAML
# security-policy.yml
organization: "My Company"
version: "1.0"
policies:
- id: no-hardcoded-secrets
description: "Hardcoded secrets should not exist in code"
tools: [detect-secrets, trufflehog]
severity: CRITICAL
action: FAIL_BUILD
- id: known-vulnerabilities
description: "No known vulnerabilities in dependencies"
tools: [safety, pip-audit, npm-audit]
severity: CRITICAL
action: FAIL_BUILD
- id: code-quality
description: "Minimum code quality standards"
tools: [bandit, semgrep]
severity: HIGH
action: WARN
- id: test-coverage
description: "Minimum 80% test coverage"
threshold: 80
severity: MEDIUM
action: WARN
compliance:
standards:
- OWASP-Top-10
- CWE
- PCI-DSS
9. Security Training & Best Practices
## Developer Security Training
### 1. OWASP Top 10
- Injection attacks
- Broken authentication
- Sensitive data exposure
- XML external entities (XXE)
- Broken access control
### 2. Secure Coding Practices
- Input validation
- Output encoding
- Parameterized queries
- Principle of least privilege
- Fail securely
### 3. Common Vulnerabilities
- SQL injection
- Cross-site scripting (XSS)
- Cross-site request forgery (CSRF)
- Insecure deserialization
- Using components with known vulnerabilities
### 4. Tools Training
- SAST tools (Bandit, Semgrep)
- Dependency scanners (Safety, npm audit)
- Secret detectors (TruffleHog)
- Container scanners (Trivy)
### Resources
- OWASP WebGoat
- HackTheBox
- TryHackMe
- SANS Cyber Academy
Sonuç
DevSecOps felsefesi basit: Güvenliği sona bırakma, en baştan entegre et.
Otomatik araçlar, CI/CD pipeline’ındaki güvenlik kontrolleri ve sürekli monitoring sayesinde güvenlik açıklarını erken tespit edebilir, maliyetli hataları önleyebilirsiniz.
“Shift Left” prensibi burada kritik: Güvenlik kontrolleri ne kadar erken yapılırsa, düzeltme maliyeti o kadar düşük olur. Bir güvenlik açığını production’da değil, development aşamasında bulmak hem daha ucuz hem de daha güvenli.