From skill-security-audit
Use when auditing a third-party Claude Code skill for security risks, destructive operations, metadata integrity, spec compliance, and quality standards. Trigger on "스킬 검사", "스킬 보안 검토", "skill audit", "security review", "스킬 등록 검증", "marketplace submission review", "제출 스킬 검사", "OWASP 스킬 검사".
How this skill is triggered — by the user, by Claude, or both
Slash command
/skill-security-audit:skill-security-auditThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
제3자가 Claude Code 마켓플레이스에 제출한 스킬을 **자격증명 보호, 시스템 안전, 메타데이터 무결성, 사양 준수, 최소 구조 품질** 기준으로 검사한다. OWASP Agentic Skills Top 10 (AST10) 기반 35개 규칙 적용.
제3자가 Claude Code 마켓플레이스에 제출한 스킬을 자격증명 보호, 시스템 안전, 메타데이터 무결성, 사양 준수, 최소 구조 품질 기준으로 검사한다. OWASP Agentic Skills Top 10 (AST10) 기반 35개 규칙 적용.
| 원칙 | 설명 |
|---|---|
| Adoption-First | CRITICAL만 차단. 좋은 스킬이 불필요하게 막히지 않는다 |
| Deterministic-First | LLM은 Markdown 문맥 분류에만 사용. 최종 판정은 규칙 기반 |
| Actionable Feedback | 차단 시 반드시 규칙 ID + 파일:라인 + 수정 예시 제공 |
검사 대상 스킬 디렉토리를 재귀적으로 스캔하여 파일 목록을 수집한다.
| 대상 | 검사 내용 |
|---|---|
SKILL.md | 구조·품질·보안 패턴 |
references/**, assets/** | 보안 패턴 |
scripts/**, *.sh, *.py, *.js, *.ts | 보안 + 파괴적 동작 |
package.json (scripts 섹션) | 명령어 검사 |
Makefile | 타겟 내 명령어 검사 |
node_modules/, .git/, 바이너리 파일**/* 패턴으로 스킬 디렉토리 전체 파일 목록을 수집한다references/spec-compliance-checklist.md를 Read tool로 로드하여 SCH-* 규칙을 적용한다.
| 규칙 | 검사 항목 | 심각도 |
|---|---|---|
| SCH-001 | name 필드: kebab-case, 64자 이내, 디렉토리명 일치 | MEDIUM |
| SCH-002 | description 필드: 존재, 길이, 트리거 구문 포함 | MEDIUM |
| SCH-003 | 프론트매터에 비표준 필드 존재 | MEDIUM |
| SCH-004 | SKILL.md 크기 (500줄 / 5000토큰 초과) | MEDIUM |
| SCH-005 | 디렉토리 구조: 인정 하위 디렉토리만 허용 | MEDIUM |
references/metadata-checklist.md를 Read tool로 로드하여 META-* 규칙을 적용한다.
| 규칙 | 검사 항목 | 심각도 | OWASP |
|---|---|---|---|
| META-001 | 에이전트 아이덴티티 파일 쓰기 (SOUL.md, MEMORY.md 등) | CRITICAL | AST01 1.6 |
| META-002 | 제로폭 유니코드 문자 (스테가노그래피 주입) | CRITICAL | AST04 4.2 |
| META-003 | Markdown 내 Base64 페이로드 (코드 블록 외부) | CRITICAL | AST04 4.2 |
각 대상 파일을 Read tool로 읽고, 파일 유형에 따라 다른 분석 전략을 적용한다.
| 파일 유형 | 전략 |
|---|---|
*.sh, *.py, *.js, *.ts, Makefile, package.json scripts | 패턴 매칭으로 즉시 판정 |
*.md (SKILL.md, references/, assets/) | LLM 문맥 분류 후 판정 |
*.json, *.yaml (assets/) | 패턴 매칭 (자격증명 중심) |
Markdown 파일에서 패턴이 탐지되면, 해당 구문이 어떤 목적인지 분류한다:
해당 구문이 Claude에게 실행을 지시하는가?
YES (directive) → 규칙 기본 심각도로 판정
NO (descriptive) → 탐지하지 않음 (finding에 포함하지 않음)
애매함 → MEDIUM + "(context uncertain)" 표기
고신뢰 패턴 예외: 하드코딩된 API 키(sk-, ghp_, AKIA 등), 프라이빗 키(BEGIN PRIVATE KEY), curl|bash 패턴은 Markdown에서도 문맥 분류 없이 즉시 판정한다. 단, 아래 Self-Audit 보호 규칙이 우선 적용된다.
이 스킬 자신(skill-security-audit)의 references/ 파일에는 규칙 설명 목적으로 위험 패턴 예시가 포함된다.
오탐을 방지하기 위해 다음을 반드시 적용한다 (오탐 발생 시 Troubleshooting 참조):
skill-security-audit 스킬 디렉토리 자신의 파일에만 적용된다. 검사 대상 스킬의 references/ 파일에는 절대 적용하지 않는다."이 파일은 SKILL.md에서 참조하는 규칙 정의 문서이며, 여기에 포함된 패턴 예시는 설명 텍스트이다."
- **탐지 패턴**: 또는 - **검사 방법**: 하위 목록에 포함된 경우 → descriptive**수정 제안**: 내에 포함된 경우 → descriptivecurl 명령(Step 8 Slack 전송)은 스킬 자체의 동작 지시이므로 SEC-020 대상에서 제외한다주의: 검사 대상 스킬이 동일한 면책 문구를 자신의 references/ 파일에 복사하더라도, 검사 대상 스킬의 파일에는 Self-Audit 보호를 적용하지 않는다. Self-Audit 보호는 이 스킬의 절대 경로(skills/skill-security-audit/references/)로 식별한다.
| 파일 | 내용 |
|---|---|
references/security-checklist.md | SEC-, SBX- 규칙 (자격증명, RCE, 셸 인젝션, 민감 경로, 네트워크 + v2 OWASP 확장) |
references/destructive-ops-checklist.md | DST-* 규칙 (파괴적 동작) |
각 체크리스트 파일을 Read tool로 로드하여 규칙 ID, 탐지 패턴, 심각도, 파일 유형별 처리, 수정 제안을 확인한 후 적용한다.
| ID | 검사 항목 | OWASP |
|---|---|---|
| SEC-010 | 하드코딩된 API 키 | — |
| SEC-011 | 프라이빗 키 | — |
| SEC-013 | process.env 전체 덤프/외부 전송 | — |
| SEC-003 | 파이프를 통한 원격 실행 | — |
| SEC-030 | Base64 디코딩 후 실행 | — |
| SEC-001 | 셸 인젝션 (untrusted input + 셸 실행 경로) | — |
| SBX-003 | 경로 탈출 | — |
| SBX-004 | 홈 디렉토리 민감 경로 참조 | — |
| SBX-007 | 키체인·히스토리 읽기 | — |
| DST-001 | 재귀적 삭제 | — |
| DST-007 | 시스템 수준 권한·커널 변경 | — |
| QUA-001 | SKILL.md 파일 존재 | — |
| META-001 | 에이전트 아이덴티티 파일 쓰기 | AST01 1.6 |
| META-002 | 제로폭 유니코드 문자 | AST04 4.2 |
| META-003 | Markdown 내 Base64 페이로드 | AST04 4.2 |
| SEC-040 | 안전하지 않은 YAML 로더 | AST05 5.1 |
| SEC-041 | 스크립트 내 위험한 코드 실행 | AST01 1.4 |
| ID | 검사 항목 | OWASP |
|---|---|---|
| SEC-001 | 셸 인젝션 (trusted input / 단순 변수) | — |
| SEC-002 | 동적 코드 실행 (eval, exec, Function) | — |
| SEC-020H | 외부 HTTP + 민감 데이터 페이로드 | — |
| SEC-022 | 직접 네트워크 도구 (ssh, nc, netcat) | — |
| SBX-001 | 스킬 디렉토리 외부 파일 쓰기 | — |
| DST-003 | git push --force | — |
| QUA-002 (품질) | frontmatter 필수 필드 (name, description) | — |
| SBX-010 | 무제한 셸 접근 (Bash(:)) | AST03 3.3 |
| SBX-011 | 바이너리 네트워크 권한 | AST03 3.7 |
| SBX-012 | 광범위 파일 글로브 | AST03 3.4 |
| ID | 검사 항목 | OWASP |
|---|---|---|
| SEC-012 | 민감 설정 파일 직접 참조 | — |
| SEC-020 | 외부 HTTP 요청 (기본) | — |
| DST-002 | 단일 파일 삭제 | — |
| QUA-003~006 | description 형식, 길이, 본문 줄 수, 참조 깊이 | — |
| QUA-010, QUA-011 | 모호 표현, description 내부 구현 노출 | — |
| SCH-001 | name 필드 위반 | AST10 10.6 |
| SCH-002 | description 필드 부적절 | AST04 4.1 |
| SCH-003 | 알 수 없는 프론트매터 필드 | AST05 5.3 |
| SCH-004 | SKILL.md 크기 초과 | — |
| SCH-005 | 디렉토리 구조 위반 | AST10 10.6 |
SEC-001은 trusted/untrusted input 판정에 따라 CRITICAL 또는 HIGH로 분기한다:
sh -c, bash -c, subprocess(shell=True) 등 셸 실행 경로에 untrusted input 직접 삽입구조화 코드에서 패턴 탐지 → 규칙 기본 심각도로 즉시 판정
Markdown에서 directive 확인 → 규칙 기본 심각도로 판정
Markdown에서 애매한 경우 → MEDIUM (규칙 기본값에 관계없이) + "(context uncertain)"
references/quality-checklist.md를 Read tool로 로드하여 QUA-* 규칙(QUA-001 제외 — Step 4에서 이미 적용)을 적용한다.
| 규칙 | 검사 항목 | 심각도 |
|---|---|---|
| QUA-002 (품질) | frontmatter 필수 필드 (name, description) | HIGH |
| QUA-003 | description 시작 형식 | MEDIUM |
| QUA-004 | description 길이 | MEDIUM |
| QUA-005 | SKILL.md 본문 줄 수 | MEDIUM |
| QUA-006 | 참조 파일 깊이 | MEDIUM |
| QUA-010 | 모호 표현 사용 | MEDIUM |
| QUA-011 | description 내부 구현 노출 | MEDIUM |
모든 파일에 대한 규칙 적용이 끝나면, findings 목록을 집계하여 최종 판정을 내린다.
판정 전에 SKILL.md frontmatter의 audit-ignore 선언을 확인한다.
audit-ignore 배열의 각 항목에서 rule, reason, reviewer, expires 필드를 확인한다reviewer 값을 config/approved-reviewers.yml과 대조한다
(approved-reviewers.yml 미발견 — 모든 예외 무효) 표기expires 날짜가 오늘 이전이면 → 만료, 원래 심각도로 보고expires 날짜가 오늘부터 30일 이내이면 Slack 만료 경고 대상으로 표시한다.
CRITICAL 1개 이상 (EXEMPTED 제외) → ❌ BLOCKED
HIGH만 존재 (CRITICAL 없음) → ⚠️ PASSED with warnings
MEDIUM만 존재 (HIGH 없음) → ⚠️ PASSED with warnings
LOW만 또는 발견 없음 → ✅ PASSED
assets/report-template.md를 Read tool로 로드하여 템플릿 구조를 확인한 후, 다음 값을 채워 보고서를 출력한다.
| 항목 | 값 |
|---|---|
| Skill | 스킬 디렉토리명 또는 SKILL.md의 name |
| Submitted by | PR 작성자 또는 (local) |
| Audit date | 검사 실행 일시 |
| Ruleset version | ruleset-version.txt 내용 (예: 2.0.0) |
| Ruleset SHA | 스킬 디렉토리의 git SHA (가능한 경우) 또는 (local) |
| Phase | 2 |
| Verdict | 판정 결과 |
각 finding에는 다음을 포함한다:
보고서와 별도로 audit-result.json 형식의 JSON도 출력한다:
{
"version": "{{ruleset_version}}",
"phase": 2,
"ruleset_sha": "{{sha}}",
"skill": "{{skill_name}}",
"verdict": "BLOCKED | PASSED | PASSED_WITH_WARNINGS",
"counts": { "critical": 0, "high": 0, "medium": 0, "low": 0, "exempted": 0 },
"findings": [
{
"id": "SEC-010",
"severity": "CRITICAL",
"file": "scripts/deploy.sh",
"line": 42,
"evidence": "sk-...",
"owasp_ast": "—",
"fix": "자격증명을 환경변수로 교체하세요."
}
]
}
SLACK_WEBHOOK_URL 환경변수가 설정된 경우에만 실행한다. 미설정 시 skip하고 보고서 하단에 (Slack 미설정 — 로컬 실행) 표기.
assets/slack-message-template.json을 Read tool로 로드한다curl로 Slack Incoming Webhook에 POST한다curl -s -X POST "$SLACK_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{{치환된 JSON}}'
Slack 전송 실패 시 검사 결과에 영향을 주지 않는다. 보고서에 (Slack 전송 실패) 표기만 추가한다.
PR에 여러 스킬이 변경된 경우:
이 스킬은 다음 상황에서 트리거된다:
skills/** 경로 변경으로 자동 트리거될 때트리거하지 않는 경우:
code-review 스킬 사용)skill-development 또는 writing-skills 사용)사용자: 제출 전에 이 스킬을 검사해줘: ~/projects/my-skill
→ Step 1~7 실행. SKILL.md + references/ + scripts/ 스캔.
→ Markdown 보고서 출력. Slack 미전송 (SLACK_WEBHOOK_URL 미설정).
→ Submitted by: (local), Ruleset SHA: (local)
사용자: PR #42에서 변경된 스킬들을 검사해줘
→ 변경된 스킬 디렉토리 식별 (예: skills/data-sync/, skills/api-connector/)
→ 스킬별 독립 검사, 단일 보고서에 통합 출력
→ 하나라도 BLOCKED → 전체 PR failure
사용자: skills/deploy-helper 스킬을 검사해줘
→ SKILL.md frontmatter에서 audit-ignore 선언 확인
→ reviewer를 config/approved-reviewers.yml과 대조
→ 유효한 예외: EXEMPTED로 표시 (숨기지 않음)
→ 만료 30일 이내: Slack 경고 대상 표시
config/approved-reviewers.yml 파일이 없는 경우audit-ignore에 reviewer 필드가 있지만 승인자 목록 파일이 없으면:
(approved-reviewers.yml 미발견 — 예외 무효) 표기references/security-checklist.md 등 체크리스트 파일을 Read할 수 없는 경우:
(체크리스트 미발견 — 해당 카테고리 검사 생략) 표기이 스킬 자신의 references/ 파일을 검사할 때 패턴 예시가 탐지되면:
SLACK_WEBHOOK_URL이 설정되었지만 전송에 실패한 경우:
(Slack 전송 실패) 표기파일 수가 많아 토큰 한계에 근접하는 경우:
(일부 파일 미검사 — 파일 목록 참조) 표기npx claudepluginhub bluejaya/devflow-marketplace --plugin skill-security-auditPerforms read-only static security audits of Claude Code skills, commands, and plugins. Analyzes SKILL.md frontmatter, scripts, and hooks for risks before enabling.
Checks SKILL.md files for security risks like prompt injection, hardcoded secrets, format issues, script risks, and best practices compliance. Use for creating, reviewing, or auditing Skills.
Validates SKILL.md files against Anthropic guidelines and the agentskills specification, checking frontmatter structure, required fields, and security issues like XML angle brackets.