
Next.js, Supabase 및 Stripe 앱을 위한 로컬 정적 보안 스캐너: 유출된 키, 누락된 RLS 및 권한 부여, 안전하지 않은 웹훅을 탐지하는 24개의 AST 기반 검사. CLI 및 GitHub Action.
Next.js + Supabase + Stripe 앱을 위한 무료 로컬 보안 스캔: 유출된 키, 누락된 RLS 및 grant, 안전하지 않은 Stripe 웹훅.
당신의 AI 에이전트가 앱을 배포했습니다. 그런데 Stripe 시크릿 키, RLS가 없는 테이블, 또는 누구나 호출할 수 있는 웹훅까지 함께 배포했나요? 명령 하나로 1초 이내에 로컬에서 확인할 수 있습니다.
npx github:edtrackai/nextjs-supabase-stripe-security-checker /path/to/your/app
아직 npm에 등록되지 않았으므로, npx는 이 GitHub 저장소에서 직접 실행합니다 (Node 18+ 및 git 필요).
- uses: edtrackai/nextjs-supabase-stripe-security-checker@v0
with:
fail-on: high
전체 워크플로와 권한은 아래와 docs/github-action.md에 있습니다.
Supabase RLS 검사기 · Stripe 웹훅 보안 · Next.js 보안 스캔 · Supabase Data API 권한(42501)

git clone https://github.com/edtrackai/nextjs-supabase-stripe-security-checker.git
cd nextjs-supabase-stripe-security-checker && npm install
node bin/nss-security-check.js /path/to/your/app
Node 18 이상. 의존성은 하나(@babel/parser)입니다. 무료이며 MIT 라이선스이고, 계정이 필요 없고, 네트워크 호출을 하지 않으며 코드를 절대 업로드하지 않습니다.
--fail-on=high는 종료 코드 1을 반환하고, --json은 기계 판독 가능한 출력을 제공합니다.광고(유료, 동일 저자): 수정 방법이 필요하신가요? Launch Audit(해당되는 경우 부가세 별도 $12)은 28개 검사, Edit 또는 Write 도구가 없는 AI 감사 에이전트, 그리고 file:line 수정 계획을 추가합니다.
| 플래그 | 기능 |
|---|---|
--json | 기계 판독 가능한 출력: {tool, version, root, filesScanned, counts, findings[]} |
--fail-on=<sev> | critical / high / medium / low 이상의 발견 사항이 있으면 종료 코드 1을 반환합니다(none은 절대 실패하지 않음). 잘못된 인자일 경우 종료 코드 2를 반환합니다. |
--list | 검사 카탈로그를 출력합니다 |
--quiet | 유료 도구에 관한 한 줄 푸터를 생략합니다(터미널에서만 stderr로 출력되며, NO_PROMO=1, CI 또는 GITHUB_ACTIONS 설정 시에도 꺼집니다) |
--help | 사용법 |
CI에서: node path/to/bin/nss-security-check.js . --fail-on=high, 또는 GitHub Action을 사용하세요(작업 요약, 어노테이션, 하나의 고정 PR 코멘트, GITHUB_TOKEN만 사용). 예제 워크플로와 권한은 docs/github-action.md를 참조하세요.
# .github/workflows/security-check.yml
name: Security check
on: [pull_request]
permissions:
contents: read
pull-requests: write # only for the PR comment; drop it with comment: false
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: edtrackai/nextjs-supabase-stripe-security-checker@v0 # or pin @v0.5.0 / a commit SHA
with:
path: .
fail-on: high
변경 사항은 CHANGELOG.md에 나열되어 있습니다(0.5.0에서 Action이 추가됨).
| ID | 심각도 | 영역 | 검사 |
|---|---|---|---|
| K1 | critical | 키 | 소스에 포함된 실제 Stripe 시크릿/제한 키(sk_live_/rk_live_), +로 분할된 키 포함(증거는 마스킹됨) |
| K2 | critical | 키 | 시크릿으로 보이는 NEXT_PUBLIC_ 변수(서비스 역할, 시크릿 키, 웹훅 시크릿…) |
| K3 | critical | 키 | 값이 git에 추적되는 .env 파일 |
| K4 | critical | 키 | "use client" 컴포넌트에서 사용되는 서버 시크릿 또는 Supabase 관리자 클라이언트 |
| A1 | high | 인증 | 서버에서 getUser()/getClaims() 대신 auth.getSession()을 신뢰함 |
| A2 | high | 인증 | 인증 검사 없이 데이터를 쓰는 Server Action |
| A3 | high | 인증 | 인증 검사 없이 데이터를 쓰는 API 라우트(POST/PUT/PATCH/DELETE)(웹훅, cron, 인증 라우트 제외) |
| A4 | high | 인증 | 소유자 필터 없이 요청에서 제공된 id로 관리자 클라이언트를 조회함(IDOR) |
| A5 | medium | 인증 | 쿼리 파라미터로 인한 오픈 리다이렉트 |
| R1 | critical | RLS | 행 수준 보안 없이 생성된 테이블 |
| R2 | critical | RLS | using (true) / with check (true)를 사용하는 쓰기 정책 |
| R3 | high | RLS | anon 역할이 쓰기를 허용하는 정책 |
| R4 | high | RLS | 고정된 search_path가 없는 security definer 함수 |
| R5 | medium | RLS | 명시적 GRANT가 없는 public의 테이블. Supabase는 2026년 10월 30일부터 새 public 테이블에 대한 기본 grant를 중단하겠다고 발표했으나, 8월 말 한 Supabase CLI 메인테이너는 (supabase/cli PR #6337에서) 이전의 기본 변경이 "실제로 적용되지 않았고(never landed)" 호스팅 프로젝트가 여전히 자동 grant 중이라고 밝혔으므로 날짜가 바뀔 수 있습니다: 자신의 프로젝트가 어떻게 동작하는지 확인하세요. grant가 없으면 Data API는 42501을 반환합니다 |
| R6 | high | RLS | anon/authenticated에 대한 전면적인 grant ... on all tables in schema public / alter default privileges ... grant(RLS 없는 테이블까지 노출시키는, 42501을 빠르게 고치는 방법) |
| S1 | critical | Stripe | 서명 검증(constructEvent)이 없는 웹훅 |
| S2 | critical | Stripe | 원시 본문 대신 request.json()을 파싱하는 웹훅 |
| S3 | medium | Stripe | event.id에 대한 멱등성이 없는 웹훅 |
| S4 | high | Stripe | 요청에서 가져온 체크아웃 가격 또는 금액 |
| S5 | high | Stripe | 웹훅이 아닌 체크아웃 성공 페이지에서 접근 권한을 부여함 |
| S6 | medium | Stripe | 실패한 이벤트를 삼킬 수 있는 웹훅 중복 제거: pending/completed 상태 없이 중복을 건너뜀 |
| S7 | low | Stripe | items.data[0]에서 읽은 청구 기간(API 2025-03-31.basil 이후 다중 항목 구독에서는 잘못됨) |
| H1 | medium | 하드닝 | next.config에 보안 헤더가 없음 |
| H2 | medium | 하드닝 | 리터럴이 아닌 값과 함께 사용된 dangerouslySetInnerHTML |
fixtures/vulnerable-app은 23개의 파일 기반 검사를 모두 트리거하며, 테스트는 각 검사가 예상된 파일에서 발생하는지 검증합니다. K3는 임시 git 저장소에서 테스트됩니다.fixtures/clean-app(하드닝된 참조 앱)과 fixtures/near-miss(각 실수를 닮은 안전한 코드: pending/completed 멱등성을 갖춘 원시 본문 웹훅, 다중 항목에 안전한 기간 조회, 가드된 리다이렉트, 소유자 필터링된 관리자 쿼리, select using (true), JSON-LD)는 0개의 발견 사항을 생성해야 합니다.npm test는 CLI 플래그와 종료 코드를 포함한 node:test 스위트를 실행합니다. npm run smoke는 한 줄 요약을 제공합니다.requireUser*, getUser*, verifySession*, assertAuth*, auth(), currentUser(), protect() 같은 이름의 헬퍼는 인식됩니다.supabase/migrations 및 .sql 파일의 SQL만 읽습니다. 대시보드에서 생성된 정책은 확인할 수 없습니다.npm audit 사용) 또는 전체 git 기록의 시크릿( gitleaks 사용)은 검사하지 않습니다.광고: 아래 제품은 동일 저자(Stack & Ship)의 유료 제품입니다. CLI는 어느 쪽이든 무료이며 MIT 라이선스로 유지됩니다.
이 무료 CLI는 작은 서브셋입니다. 출시를 앞두고 있다면: