| name | security-scan |
| description | Python 프로젝트 보안 취약점 스캔 및 보안 강화 가이드 |
| version | 1.0.0 |
| tags | ["python","security","vulnerability","scanning","SAST"] |
| author | deep-research-MAF |
Security Scan Skill
Overview
Python 프로젝트의 보안 취약점 검사, 민감 정보 탐지, 보안 모범 사례 적용 가이드
Security Scanning Tools
1. Bandit (SAST)
Python 코드 보안 취약점 정적 분석
설치
uv add --dev bandit
uvx bandit -r backend/src
기본 사용법
bandit -r backend/src
bandit -r backend/src -ll
bandit -r backend/src -f json -o security-report.json
bandit -r backend/src -t B201,B301
bandit -r backend/src -s B101
Configuration (.bandit)
exclude_dirs:
- /tests
- /venv
- /.venv
tests:
- B201
- B301
- B302
- B303
- B304
- B305
- B306
- B307
- B308
- B309
- B310
- B311
- B312
- B313
- B314 - B320
- B321
- B323
- B324
- B401 - B413
- B501 - B509
- B601 - B612
- B701
2. Safety
의존성 패키지 취약점 검사
uv add --dev safety
safety check
safety check -r requirements.txt
safety check --json
safety check --full-report
3. Pip-audit
PyPI 패키지 보안 감사
uv add --dev pip-audit
pip-audit
pip-audit -r requirements.txt
pip-audit --fix
pip-audit --format json
4. Semgrep
고급 정적 분석 (SAST)
docker run -v $(pwd):/src returntocorp/semgrep semgrep --config=auto /src
uv add --dev semgrep
semgrep --config=p/python backend/src
semgrep --config=p/owasp-top-ten backend/src
semgrep --config=.semgrep.yml backend/src
5. Trivy
컨테이너 이미지 및 파일시스템 스캔
brew install aquasecurity/trivy/trivy
trivy fs backend/
trivy fs --scanners vuln requirements.txt
trivy image your-image:tag
trivy fs --severity HIGH,CRITICAL backend/
Common Security Issues
1. Hardcoded Secrets
❌ Bad
API_KEY = "sk-1234567890abcdef"
DATABASE_URL = "postgresql://user:password@localhost/db"
✅ Good
import os
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("API_KEY")
DATABASE_URL = os.getenv("DATABASE_URL")
if not API_KEY:
raise ValueError("API_KEY environment variable is required")
Detection
uv add --dev detect-secrets
detect-secrets scan > .secrets.baseline
detect-secrets audit .secrets.baseline
docker run -it -v "$PWD:/pwd" trufflesecurity/trufflehog:latest filesystem /pwd
2. SQL Injection
❌ Bad
def get_user(user_id):
query = f"SELECT * FROM users WHERE id = {user_id}"
cursor.execute(query)
✅ Good
def get_user(user_id: int):
query = "SELECT * FROM users WHERE id = %s"
cursor.execute(query, (user_id,))
3. Command Injection
❌ Bad
import os
os.system(f"ls {user_input}")
✅ Good
import subprocess
subprocess.run(["ls", user_input], check=True, capture_output=True)
4. Insecure Deserialization
❌ Bad
import pickle
data = pickle.loads(untrusted_data)
✅ Good
import json
data = json.loads(trusted_data)
5. Weak Cryptography
❌ Bad
import hashlib
hashlib.md5(password.encode()).hexdigest()
✅ Good
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
Security Best Practices
1. Environment Variables
AZURE_OPENAI_KEY=your-key-here
BING_API_KEY=your-key-here
.env
.env.local
*.key
*.pem
2. Input Validation
from pydantic import BaseModel, validator, Field
class Query(BaseModel):
text: str = Field(..., min_length=1, max_length=1000)
@validator('text')
def validate_text(cls, v):
if '<script>' in v.lower():
raise ValueError('Invalid characters detected')
return v.strip()
3. Rate Limiting
from slowapi import Limiter
from slowapi.util import get_remote_address
limiter = Limiter(key_func=get_remote_address)
@app.post("/api/query")
@limiter.limit("10/minute")
async def query_endpoint(request: Request):
pass
4. CORS Configuration
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["https://your-domain.com"],
allow_credentials=True,
allow_methods=["GET", "POST"],
allow_headers=["*"],
)
5. Security Headers
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware
app.add_middleware(HTTPSRedirectMiddleware)
app.add_middleware(
TrustedHostMiddleware,
allowed_hosts=["example.com", "*.example.com"]
)
@app.middleware("http")
async def add_security_headers(request, call_next):
response = await call_next(request)
response.headers["X-Content-Type-Options"] = "nosniff"
response.headers["X-Frame-Options"] = "DENY"
response.headers["X-XSS-Protection"] = "1; mode=block"
response.headers["Strict-Transport-Security"] = "max-age=31536000"
return response
Security Scanning Workflow
1. Pre-commit Hooks
repos:
- repo: https://github.com/PyCQA/bandit
rev: '1.7.5'
hooks:
- id: bandit
args: ['-r', 'backend/src']
- repo: https://github.com/Yelp/detect-secrets
rev: v1.4.0
hooks:
- id: detect-secrets
args: ['--baseline', '.secrets.baseline']
2. CI/CD Pipeline
name: Security Scan
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install UV
run: pip install uv
- name: Run Bandit
run: |
uv add --dev bandit
bandit -r backend/src -f json -o bandit-report.json
- name: Run Safety
run: |
uv add --dev safety
safety check --json
- name: Run Trivy
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
severity: 'CRITICAL,HIGH'
- name: Upload reports
uses: actions/upload-artifact@v3
with:
name: security-reports
path: |
bandit-report.json
trivy-report.json
3. Regular Scans
#!/bin/bash
echo "🔍 Running security scans..."
echo "📦 Checking dependencies..."
pip-audit
echo "🔐 Scanning code..."
bandit -r backend/src -ll
echo "🕵️ Detecting secrets..."
detect-secrets scan --baseline .secrets.baseline
echo "📊 Trivy scan..."
trivy fs --severity HIGH,CRITICAL .
echo "✅ Security scan complete!"
Vulnerability Management
1. Severity Levels
- CRITICAL: Immediate action required
- HIGH: Fix within 7 days
- MEDIUM: Fix within 30 days
- LOW: Fix when convenient
2. Response Process
- Identify: Run security scans
- Assess: Determine impact and severity
- Fix: Update dependencies or patch code
- Verify: Re-scan to confirm fix
- Document: Record in security log
3. Security Checklist
Quick Commands
bandit -r backend/src -ll
safety check
pip-audit
detect-secrets scan
pip-audit --fix
safety check --json | safety review
bandit -r backend/src -f json -o security-report.json
trivy fs --format json --output trivy-report.json .
References