sast-skills은(는) 무엇을 하나요?
LLM 코딩 어시스턴트를 완전한 기능의 SAST 스캐너로 바꿔보세요. Claude Code, Codex, Opencode, Cursor 등 CLAUDE.md / AGENTS.md 스킬 폴더를 로드하는 모든 어시스턴트에 바로 적용 가능한 에이전트 스킬입니다.
Claude Code + Opus 조합이 품질 측면에서 권장되지만, 모든 역량 있는 모델에서 작동합니다.
주요 특징
- 28가지 취약점 클래스에 걸친 31개 스킬 — 인젝션, 취약한 접근 제어, 취약한 암호화, 파일 처리, 공급망, 비즈니스 로직, LLM 특화 위협(프롬프트 인젝션, 안전하지 않은 출력 처리).
- 4단계 오케스트레이션 — 정찰 → 병렬 탐지 → 종합 리포트 → 증거 기반 분류. 전적으로
CLAUDE.md/AGENTS.md에서 구동됩니다. - 멱등성 및 재개 가능 — 각 단계는 출력 파일이 이미 존재하면 작업을 건너뜁니다. 문제를 수정한 후 다시 실행하면 변경된 부분만 새로고침합니다.
- 머신 리더블 출력 — 모든 스킬이 표준 JSON을 출력합니다.
sast-skills export명령어로 JSON, SARIF 2.1.0, HTML로 집계하여 GitHub Code Scanning 및 CI와 연동할 수 있습니다. - 크로스 어시스턴트 — Claude Code용 (
.claude/skills) 및 모든AGENTS.md어시스턴트용 (.agents/skills) 동일한 스킬이 제공됩니다. - 설정 제로 CLI —
install/update/uninstall/doctor/export명령어를 제공하며, GitHub Actions에서 npm 증명(SLSA 증명)과 함께 배포됩니다.
흐름
오케스트레이터는 정찰, 병렬 탐지, 종합, 분류의 네 단계를 실행합니다:
flowchart TD
U(["사용자: 취약점 스캔 실행"]) --> R{"CLAUDE.md / AGENTS.md 오케스트레이터"}
R --> S1["단계 1 — sast-analysis<br/>코드베이스 및 아키텍처 맵"]
S1 -->|sast/architecture.md| S2["단계 2 — 병렬 취약점 스캔<br/>28개 스킬: 정찰, 배치 검증, 병합"]
S2 -->|sast/*-results.md 및 *-results.json| S3["단계 3 — sast-report<br/>통합 및 순위 지정"]
S3 -->|sast/final-report.md| S4["단계 4 — sast-triage<br/>오탐 제거,<br>심각도 조정 및 증거 기반 분류"]
S4 -->|sast/final-report-triaged.md 및 triaged.json| EXP["npx sast-skills export<br/>JSON, SARIF, HTML"]
EXP --> CS(["GitHub Code Scanning, CI, 대시보드"])
모든 단계는 멱등성을 가집니다. 출력 파일이 이미 존재하면 오케스트레이터가 해당 단계를 건너뜁니다. 문제를 수정한 후 스캔을 다시 실행하면 변경된 부분만 새로고침됩니다.
탐지 항목
모든 스킬은 동일한 3단계 패턴을 따릅니다: 정찰 → 배치 검증 (병렬 서브에이전트, 배치당 3개) → 병합. 각 스킬은 사람이 읽을 수 있는 마크다운 리포트와 sast-skills export가 집계하는 표준 JSON 결과 파일을 작성합니다.
정찰 및 종합
| 스킬 | 역할 |
|---|---|
sast-analysis | 코드베이스 정찰, 아키텍처 매핑, 위협 모델 |
sast-report | 분류별 결과를 통합하여 순위가 매겨진 리포트 생성 |
sast-triage | 오탐 제거 및 코드베이스 증거에 기반한 심각도 조정 |
인젝션
| 스킬 | 취약점 클래스 |
|---|---|
sast-sqli | SQL 인젝션 |
sast-nosql | NoSQL 인젝션 (Mongo, Firestore, DynamoDB) |
sast-ldap | LDAP 필터 / DN 인젝션 |
sast-graphql | 안전하지 않은 GraphQL 문서 구성 |
sast-xss | 크로스 사이트 스크립팅 |
sast-ssti | 서버 사이드 템플릿 인젝션 |
sast-rce | 원격 코드 실행 (명령 인젝션, eval, 안전하지 않은 역직렬화) |
sast-xxe | XML 외부 엔티티 |
sast-ssrf | 서버 사이드 요청 위조 |
sast-openredirect | 오픈 리다이렉트 (피싱 / OAuth 토큰 탈취) |
접근 제어 및 인증
| 스킬 | 취약점 클래스 |
|---|---|
sast-idor | 안전하지 않은 직접 객체 참조 |
sast-missingauth | 인증 누락 / 취약한 함수 수준 권한 부여 |
sast-jwt | 안전하지 않은 JWT 구현 |
sast-csrf | 사이트 간 요청 위조 |
sast-cors | CORS 잘못된 구성 |
파일, 암호화 및 런타임
| 스킬 | 취약점 클래스 |
|---|---|
sast-pathtraversal | 경로 / 디렉터리 트래버설 |
sast-fileupload | 안전하지 않은 파일 업로드 |
sast-crypto | 취약한 프리미티브, 잘못된 모드, IV 재사용, 취약한 PRNG |
sast-prototype | JavaScript 프로토타입 오염 |
sast-redos | 치명적 역추적 정규식 DoS |
sast-race | 경쟁 조건 및 TOCTOU |
데이터 노출 및 공급망
| 스킬 | 취약점 클래스 |
|---|---|
sast-hardcodedsecrets | 클라이언트 측 코드의 API 키 / 토큰 / 자격 증명 |
sast-pii | 로그 / 원격 분석 / 오류 페이지로의 PII 및 자격 증명 누출 |
sast-deps | 알려진 취약점이 있는 종속성 (잠금 파일의 CVE) |
sast-iac | 안전하지 않은 IaC (Dockerfile / Terraform / Kubernetes / GitHub Actions) |
비즈니스 로직 및 LLM 특화
| 스킬 | 취약점 클래스 |
|---|---|
sast-businesslogic | 가격 조작, 워크플로 우회, 보상 남용 |
sast-promptinjection | LLM 프롬프트에 도달하는 신뢰할 수 없는 텍스트 (OWASP LLM #1) |
sast-llmoutput | 코드 / HTML / SQL / 셸 싱크에 도달하는 검증되지 않은 LLM 출력 (OWASP LLM #2) |
설치
npx sast-skills install
설치 프로그램은 대상 어시스턴트(claude / agents / all)와 설치 범위(현재 프로젝트 또는 사용자 홈 디렉터리, project / global)를 묻습니다. 프롬프트를 건너뛰려면:
npx sast-skills install --yes --assistant claude --scope project
프로젝트에 이미
CLAUDE.md또는AGENTS.md가 있는 경우, 설치 프로그램은 기본적으로 덮어쓰기를 거부합니다. 백업 후--force플래그를 사용하세요.
수동 설치 (npx / npm 없이)
npx를 실행할 수 없는 경우 (기업 프록시, npm 레지스트리 접근 불가, 오프라인 환경) 또는 게시된 npm 패키지 대신 이 포크의 소스를 고정하고 싶은 경우 이 방법을 사용하세요. CLI 설치 프로그램은 두 가지 작업만 수행합니다 — 프로젝트 루트에 오케스트레이터 진입 파일을 넣고 각 스킬의 SKILL.md를 적절한 숨김 디렉터리에 복사하는 것입니다. 따라서 간단한 cp -R로도 정확히 재현할 수 있습니다.
1. 번들 파일 가져오기
git clone https://github.com/mstfknn/sast-skills.git
필요한 모든 것은 sast-skills/sast-files/ 디렉터리에 있습니다:
sast-files/
├── CLAUDE.md # Claude Code용 오케스트레이터 진입 파일
├── AGENTS.md # Gemini CLI / Codex / OpenCode / Cursor용 오케스트레이터 진입 파일
├── .claude/skills/sast-*/SKILL.md # Claude Code 형식의 31개 스킬
└── .agents/skills/sast-*/SKILL.md # AGENTS.md 어시스턴트를 위해 미러링된 동일한 31개 스킬
두 스킬 트리는 npm run sync 명령어로 동기화됩니다 — 내용은 동일하며 디렉터리 이름만 다릅니다.
2a. Claude Code용 설치
export SAST_SRC=/절대/경로/sast-skills
cd /경로/내-프로젝트
프로젝트 범위 (권장 — 리포지토리와 함께 버전 관리됨):
cp "$SAST_SRC/sast-files/CLAUDE.md" ./CLAUDE.md
cp -R "$SAST_SRC/sast-files/.claude" ./
이미 프로젝트 수준의
CLAUDE.md를 사용 중인 경우 덮어쓰지 마세요 — Claude Code는 프로젝트당 하나의CLAUDE.md만 읽습니다. 대신 오케스트레이터 콘텐츠(4단계 흐름)를 기존 파일에 병합하세요.
글로벌 범위 (모든 프로젝트에서 스킬 사용 가능, 오케스트레이터는 프로젝트별로 복사):
mkdir -p ~/.claude/skills
cp -R "$SAST_SRC/sast-files/.claude/skills/." ~/.claude/skills/
# 스캔 흐름을 사용할 프로젝트에서:
cp "$SAST_SRC/sast-files/CLAUDE.md" /경로/내-프로젝트/CLAUDE.md
2b. Gemini CLI (및 기타 AGENTS.md 어시스턴트)용 설치
export SAST_SRC=/절대/경로/sast-skills
cd /경로/내-프로젝트
cp "$SAST_SRC/sast-files/AGENTS.md" ./AGENTS.md
cp -R "$SAST_SRC/sast-files/.agents" ./
AGENTS.md는 Gemini CLI, Codex CLI, OpenCode, Cursor에서 사용하는 크로스 어시스턴트 규칙입니다. 사용 중인 Gemini CLI 버전이 GEMINI.md를 찾는 경우 이름을 변경하면 됩니다 — 내용은 동일합니다:
mv AGENTS.md GEMINI.md
3. 설치 확인
# 프로젝트 범위 (Claude Code)
ls CLAUDE.md && ls .claude/skills/ | head
# 프로젝트 범위 (Gemini / AGENTS.md)
ls AGENTS.md && ls .agents/skills/ | head
# 글로벌 범위 (Claude Code)
ls ~/.claude/skills/ | head
31개의 sast-* 스킬 디렉터리가 모두 보여야 합니다. 프로젝트를 어시스턴트에서 열고 **"취약점 스캔 실행"**을 프롬프트하면 CLAUDE.md / AGENTS.md 내부의 오케스트레이터가 4단계를 구동합니다.
4. 수동 설치 업데이트 유지
cd "$SAST_SRC" && git pull
# 2a / 2b 단계의 cp 명령어를 다시 실행하여 새로고침 — 멱등성 있음.
클론을 유지하면 cd "$SAST_SRC" && git pull && <cp 재실행>은 npx sast-skills update의 수동 버전입니다.
CLI 명령어
| 명령어 | 설명 |
|---|---|
npx sast-skills install | CLAUDE.md / AGENTS.md 및 스킬 트리를 프로젝트 또는 $HOME에 복사 |
npx sast-skills update | 현재 번들된 스킬 파일로 기존 설치 새로고침 |
npx sast-skills uninstall | 설치된 스킬 제거; 수정된 CLAUDE.md는 --force 없이 삭제 거부 |
npx sast-skills doctor | 설치 상태를 확인하고 파일별로 OK / MISSING / MODIFIED 보고; 문제 시 0이 아닌 값으로 종료 |
npx sast-skills export --input sast/ --format sarif --output report.sarif | sast/*-results.json을 JSON, SARIF 2.1.0 또는 HTML로 집계 |
npx sast-skills export --input sast/ --triaged --format sarif | 원시 스킬별 결과 대신 분류된 sast/triaged.json 우선 사용 |
npx sast-skills --version | 설치된 CLI 버전 출력 |
설치 플래그
| 플래그 | 용도 |
|---|---|
--yes | 비대화형; 표준 입력이 TTY가 아닌 경우 필요 |
--assistant <claude|agents|all> | 설치할 스킬 트리 선택 |
--scope <project|global> | ./.claude/skills/ 또는 $HOME/.claude/skills/에 설치 |
--target <path> | 명시적 설치 대상 (--scope 대체) |
--force | 기존 CLAUDE.md / AGENTS.md 덮어쓰기 허용 |
--dry-run | 파일 계획만 출력하고 실제 쓰기는 하지 않음 |
스캔 실행
설치 후 AI 어시스턴트에서 프로젝트를 열고 다음과 같이 요청하세요:
취약점 스캔 실행
또는
이 코드베이스에서 취약점 찾아줘
오케스트레이터가 작업을 시작합니다. 네 단계를 자동으로 실행하고 멱등성을 존중하며 (재실행 시 누락된 부분만 처리), 모든 결과를 프로젝트 루트의 sast/ 디렉터리에 씁니다.
출력 파일
| 파일 | 설명 |
|---|---|
sast/architecture.md | 기술 스택, 아키텍처, 진입점, 데이터 흐름 |
sast/*-results.md | 취약점 클래스별 결과 (사람이 읽을 수 있음) |
sast/*-results.json | 표준 머신 리더블 결과 (sast-skills export에 사용) |
sast/final-report.md | 심각도 순으로 정렬된 통합 원시 리포트 |
sast/final-report-triaged.md | 분류된 리포트 — 오탐 제거, 증거 기반 심각도 조정 |
sast/triaged.json | 표준 분류 결과 (sast-skills export --triaged에서 선호) |
결과 스키마
각 스킬은 sast/<skill>-results.json을 다음과 같은 결과 목록으로 작성합니다:
{
"findings": [
{
"id": "sast-sqli-0001",
"skill": "sast-sqli",
"severity": "critical|high|medium|low|info",
"title": "/api/user 에서 SQL 인젝션",
"description": "…",
"location": { "file": "src/api/user.js", "line": 42, "column": 10 },
"remediation": "…"
}
]
}
sast-skills export는 이러한 파일을 하나의 문서로 집계하고 run 래퍼로 감쌉니다 — { "run": { "tool": "sast-skills", "version": "<cli-version>" }, "findings": [...] }. 보고서를 생성한 CLI 버전을 기록합니다. 분류 단계는 동일한 래핑된 형식으로 sast/triaged.json을 작성합니다.
분류된 결과에는 triage_status (confirmed|upgraded|downgraded|false_positive), triage_original_severity (심각도가 변경된 경우), 그리고 구체적인 코드베이스 인용이 포함된 triage_evidence가 추가됩니다.
CI 통합
GitHub Code Scanning (SARIF)
.github/actions/scan/action.yml의 복합 액션:
- uses: mstfknn/sast-skills/.github/actions/scan@main
with:
input: sast/
output: sast-skills.sarif
sast-skills export --format sarif를 실행하고 github/codeql-action/upload-sarif@v3를 통해 Code Scanning에 결과를 업로드합니다.
Pre-commit 훅
hooks/pre-commit을 .git/hooks/pre-commit에 복사하여 sast-skills doctor가 모든 커밋을 게이트하도록 설정하세요.
Docker
docker build -t sast-skills .
docker run --rm -v "$PWD:/work" sast-skills export --input sast/ --format sarif --output report.sarif
번들된 Dockerfile은 node:20-alpine 기반이며 sast-skills가 엔트리포인트로 설정되어 있습니다.
확인 및 문제 해결
# 설치가 예상된 형태인가?
npx sast-skills doctor --target . --assistant claude
# 버전 확인
npx sast-skills --version
npm view sast-skills version # 레지스트리의 최신 버전
# 업그레이드
npx sast-skills update
doctor는 대상의 모든 번들 파일이 설치된 버전의 복사본과 일치하면 0으로 종료하고, 파일이 MISSING 또는 MODIFIED이면 1로 종료합니다. MODIFIED는 파일이 번들 복사본과 달라졌음을 의미합니다 — 진입 파일을 편집한 경우 예상된 동작이며, 그렇지 않으면 update를 실행해야 한다는 신호입니다.
기여
CONTRIBUTING.md를 참조하세요. 개발 루프:
npm install
npm test # vitest 스위트 (TDD-guard 활성화)
npm run sync # .claude/skills → .agents/skills 미러링
node scripts/scaffold-skill.js sast-foo # 두 트리에 새 스킬 스텁 생성
node scripts/register-skill.js sast-foo foo "Foo" "Foo 인젝션 설명"
npm run lint:md # markdownlint
# (선택 사항) scratch 리포지토리에서 수동 E2E 검증
echo "scratch/" >> .gitignore
npm pack --pack-destination scratch/
cd scratch && npm init -y && npm install ./sast-skills-*.tgz && npx sast-skills install --yes
# 그런 다음 Claude Code에서 열고 프롬프트: 취약점 스캔 실행
패치와 새 스킬 모두에 대해 TDD를 선호합니다. sast-skills의 각 함수는 src/ 디렉터리에 있으며 복사본은 없습니다. PR 전에 npm test && npm run lint:md를 실행하세요.
라이선스
MIT — 로고 크레딧: Flaticon의 Freepik