| name | bdev-secuaudit |
| description | 바이브코딩으로 만든 웹 프로덕트가 보안에 취약한지 감사(audit)하고, 우선순위 처방을 낸 뒤 **승인을 받아 코드에 직접 수정(fix)**까지 하는 스킬. 로컬 코드베이스 또는 배포된 URL(혹은 둘 다)을 받아 5개 영역(① 일반 해킹 취약점/OWASP ② 시크릿·키 노출 ③ 인증·인가 ④ 입력검증·인젝션 ⑤ 설정·배포)을 점검해 0~100 보안점수와 심각도(P0~P3)별 리포트를 낸다. fix 모드에서는 진단에서 끝내지 않고 .env gitignore·환경변수 분리·RLS 정책·인증 미들웨어·입력 검증·보안 헤더·CORS·소스맵 off 등을 Edit/Write로 직접 적용한다. 트리거 — "보안 점검", "내 사이트 안전한지 봐줘", "취약점 검사", "보안 감사", "해킹당할까", "시크릿 노출 확인", "bdev-secuaudit", "security audit", "RLS 확인", "API 키 노출됐나", "보안 취약점 고쳐줘". 철칙 — 실제 공격·익스플로잇은 절대 실행하지 않고(읽기/안전 프로브만), 본인 소유 자산만 점검하며, false positive를 만들지 않고, 수정은 항상 승인 후에 한다. 시크릿이 노출됐으면 수정보다 먼저 "즉시 회전(rotate)"을 경고한다. |
bdev-secuaudit — 바이브코더용 보안 감사·수정기
바이브코딩으로 빠르게 만든 프로덕트는 기능은 돌지만 보안이 비어 있는 경우가 많다. 이 스킬은 그걸 찾아내고(audit) → 우선순위로 정리하고 → 승인받아 직접 고친다(fix).
철칙 (먼저 읽기 — 어기지 말 것)
- 공격하지 않는다. 실제 익스플로잇(인젝션 페이로드 주입·인증 우회 시도·브루트포스·DoS)을 라이브 자산에 실행하지 않는다. 점검은 읽기 + 안전한 비파괴 프로브(헤더 확인, 본인 사이트의 무인증 엔드포인트를 GET으로 한 번 호출해 데이터가 나오는지 정도)만 한다.
- 본인 자산만. URL 점검은 사용자가 소유·운영하는 사이트에 한한다. 제3자 사이트 감사 요청은 거절한다.
- 정직하게 판정한다. 없는 취약점을 만들지 않는다. 확실치 않으면 "확인 필요(⚠️)"로 두고 왜 의심되는지와 어떻게 확정하는지를 적는다. 과장된 공포 마케팅 금지.
- 시크릿 노출은 수정보다 회전이 먼저. 키·토큰이 git 히스토리나 클라이언트 번들에 노출됐으면, gitignore 추가로는 이미 늦었다. **"이 키는 이미 유출된 것으로 간주하고 즉시 폐기·재발급(rotate)하라"**를 가장 먼저, 굵게 경고한다. 코드 수정은 그다음.
- 수정은 승인 후에. fix 모드라도 바꿀 파일 목록을 먼저 표로 보여주고 승인받은 항목만 Edit/Write 한다. 동작을 깨는 변경(인증 추가로 기존 흐름이 막히는 등)은 영향과 함께 미리 고지한다.
Phase 1 — 스코프 & 모드 결정
스코프 (입력에서 판별):
- 로컬 코드베이스 →
Glob/Grep/Read로 정적 분석. 가장 깊은 진단 + 직접 수정 가능.
- 배포 URL →
WebFetch로 응답 헤더·HTML·robots·노출 엔드포인트를 비파괴 점검(블랙박스).
- 둘 다 → 코드에서 찾은 취약점을 라이브에서 교차 검증(예: 코드의 무인증 라우트를 실제 GET해 데이터가 나오는지).
모드:
- audit (기본) — 진단 + 처방까지(읽기 전용).
- fix (적용) — 사용자가 "고쳐줘·수정·적용·하드닝·fix·patch" → Phase 4에서 코드를 직접 수정.
스택 감지: package.json/next.config.*/requirements.txt/supabase/ 등으로 Next.js·React·Node/Express·Python(Flask/FastAPI/Django)·Supabase·Firebase 등을 파악해 점검 포인트를 맞춘다.
한 줄 출력: bdev-secuaudit — {repo|url|둘다} / {스택} / {audit|fix} 모드
Phase 2 — 5개 영역 감사
references/audit-checklist.md의 각 항목을 점검하고 상태(✅양호 / ⚠️확인필요 / ❌취약 / —해당없음)·근거(파일:줄 또는 응답 증거)·심각도(P0~P3)를 기록한다. 빠른 1차 스윕은 references/grep-signatures.md의 패턴으로 시작한다.
- 일반 해킹 취약점 (OWASP) — 알려진 CVE 의존성(
npm audit), 안전하지 않은 역직렬화(Python pickle 류·Node vm), SSRF, 오픈 리다이렉트, 레이트리밋 부재, 위험한 동적실행 함수(eval·child_process·React raw-HTML 주입 API).
- 시크릿·키 노출 (P0 단골) —
.env가 git에 커밋됐는지, 클라이언트 번들/NEXT_PUBLIC_*에 비밀키가 박혔는지, Supabase service_role·OpenAI·Stripe secret이 프론트에 노출됐는지, 하드코딩된 비밀번호·토큰.
- 인증·인가 — Supabase RLS 미설정(가장 흔한 치명상), 무인증
/api/* 라우트, IDOR(남의 id로 접근), 클라이언트 only 권한체크(서버 검증 없음), 약한/없는 세션 검증, 관리자 라우트 무방비.
- 입력검증·인젝션 — SQL/NoSQL 인젝션(문자열 조립 쿼리), XSS(미이스케이프 렌더), 파일 업로드 검증 부재, 명령어 인젝션, 프롬프트 인젝션(LLM 앱), 과도한 페이로드 미제한.
- 설정·배포 — 보안 헤더 누락(CSP·HSTS·X-Frame-Options·X-Content-Type-Options), CORS 와일드카드(
* + credentials), 프로덕션 소스맵·스택트레이스·디버그 모드 노출, 기본 크리덴셜, 미적용 보안 업데이트, 공개 스토리지 버킷.
Phase 3 — 리포트
다음을 출력한다.
- 0~100 보안점수 + 한 줄 등급 (P0 1건당 큰 감점). 점수 산식은 정직하게 — 미점검 영역은 점수에 반영하지 말고 "미점검"으로 표기.
- 스코어카드 표: 영역 / 상태 / 핵심 근거 / 심각도(P0~P3).
- 발견 목록: 각 건마다 무엇이(파일:줄/엔드포인트) · 왜 위험한지(공격 시나리오 1줄) · 어떻게 고치는지 · 심각도.
references/fix-recipes.md 참조.
- 즉시 조치 (P0): 노출된 시크릿 회전, RLS 켜기 등 "지금 당장" 항목을 맨 위에 굵게.
- 점검하지 못한 것(블랙박스 한계 등)을 정직하게 명시.
심각도 기준: P0 = 지금 털릴 수 있음(노출 시크릿·무인증 데이터 접근·RLS off). P1 = 공격자에게 명백한 경로. P2 = 심층방어 미흡. P3 = 권장 하드닝.
Phase 4 — 수정 적용 (fix 모드: 코드에 직접)
로컬 코드베이스 + fix 모드면 처방하고 끝내지 말고 실제로 적용한다.
4-1. 적용 계획 제시 (먼저, 승인 필수)
바꿀 파일 + 변경 한 줄 설명 + 영향(동작 변화 여부)을 표로 보여주고 승인받는다. P0부터.
| 파일 | 작업 | 내용 | 영향 |
|---|
.gitignore | 수정 | .env* 무시 | 없음 |
supabase/migrations/xxx.sql | 생성 | 테이블 RLS 활성화 + 정책 | 무인증 접근 차단됨 |
next.config.js | 수정 | 보안 헤더 + 소스맵 off | 없음 |
middleware.ts | 생성 | /api/admin/* 인증 가드 | 인증 없으면 401 |
4-2. 시크릿 노출이면 — 회전 안내를 코드 수정보다 먼저
"이 키들은 유출 간주, 지금 [Supabase/Stripe/OpenAI] 대시보드에서 폐기·재발급하라"를 먼저 띄운다. gitignore·git filter-repo 히스토리 정리는 회전 후 보조 조치.
4-3. 적용 & 검증
references/fix-recipes.md의 스택별 레시피로 Edit/Write. 적용 후 가능하면 빌드/타입체크나 라이브 재프로브로 "정말 막혔는지" 확인하고, 깨진 흐름이 없는지 점검한다. 승인 안 된 항목은 처방만 남긴다.
4-4. 마무리
적용한 것 / 사용자가 직접 해야 하는 것(키 회전, 대시보드 설정, 환경변수 등록) / 남은 P1~P3을 체크리스트로 정리한다.
출력 언어
사용자가 한국어면 한국어로. 근거의 파일경로·코드·헤더명은 원문 그대로.