--- id: devsec-dast-sast title: SAST / DAST / IAST — 코드 / 실행 / 통합 검사 category: Coding status: draft source_trust_level: B verification_status: conceptual created_at: 2026-05-09 updated_at: 2026-05-09 tags: [devsecops, sast, dast, security, vibe-coding] tech_stack: { language: "Various", applicable_to: ["DevOps"] } applied_in: [] aliases: [SAST, DAST, IAST, Semgrep, CodeQL, OWASP ZAP, security testing] --- # SAST / DAST / IAST > **SAST = static (코드 분석), DAST = dynamic (실행 중 검사), IAST = 통합 (실행 + agent)**. SAST 매 PR + DAST 정기 + IAST production. **Semgrep / CodeQL / Snyk Code / OWASP ZAP / Burp**. ## 📖 핵심 개념 - SAST: Source code 분석 — false positive 자주. - DAST: 실행 → 외부 attack — false negative 자주. - IAST: SAST + DAST + agent — 정확. - SCA: Software Composition Analysis (의존성). ## 💻 코드 패턴 ### Semgrep (SAST, OSS, modern) ```bash # 표준 ruleset semgrep --config=auto src/ # 특정 ruleset semgrep --config=p/owasp-top-ten src/ semgrep --config=p/javascript src/ semgrep --config=p/typescript src/ semgrep --config=p/react src/ ``` ```yaml # 자체 rule rules: - id: no-eval pattern: eval(...) message: "eval() is dangerous" severity: ERROR languages: [javascript, typescript] - id: hardcoded-secret patterns: - pattern-regex: '(api_key|password|token)\s*=\s*["''][\w-]{20,}' message: "Hardcoded secret" severity: ERROR ``` ### CodeQL (GitHub) ```yaml # .github/workflows/codeql.yml - uses: github/codeql-action/init@v3 with: { languages: javascript, typescript } - uses: github/codeql-action/analyze@v3 ``` → GitHub Advanced Security. 깊은 분석. ### Snyk Code (commercial) ```bash snyk code test ``` → AI 기반 false positive 적음. ### Common SAST 발견 ```ts // SQL injection const q = `SELECT * FROM users WHERE name = '${name}'`; // ❌ // Path traversal const file = readFile(`/data/${userInput}`); // ❌ // XSS res.send(`

${userInput}

`); // ❌ // SSRF fetch(req.body.url); // ❌ // Hardcoded secret const API_KEY = 'sk-abc123...'; // ❌ // Insecure crypto crypto.createHash('md5').update(password).digest('hex'); // ❌ ``` ### DAST — OWASP ZAP ```bash # Quick scan docker run -t owasp/zap2docker-stable zap-baseline.py -t https://example.com # Full scan docker run -v $(pwd):/zap/wrk owasp/zap2docker-stable \ zap-full-scan.py -t https://example.com -r report.html ``` ```yaml # CI — staging 배포 후 - name: ZAP scan uses: zaproxy/action-baseline@v0.10.0 with: target: 'https://staging.example.com' fail_action: false # 자동 fail X — 검토 ``` ### Burp Suite (manual / advanced) ``` - Web app proxy - 사용자 행동 capture - Replay + 변형 - Active scan ``` → Pen test 표준. ### Authenticated DAST ```yaml # ZAP 가 로그인 후 검사 - name: ZAP authenticated run: | zap-cli context import context.xml zap-cli active-scan https://staging.example.com ``` ### IAST (modern) ``` Contrast Security / Datadog ASM - Agent 가 runtime 추적 - 실제 사용 path 만 검사 - false positive ~0 ``` ```ts // Datadog import 'dd-trace/init'; // agent 가 자동 — SAST + DAST 결합 ``` ### Pre-commit hook (빠른 feedback) ```yaml # .pre-commit-config.yaml repos: - repo: https://github.com/returntocorp/semgrep rev: v1.45.0 hooks: - id: semgrep args: [--config=p/secrets, --error] - repo: https://github.com/Yelp/detect-secrets rev: v1.4.0 hooks: - id: detect-secrets args: [--baseline, .secrets.baseline] ``` ### Secret scanning ```bash # Gitleaks gitleaks detect --source . --verbose # TruffleHog trufflehog filesystem . # detect-secrets detect-secrets scan --baseline .secrets.baseline ``` → git history 안 secret 검출. ```yaml # GitHub - name: Gitleaks uses: gitleaks/gitleaks-action@v2 ``` ### License scanning ```bash license-checker --excludePackages 'MIT;Apache-2.0;ISC;BSD-3-Clause' --failOn 'GPL-3.0;AGPL-3.0' ``` ### IaC scanning ```bash # Trivy IaC trivy config . # Checkov checkov -d terraform/ # Tfsec tfsec . ``` ```hcl # 발견 예 resource "aws_s3_bucket" "data" { bucket = "data" # ❌ encryption 없음 # ❌ versioning 없음 # ❌ public access block 없음 } ``` ### CI 통합 — fail 정책 ```yaml - name: SAST run: semgrep --config=auto --error --severity ERROR src/ - name: SCA run: npm audit --audit-level=high - name: Secrets run: gitleaks detect --no-git --source . - name: IaC run: trivy config terraform/ --severity HIGH,CRITICAL --exit-code 1 ``` ### False positive 관리 ```yaml # .semgrepignore src/legacy/** # nosem comment const x = eval(safeExpression); // nosemgrep: no-eval ``` → Triaged false positive 만 ignore. ### SARIF (표준 format) ```yaml - name: Semgrep run: semgrep --config=auto --sarif --output=results.sarif - uses: github/codeql-action/upload-sarif@v3 with: { sarif_file: results.sarif } ``` → GitHub Security 탭. ### Threat modeling (위쪽) - STRIDE / DREAD framework. - 새 feature 마다 threat list. - SAST / DAST 보다 먼저 — 디자인 단계. ## 🤔 의사결정 기준 | 단계 | 도구 | |---|---| | Pre-commit | Gitleaks / Semgrep | | PR CI | SAST (Semgrep / CodeQL) + SCA (npm audit) + IaC (Trivy) | | Staging | DAST (ZAP) | | Production | IAST (Datadog) | | Audit / pen test | Burp Suite | | Compliance | SARIF + GitHub Security | ## ❌ 안티패턴 - **SAST 만 + DAST 없음**: business logic flaw 못 잡음. - **DAST 만 + SAST 없음**: 코드 path 안 닿는 곳 missed. - **모든 finding fail CI**: 노이즈. severity 기반. - **False positive 그냥 ignore (rule 끄기)**: 실제 issue 도 놓침. inline. - **Secret 발견 후 force push**: history 안 남음. rotate + history rewrite. - **Production agent 끄기**: 성능 우선 — risk. - **IaC scan 누락**: cloud misconfig 자주. ## 🤖 LLM 활용 힌트 - Semgrep + Gitleaks + Trivy IaC = OSS 좋은 baseline. - DAST = staging schedule. - IAST 가 modern best. - SARIF 로 통일. ## 🔗 관련 문서 - [[Security_OWASP_Top_10_Practical]] - [[DevSec_Container_Scanning]] - [[DevSec_Supply_Chain]]