Supabase RLS(행 수준 보안) 누락
RLS를 켜지 않으면, 누구나 가진 공개용 anon 키만으로 데이터베이스 전체를 읽고 쓸 수 있습니다.
이게 무슨 문제인가요?
Supabase는 테이블마다 "누가 어떤 데이터를 읽고 쓸 수 있는지"를 정하는 규칙인 RLS(Row Level Security, 행 수준 보안)를 켜도록 설계돼 있습니다. 그런데 RLS를 켜지 않으면, 앱이 브라우저에 공개적으로 들고 있는 anon 키만으로 그 테이블의 모든 행에 접근할 수 있게 됩니다. 바이브코딩 도구로 빠르게 만든 앱에서 가장 흔하게 빠지는 함정입니다.
왜 위험한가요?
공격자는 앱 코드에 이미 노출돼 있는 공개 키만으로 회원 이름·연락처·주소·결제 정보 같은 전체 데이터를 그대로 내려받을 수 있습니다. 읽기뿐 아니라 쓰기·삭제를 막는 정책까지 없으면 데이터를 바꾸거나 통째로 지우는 것도 가능합니다. 별도의 해킹 기술 없이 브라우저 개발자 도구만으로 일어납니다.
내 앱도 해당되나요?
Supabase 대시보드 → Table Editor 에서 각 public 테이블에 RLS disabled(빨간 표시)가 있는지 확인하세요. 또는 Authentication → Policies 에 정책이 하나도 없는 테이블이 있는지 봅니다. 정책이 비어 있는데 데이터가 보인다면 그 테이블은 사실상 공개 상태입니다.
어떻게 고치나요?
- 1모든 공개 테이블에 RLS 켜기
Supabase 대시보드 Table Editor 에서
public스키마의 모든 테이블에 대해 RLS(Row Level Security)를 Enable 합니다. - 2테이블별 접근 정책 작성
"본인 행만 읽기"처럼 최소 권한 정책을 만듭니다. 예: 로그인 사용자가 자기 데이터만 보도록
auth.uid() = user_id조건의 select 정책을 추가합니다. - 3외부 접근이 불필요한 테이블은 완전 차단
anon(공개)이 접근할 이유가 없는 테이블은 정책을 0개로 두어 기본 거부 상태로 만듭니다.
- 4클라이언트가 service_role 키를 쓰지 않는지 확인
프론트엔드에서는
anon키만 사용해야 합니다. RLS를 우회하는service_role키가 브라우저로 새지 않았는지 함께 점검하세요. - 5다른 계정으로 재점검
정책 적용 후, 다른 사용자 계정(또는 비로그인)으로 내 데이터 조회를 시도해 빈 결과가 나오는지 확인합니다.
자주 묻는 질문
anon 키는 원래 브라우저에 공개되도록 설계된 키입니다. 위험한 건 키 노출 자체가 아니라 RLS가 없을 때입니다. RLS만 제대로 설정돼 있으면 공개 키로는 허용된 데이터에만 접근할 수 있습니다.
정책을 함께 작성하면 정상 동작합니다. RLS만 켜고 정책을 안 만들면 기본값이 "모두 거부"라 데이터가 안 보일 수 있는데, 이는 버그가 아니라 안전한 기본 상태입니다. 필요한 접근을 정책으로 열어주면 됩니다.
public 스키마에서 anon/authenticated 가 접근 가능한 모든 테이블에 필요합니다. 내부 전용 데이터일수록 더 엄격히 막아야 합니다.
관련 보안 이슈
앱 주소만 알려주시면 코드·서버 접근 없이 무료로 점검해 드립니다. 위험이 나오면 사람이 직접 고치는 것까지 도와드려요.
* 이 글은 보안 보증이 아닌 일반적인 안내입니다. VibeRadar 가 실제 점검에서 자주 보는 취약점 유형을 설명하며, 특정 서비스의 결함을 단정하지 않습니다.