· 김뽑희

보안 체크

바이브코딩 사이트 배포 전 보안 체크리스트 (Supabase RLS·.env)

개발 몰라도 클로드한테 세 마디만 하면 막을 수 있어요. 왜 위험한지, 직접 확인하는 법, 붙여넣을 점검 문장, 이미 터졌을 때까지.

원본 영상 · 1분 6초
이 자료의 내용

한눈에 보기

돌아가는 사이트와 안전한 사이트는 달라요. AI는 "돌아가게"는 기가 막히게 만들어 주지만, 문단속까지 알아서 해 주진 않아요. 그대로 올리면 이런 일이 생길 수 있어요.

  • 내 돈으로 남이 AI를 써요. 비밀 키가 화면 코드에 그대로 박혀 있으면 누구나 가져다 쓸 수 있거든요
  • 회원 정보를 아무나 봐요. 데이터베이스 문이 열려 있으면요

올리기 전 체크리스트

  • 1. 비밀 키 이름 앞에 NEXT_PUBLIC_이 붙어 있지 않다 (F12로 검색해도 안 나온다)
  • 2. .env 파일이 깃허브에 올라간 적이 없다 (올라갔다면 키를 새로 바꿨다)
  • 3. Supabase 테이블마다 RLS가 켜져 있고, "내 데이터만 보이게" 정책도 있다
  • 끝으로 클로드 코드에서 /security-review를 한 번 돌렸다

제일 빠른 방법: 한 번에 점검하기

클로드 코드에서 프로젝트를 열고 이걸 그대로 붙여넣으세요. 고치기 전에 보고부터 받게 해 뒀어요.

프롬프트
이 프로젝트를 배포하기 전에 보안 점검을 해 줘. 아직 아무것도 고치지 말고 먼저 결과만 보고해 줘.

1. 비밀 키(API 키, 시크릿 키, service_role 키 등)가 브라우저로 가는 코드에 들어간 곳이 있는지. 특히 이름에 NEXT_PUBLIC_이 붙은 비밀 키가 있는지.
2. .env 파일이 .gitignore에 들어 있는지, 그리고 git 기록에 .env가 커밋된 적이 있는지.
3. Supabase를 쓴다면 테이블마다 RLS가 켜져 있는지, 정책(policy)이 있는지, 모두에게 다 열어 주는 정책은 없는지.

항목마다 "안전 / 위험 / 확인 필요"로 표를 만들고, 위험한 건 어떻게 고칠지 쉬운 말로 설명해 줘.

먼저, 키에는 두 종류가 있어요

구분공개 키비밀 키
예Supabase 공개 키(anon / publishable)OpenAI 같은 AI API 키, Supabase 시크릿 키·service_role 키, 결제 키
브라우저에 있어도 되나돼요 (단, 3번 RLS가 켜져 있을 때만)절대 안 돼요
새면문지기(RLS)가 지켜 줌누구나 내 돈으로 쓰고, 데이터 문을 다 열 수 있음

특히 Supabase의 시크릿 키·service_role 키는 RLS를 무시하고 통과하는 만능 열쇠예요. 브라우저에 있으면 3번을 아무리 잘해도 소용없어요.

1. 비밀 키에 NEXT_PUBLIC_ 붙이지 않기

왜 위험? Next.js는 이름 앞에 NEXT_PUBLIC_이 붙은 값을 빌드할 때 브라우저로 가는 코드에 그대로 박아 넣어요. 손님 누구나 볼 수 있는 진열장에 금고 열쇠를 올려 두는 셈이에요.

직접 확인하는 법:

  1. 내 사이트를 열고 F12(개발자 도구)
  2. Ctrl + Shift + F(맥은 Cmd + Option + F)로 전체 검색창 열기
  3. 키 앞 글자 몇 개(예: sk-)를 검색
  4. 결과가 나오면 새고 있는 거예요

클로드한테 할 말:

프롬프트
비밀 키가 브라우저 코드에 들어간 곳을 찾아서 서버 쪽으로 옮겨 줘. 브라우저는 내 서버(API 라우트)에 부탁만 하고, 키는 서버에서만 쓰게 바꿔 줘.

알아 둘 것: NEXT_PUBLIC_ 값은 빌드할 때 굳어져요. 키를 바꿨으면 다시 빌드·배포해야 반영돼요.

2. .env 파일이 깃허브에 올라갔는지 보기

왜 위험? .env는 비밀 키들을 적어 두는 메모장이에요. 깃허브에 한 번 올라가면 기록에 남아서, 나중에 지워도 옛날 버전에서 다시 꺼내 볼 수 있어요.

클로드한테 할 말:

프롬프트
.env가 .gitignore에 들어 있는지 확인하고, git 기록에서 .env가 커밋된 적이 있는지 찾아 줘. 커밋된 적이 있으면 어떤 키 이름들이 들어 있었는지 목록만 보여 줘. 키 값은 화면에 출력하지 마.

이미 올라갔다면? 순서가 중요해요.

  1. 각 서비스 관리 화면에서 새 키를 발급
  2. 앱에 새 키를 넣고 다시 배포
  3. 옛 키는 폐기(삭제·비활성화)
  4. 그다음에 필요하면 기록 정리

기록 지우기부터 하면 안 돼요. 옛 키는 이미 누가 가져갔을 수 있으니, 키 교체가 먼저예요. 깃허브의 **푸시 보호(push protection)**를 켜 두면 비밀이 들어간 푸시를 미리 막아 줘요.

3. Supabase 테이블마다 RLS 켜기 (제일 중요)

**RLS(행 수준 보안)**는 "이 줄은 누가 볼 수 있어?"를 정하는 문지기예요. 안 켜면 공개 키만 있으면 누구나 내 데이터를 읽고 고칠 수 있어요. 공식 문서도 공개되는 스키마의 모든 테이블에 RLS를 켜라고 해요.

함정 하나: RLS를 켜기만 하면 내 앱에서도 데이터가 안 보여요. 문지기가 아무도 안 들여보내거든요. 그래서 "누구는 들어와도 돼" 하는 정책(policy), 즉 출입 명단까지 만들어야 해요.

클로드한테 할 말:

프롬프트
Supabase의 모든 테이블에 RLS가 켜져 있는지 확인해 줘. 꺼진 테이블은 켜고, 로그인한 사용자가 자기 데이터만 보고 고칠 수 있는 정책을 만들어 줘. 모두에게 공개해야 하는 테이블이 있으면 먼저 나한테 물어봐.

정책이 어떻게 생겼는지 궁금하다면, "로그인한 사람은 자기 할 일만 볼 수 있다"는 정책은 이런 모양이에요.

명령어
create policy "본인 것만 보기" on todos
for select to authenticated
using ( (select auth.uid()) = user_id );

흔한 실수:

  • 켜고 나서 "데이터가 다 사라졌어요!" → 정책이 없어서예요. 지워진 게 아니에요
  • 귀찮아서 "모두 허용" 정책을 넣음 → RLS를 끈 거나 다름없어요

끝으로: /security-review

클로드 코드를 쓴다면 올리기 전에 이 명령 하나 돌려 보세요. 아직 합치지 않은 변경을 보안 눈으로 훑어서 로그인 구멍, 데이터 노출, 인젝션 같은 위험을 찾아 줘요.

명령어
/security-review

돌아가는 조건: 깃허브 같은 원격 저장소(origin)에 연결된 프로젝트여야 해요. 원격의 기본 브랜치와 비교해서 바뀐 부분을 보거든요.

한 줄 정리

키는 서버에, .env는 내 컴퓨터에, 데이터베이스엔 문지기(RLS)와 출입 명단(정책)을. 이미 샜다면 지우기보다 키 교체가 먼저.

출처

복사해서 쓰는 것 모음 · 6개

제일 빠른 방법: 한 번에 점검하기

프롬프트
이 프로젝트를 배포하기 전에 보안 점검을 해 줘. 아직 아무것도 고치지 말고 먼저 결과만 보고해 줘.

1. 비밀 키(API 키, 시크릿 키, service_role 키 등)가 브라우저로 가는 코드에 들어간 곳이 있는지. 특히 이름에 NEXT_PUBLIC_이 붙은 비밀 키가 있는지.
2. .env 파일이 .gitignore에 들어 있는지, 그리고 git 기록에 .env가 커밋된 적이 있는지.
3. Supabase를 쓴다면 테이블마다 RLS가 켜져 있는지, 정책(policy)이 있는지, 모두에게 다 열어 주는 정책은 없는지.

항목마다 "안전 / 위험 / 확인 필요"로 표를 만들고, 위험한 건 어떻게 고칠지 쉬운 말로 설명해 줘.

1. 비밀 키에 NEXTPUBLIC 붙이지 않기

프롬프트
비밀 키가 브라우저 코드에 들어간 곳을 찾아서 서버 쪽으로 옮겨 줘. 브라우저는 내 서버(API 라우트)에 부탁만 하고, 키는 서버에서만 쓰게 바꿔 줘.

2. .env 파일이 깃허브에 올라갔는지 보기

프롬프트
.env가 .gitignore에 들어 있는지 확인하고, git 기록에서 .env가 커밋된 적이 있는지 찾아 줘. 커밋된 적이 있으면 어떤 키 이름들이 들어 있었는지 목록만 보여 줘. 키 값은 화면에 출력하지 마.

3. Supabase 테이블마다 RLS 켜기 (제일 중요)

프롬프트
Supabase의 모든 테이블에 RLS가 켜져 있는지 확인해 줘. 꺼진 테이블은 켜고, 로그인한 사용자가 자기 데이터만 보고 고칠 수 있는 정책을 만들어 줘. 모두에게 공개해야 하는 테이블이 있으면 먼저 나한테 물어봐.

3. Supabase 테이블마다 RLS 켜기 (제일 중요)

명령어
create policy "본인 것만 보기" on todos
for select to authenticated
using ( (select auth.uid()) = user_id );

끝으로: /security-review

명령어
/security-review

자료를 보고 궁금한 점이 생겼나요?