MCP server that scans AI-generated code for security vulnerabilities (OWASP Top 10, hardcoded secrets, SQL injection, XSS)
npm install security-scanner-mcpscan-security | μ’
ν© λ³΄μ μ€μΊ - λͺ¨λ κ²μ¬λ₯Ό νλ²μ μν |
scan-secrets | νλμ½λ©λ API ν€, λΉλ°λ²νΈ, ν ν° κ²μΆ |
scan-injection | SQL/NoSQL/Command Injection μ·¨μ½μ κ²μ¬ |
scan-xss | Cross-Site Scripting μ·¨μ½μ κ²μ¬ |
scan-crypto | μνΈν μ·¨μ½μ (μ½ν ν΄μ, λΆμμ ν λλ€ λ±) |
scan-auth | μΈμ¦/μΈμ
μ·¨μ½μ (JWT, μΏ ν€, CORS λ±) |
scan-path | νμΌ/κ²½λ‘ μ·¨μ½μ (Path Traversal, μ
λ‘λ λ±) |
scan-dependencies | package.json λ±μμ μ·¨μ½ν μμ‘΄μ± κ²μ¬ |
scan-iac | Dockerfile, Kubernetes, Terraform 보μ κ²μ¬ |
get-fix-suggestion | μ·¨μ½μ μ λν μμ λ μ½λ μλ μμ± |
generate-security-report | Mermaid λ€μ΄μ΄κ·Έλ¨ + SARIF + CVE μ 보 μ’
ν© λ¦¬ν¬νΈ |
scan-in-sandbox | Docker 격리 νκ²½μμ μμ νκ² μ€μΊ μ€ν |
bash
npm install -g security-scanner-mcp
`
$3
`bash
git clone https://github.com/ongjin/security-scanner-mcp.git
cd security-scanner-mcp
npm install && npm run build
`
Claude Codeμ λ±λ‘
`bash
npm μ μ μ€μΉ ν
claude mcp add --scope project security-scanner -- security-scanner-mcp
λλ μμ€μμ λΉλν κ²½μ°
claude mcp add --scope project security-scanner -- node /path/to/security-scanner-mcp/dist/index.js
`
λΉ λ₯Έ μ€μ (λꡬ μλ νμ©)
λ§€λ² λꡬ μ¬μ© μΉμΈμ λλ₯΄λ κ²μ΄ λ²κ±°λ‘λ€λ©΄, μλ λ°©λ²μΌλ‘ μλ νμ©μ μ€μ νμΈμ.
$3
1. Claude μ±μ μ¬μμν©λλ€.
2. security-scanner λꡬλ₯Ό μ¬μ©νλ 첫 λ²μ§Έ μ§λ¬Έμ λμ§λλ€.
3. μλ¦Όμ°½μ΄ λ¨λ©΄ "Always allow requests from this server" 체ν¬λ°μ€λ₯Ό ν΄λ¦νκ³ Allowλ₯Ό λλ₯΄μΈμ.
(μ΄νμλ λ¬»μ§ μκ³ μ€νλ©λλ€.)
$3
ν°λ―Έλ νκ²½(claude λͺ
λ Ήμ΄)μ μ¬μ© μ€μ΄λΌλ©΄ κΆν κ΄λ¦¬ λͺ
λ Ήμ΄λ₯Ό μ¬μ©νμΈμ.
1. ν°λ―Έλμμ claudeλ₯Ό μ€νν©λλ€.
2. ν둬ννΈ μ
λ ₯μ°½μ /permissionsλ₯Ό μ
λ ₯νκ³ μν°λ₯Ό μΉ©λλ€.
3. Global Permissions (λλ Project Permissions) > Allowed Toolsλ₯Ό μ νν©λλ€.
4. mcp__security-scanner__scan-securityλ§ μ
λ ₯νκ±°λ, λͺ¨λ λꡬλ₯Ό νμ©νλ €λ©΄ mcp__security-scanner__*λ₯Ό μ
λ ₯ν©λλ€.
> π‘ Tip: λλΆλΆμ κ²½μ° scan-security νλλ§ νμ©ν΄λ μΆ©λΆν©λλ€. μ΄ λκ΅¬κ° λͺ¨λ 보μ κ²μ¬λ₯Ό ν΅ν©ν΄μ μννκΈ° λλ¬Έμ
λλ€.
μ¬μ© μμ
$3
`
λ: μ΄ μ½λ 보μ κ²μ¬ν΄μ€
const apiKey = "AIzaSyC1234567890abcdef";
const query = SELECT * FROM users WHERE id = ${userId};
element.innerHTML = userInput;
Claude: [scan-security νΈμΆ]
β οΈ λ³΄μ μ·¨μ½μ λ°κ²¬!
$3
- Google API Key (λΌμΈ 1)
- Google API Keyκ° μ½λμ νλμ½λ©λμ΄ μμ΅λλ€
- π‘ ν΄κ²°μ±
: νκ²½λ³μλ‘ κ΄λ¦¬νκ³ , API ν€ μ ν μ€μ νκΈ°
$3
- Template Literal SQL (λΌμΈ 2)
- ν
νλ¦Ώ 리ν°λ΄λ‘ SQL 쿼리μ λ³μλ₯Ό μ½μ
νκ³ μμ΅λλ€
- π‘ ν΄κ²°μ±
: Prepared Statementλ₯Ό μ¬μ©νμΈμ
- innerHTML Assignment (λΌμΈ 3)
- innerHTMLμ λμ κ°μ ν λΉνκ³ μμ΅λλ€
- π‘ ν΄κ²°μ±
: textContentλ₯Ό μ¬μ©νκ±°λ DOMPurifyλ‘ sanitizeνμΈμ
`
$3
`
λ: innerHTML μ·¨μ½μ μμ μ½λ 보μ¬μ€
Claude: [get-fix-suggestion νΈμΆ]
β
μμ λ μ½λ
// β Before (μ·¨μ½)
element.innerHTML = userInput;
// β
After (μμ )
element.textContent = userInput;
// λλ HTMLμ΄ νμν κ²½μ°:
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userInput);
`
$3
`
λ: Dockerfile 보μ κ²μ¬ν΄μ€
Claude: [scan-iac νΈμΆ]
π³ Dockerfile 보μ μ·¨μ½μ λ°κ²¬!
$3
- DOC001: root μ¬μ©μλ‘ μ€ν
- π‘ ν΄κ²°μ±
: USER λͺ
λ ΉμΌλ‘ non-root μ¬μ©μ μ€μ
- DOC005: νλμ½λ©λ μν¬λ¦Ώ
- π‘ ν΄κ²°μ±
: ARGμ λΉλ μν¬λ¦Ώ μ¬μ©
$3
- DOC002: latest νκ·Έ μ¬μ©
- π‘ ν΄κ²°μ±
: λͺ
μμ λ²μ νκ·Έ μ¬μ© (μ: node:20-alpine)
...
`
$3
`
λ: μ 체 보μ 리ν¬νΈλ₯Ό Mermaid λ€μ΄μ΄κ·Έλ¨μΌλ‘ 보μ¬μ€
Claude: [generate-security-report νΈμΆ]
π‘οΈ λ³΄μ μ€μΊ λμ보λ
π μ 체 μμ½
μ΄ 8κ°μ μ·¨μ½μ μ΄ λ°κ²¬λμμ΅λλ€.
π― μ¬κ°λλ³ λΆν¬
`mermaid
pie title μ¬κ°λλ³ μ·¨μ½μ λΆν¬
"π΄ Critical" : 2
"π High" : 3
"π‘ Medium" : 2
"π’ Low" : 1
\`
βοΈ κ°λ₯ν 곡격 μλ리μ€
`mermaid
flowchart TD
Start([곡격μ]) --> Recon[μ μ°°]
Recon --> Secrets[νλμ½λ©λ
μν¬λ¦Ώ λ°κ²¬]
Secrets --> Access[μΈμ¦ μ°ν]
...
\`
+ SARIF 리ν¬νΈ (GitHub Code Scanning νΈν)
+ CVE/OWASP μμΈ μ 보
`
$3
`
λ: μ΄ μ½λλ₯Ό μλλ°μ€μμ μμ νκ² κ²μ¬ν΄μ€
Claude: [scan-in-sandbox νΈμΆ]
π³ μλλ°μ€ μ€μΊ κ²°κ³Ό
β
μ€μΊ μλ£
$3
- λ©λͺ¨λ¦¬ μ ν: 512MB
- CPU μ ν: 0.5 μ½μ΄
- νμμμ: 30000ms
- λ€νΈμν¬: λΉνμ±ν
- κΆν: μ΅μ κΆν
`
κ²μΆνλ μ·¨μ½μ
$3
- AWS Access Key / Secret Key
- Google API Key / OAuth Secret
- GitHub Token / Slack Token
- Database Connection String
- Private Key (RSA, EC λ±)
- JWT Token
- Kakao / Naver API Key
- Stripe / Twilio API Key
$3
- SQL Injection (λ¬Έμμ΄ μ°κ²°, ν
νλ¦Ώ 리ν°λ΄)
- NoSQL Injection (MongoDB)
- Command Injection (exec, spawn)
- LDAP Injection
$3
- dangerouslySetInnerHTML (React)
- innerHTML / outerHTML
- jQuery .html() / Vue v-html
- eval() / new Function()
- document.write()
$3
- μ½ν ν΄μ (MD5, SHA1)
- μμ νμ§ μμ λλ€ (Math.random)
- νλμ½λ©λ μνΈν ν€/IV
- SSL μΈμ¦μ κ²μ¦ λΉνμ±ν
- μ·¨μ½ν TLS λ²μ (1.0, 1.1)
$3
- JWT μ€μ μ€λ₯ (none μκ³ λ¦¬μ¦, λ§λ£ μμ)
- μμ νμ§ μμ μΏ ν€ μ€μ
- CORS μμΌλμΉ΄λ
- μ½ν λΉλ°λ²νΈ μ μ±
$3
- Path Traversal
- μνν νμΌ μμ
- μμ νμ§ μμ νμΌ μ
λ‘λ
- Zip Slip (Java)
- Pickle μμ§λ ¬ν (Python)
$3
Dockerfile (CIS Docker Benchmark):
- root μ¬μ©μλ‘ μ€ν
- νλμ½λ©λ μν¬λ¦Ώ
- latest νκ·Έ μ¬μ©
- λΆνμν ν¬νΈ λ
ΈμΆ
- ν¬μ€μ²΄ν¬ λλ½
Kubernetes (Pod Security Standards):
- Privileged 컨ν
μ΄λ
- Root μ€ν
- Host λ€νΈμν¬/PID/IPC μ¬μ©
- μνν Capability μΆκ°
- Resource limit λ―Έμ€μ
Terraform (Multi-Cloud):
- κ³΅κ° IP ν λΉ
- μνΈν λ―Έμ€μ
- λ°©νλ²½ μ 체 μ€ν (0.0.0.0/0)
- Public μ κ·Ό κ°λ₯ 리μμ€
$3
- npm audit μ°λ
- Python requirements.txt κ²μ¬
- Go go.mod κ²μ¬
μ§μ μΈμ΄
- β
JavaScript / TypeScript
- β
Python
- β
Java
- β
Go
- β
Dockerfile
- β
Kubernetes YAML
- β
Terraform HCL
π¨ 리ν¬νΈ ν¬λ§·
- Markdown: μ½κΈ° μ¬μ΄ ν
μ€νΈ 리ν¬νΈ
- Mermaid: μκ°ν λ€μ΄μ΄κ·Έλ¨ (Pie, Bar, Flowchart)
- SARIF: GitHub Code Scanning / VS Code νΈν ν¬λ§·
- CVE Enrichment: NVD λ°μ΄ν°λ² μ΄μ€ μ°λ
- OWASP Mapping: OWASP Top 10:2021 + CWE λ§€ν
π³ Docker μλλ°μ€
μ
μμ μΈ μ½λλ‘λΆν° νΈμ€νΈλ₯Ό 보νΈνκΈ° μν΄ Docker 격리 νκ²½μμ μ€μΊμ μ€νν μ μμ΅λλ€.
$3
#### Docker Hubμμ pull (κΆμ₯)
`bash
미리 λΉλλ μ΄λ―Έμ§ λ€μ΄λ‘λ (Trivy, GitLeaks, Checkov ν¬ν¨)
docker pull ongjin/security-scanner-mcp:latest
docker tag ongjin/security-scanner-mcp:latest security-scanner-mcp:latest
`
ν¬ν¨λ μΈλΆ 보μ λꡬ:
- Trivy v0.50.4 - 컨ν
μ΄λ/IaC μ·¨μ½μ μ€μΊλ
- GitLeaks v8.18.4 - μν¬λ¦Ώ νμ§
- Checkov - Infrastructure as Code 보μ μ€μΊλ
#### μμ€μμ μ§μ λΉλ (μ νμ¬ν)
`bash
npm run docker:build
`
> μ°Έκ³ : λΉλμλ 5-10λΆ μ λ μμλλ©°, μ΄λ―Έμ§ ν¬κΈ°λ μ½ 500MBμ
λλ€.
$3
Claude Codeμμ:
`
scan-in-sandbox νΈμΆ
`
보μ μ€μ :
- λ©λͺ¨λ¦¬ μ ν: 128MB ~ 2GB
- CPU μ ν: 0.1 ~ 2.0 μ½μ΄
- νμμμ: 5μ΄ ~ 5λΆ
- λ€νΈμν¬: κΈ°λ³Έ λΉνμ±ν
- νμΌμμ€ν
: μ½κΈ° μ μ©
- κΆν: μ΅μ κΆν (no-new-privileges, drop all capabilities)
λ°λͺ¨
`bash
λ°λͺ¨ μ€ν
npm run demo
`
μν€ν
μ²
`
src/
βββ index.ts # MCP μλ² (12κ° λꡬ)
βββ scanners/ # μ½λ μ€μΊλ (8κ°)
β βββ secrets.ts
β βββ injection.ts
β βββ xss.ts
β βββ ...
βββ iac-scanners/ # IaC μ€μΊλ (3κ°)
β βββ dockerfile.ts # 15κ° κ·μΉ
β βββ kubernetes.ts # 13κ° κ·μΉ
β βββ terraform.ts # 15κ° κ·μΉ
βββ remediation/ # μλ μμ
β βββ code-fixer.ts # AST κΈ°λ° μ½λ λ³ν
β βββ templates/ # μμ ν
νλ¦Ώ
βββ reporting/ # 리ν¬ν
β βββ mermaid-generator.ts # λ€μ΄μ΄κ·Έλ¨ μμ±
β βββ sarif-generator.ts # SARIF ν¬λ§·
β βββ markdown-formatter.ts
βββ external/ # μΈλΆ API
β βββ cve-lookup.ts # NVD API μ°λ
β βββ owasp-database.ts # OWASP Top 10 DB
βββ sandbox/ # μλλ°μ€
βββ docker-manager.ts # Docker μ€ν κ΄λ¦¬
`
π₯οΈ CLI λͺ¨λ (CI/CD ν΅ν©)
Claude μμ΄ λ
립μ μΌλ‘ μ€νν μ μλ CLI λͺ¨λλ₯Ό μ 곡ν©λλ€. Jenkins, GitHub Actions, GitLab CI λ± μ΄λμλ μ¬μ© κ°λ₯ν©λλ€.
$3
`bash
νμΌ μ€μΊ
npx security-scanner-mcp scan ./src/app.js
λλ ν 리 μ€μΊ
npx security-scanner-mcp scan ./src
κ²°κ³Όλ₯Ό νμΌλ‘ μ μ₯
npx security-scanner-mcp scan ./src --output report.txt
`
$3
`bash
JSON ν¬λ§· (νμ±μ©)
npx security-scanner-mcp scan ./src --format json
SARIF ν¬λ§· (GitHub Code Scanning νΈν)
npx security-scanner-mcp scan ./src --format sarif --output report.sarif
`
$3
`bash
Critical μ·¨μ½μ λ°κ²¬ μ λΉλ μ€ν¨ (exit code 1)
npx security-scanner-mcp scan ./src --fail-on critical
High μ΄μ μ·¨μ½μ λ°κ²¬ μ λΉλ μ€ν¨
npx security-scanner-mcp scan ./src --fail-on high
νΉμ νμΌλ§ ν¬ν¨
npx security-scanner-mcp scan ./src --include ".ts,.js"
νΉμ ν΄λ μ μΈ
npx security-scanner-mcp scan ./src --exclude "node_modules,dist,test"
`
$3
`groovy
pipeline {
agent any
stages {
stage('Security Scan') {
steps {
sh 'npx security-scanner-mcp scan ./src --format json --output security-report.json --fail-on high'
}
}
}
post {
always {
archiveArtifacts artifacts: 'security-report.json', fingerprint: true
}
}
}
`
$3
`yaml
name: Security Scan
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Security Scan
run: npx security-scanner-mcp scan ./src --format sarif --output results.sarif --fail-on critical
- name: Upload SARIF to GitHub
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: results.sarif
`
$3
`yaml
security_scan:
stage: test
script:
- npx security-scanner-mcp scan ./src --format json --output gl-security-report.json --fail-on high
artifacts:
reports:
security: gl-security-report.json
``