제공 서비스
웹 보안 점검 · 무료 단건 외부 공격표면 관리 · 지속 자동 AI 취약점 진단 · 신규 모의해킹 · 침투 테스트
요금제 스토어 블로그 파트너 마이페이지 무료 보안 점검
CRM보안 2026.04.02 · 조회 431

바이브코딩 CRM 보안 사고 실제 사례 분석 (2025-2026)

AI 코딩으로 만든 CRM에서 실제로 발생한 보안 사고 5건을 분석합니다. Supabase RLS 미설정, API 키 유출, 인증 없는 엔드포인트 등 반복되는 패턴과 예방법을 정리했습니다.

S
보안 전문 기업 SENTRIX 레드팀
해킹대회 수상 · 보안 실무 10년 · 실전 진단 경험을 바탕으로 작성합니다.
이 글의 취약점, 내 사이트엔 없을까요? URL 하나로 30초 무료 점검.

실제로 터진 사고들

바이브코딩이 대중화되면서 보안 사고도 급증하고 있습니다. AI가 만든 코드의 보안 취약점은 기존 개발보다 더 체계적으로 반복됩니다. 같은 프롬프트에서 같은 취약점 패턴이 나오기 때문입니다.

이 점이 공격자에게는 선물입니다. 개발자마다 제각각인 실수가 아니라, AI 코딩 도구가 찍어내는 동일한 구조의 구멍이기 때문입니다. 공격자는 특정 도구로 만든 앱을 찾아내는 지문(fingerprint)만 알면, 취약점 하나를 검증한 뒤 같은 패턴을 수천 개 사이트에 그대로 적용합니다. 아래 5건은 SENTRIX 레드팀이 실제 진단·대응 현장에서 반복적으로 마주친 사고 유형을 정리한 것입니다.

사례 1: Lovable CRM 170개 앱 DB 노출 (2025.06)

Lovable로 만든 170개 이상의 앱에서 Supabase RLS가 설정되지 않은 채 운영되고 있었습니다. 고객 이름, 이메일, 전화번호, 결제 정보가 anon key만으로 조회 가능한 상태였습니다.

공격자는 이렇게 악용합니다. Supabase의 anon key는 브라우저로 전달되는 프론트엔드 코드 안에 그대로 들어 있습니다(설계상 노출이 전제입니다). 공격자는 앱의 자바스크립트 번들에서 프로젝트 URL과 anon key를 긁어낸 뒤, RLS가 꺼져 있으면 그 key만으로 REST API를 직접 호출해 테이블 전체를 페이지 단위로 덤프합니다.

# RLS가 꺼진 테이블은 anon key만으로 전체 조회된다
curl "https://xxxx.supabase.co/rest/v1/customers?select=*" \
  -H "apikey: eyJhbGciOi...ANON_KEY" \
  -H "Authorization: Bearer eyJhbGciOi...ANON_KEY"
# [{"name":"홍길동","phone":"010-...","email":"..."}, ... 전체 행]

직접 확인하는 법. Supabase 대시보드 → Table Editor에서 각 테이블 왼쪽의 방패 아이콘이 초록색(RLS 활성화)인지 봅니다. 하나라도 꺼져 있으면 위험입니다. 또는 SQL Editor에서 다음 쿼리로 RLS 미적용 테이블을 한 번에 찾을 수 있습니다.

-- RLS가 꺼진 public 테이블 목록
SELECT tablename FROM pg_tables
WHERE schemaname = 'public'
AND tablename NOT IN (
  SELECT tablename FROM pg_tables t
  JOIN pg_class c ON c.relname = t.tablename
  WHERE c.relrowsecurity = true
);

원인: Lovable이 생성한 코드에 RLS 정책이 포함되지 않았고, 개발자들이 이를 인지하지 못했습니다.

그래서 뭘 해야 하나(우선순위 1). 모든 테이블에 ALTER TABLE ... ENABLE ROW LEVEL SECURITY;를 적용하고, 최소 권한 정책부터 추가합니다. RLS를 켜면 정책이 없는 상태에서는 아무것도 읽히지 않으므로, 먼저 잠근 뒤 필요한 접근만 여는 순서가 안전합니다.

-- 먼저 잠근다
ALTER TABLE customers ENABLE ROW LEVEL SECURITY;
-- 본인 데이터만 허용
CREATE POLICY "own_rows" ON customers
FOR SELECT USING (auth.uid() = user_id);

교훈: AI가 생성한 DB 설정은 반드시 직접 검증해야 합니다.

사례 2: Cursor 생성 API 키 GitHub 유출 (2025.09)

Cursor로 만든 CRM 프로젝트에서 OpenAI API 키와 Supabase service_role 키가 코드에 하드코딩된 채로 GitHub에 push됐습니다. 봇이 15분 만에 탐지하여 API 키로 수백 달러의 요금이 발생했습니다.

왜 15분 만인가. GitHub의 public push 이벤트는 실시간 스트림으로 공개됩니다. 공격자 봇은 이 스트림을 구독하며 sk-, eyJ(JWT), AKIA(AWS) 같은 키 패턴을 정규식으로 훑습니다. 커밋이 올라온 순간 키가 수집되고, 자동화된 스크립트가 곧바로 과금 API를 호출합니다. service_role 키가 섞여 있었다면 요금 피해를 넘어 CRM 데이터 전체가 RLS를 우회해 탈취됩니다. service_role은 모든 정책을 무시하는 마스터 키이기 때문입니다.

직접 확인하는 법. 키가 이미 Git 이력에 들어갔는지 로컬에서 즉시 점검합니다.

# 추적 중인 파일에 .env가 들어갔는지
git ls-files | grep -E "\.env"

# 과거 커밋 이력에 키 패턴이 남았는지
git log -p | grep -E "sk-[A-Za-z0-9]{20,}|service_role|eyJ[A-Za-z0-9_-]{20,}"

원인: AI가 .env 대신 코드에 직접 키를 삽입했고, .gitignore 설정이 누락됐습니다.

그래서 뭘 해야 하나. 순서가 중요합니다. (1) 노출된 키를 먼저 폐기·재발급합니다. 이미 유출된 키는 커밋을 지워도 이력에 남으므로 무효화가 유일한 해법입니다. (2) 그다음 .gitignore.env류를 추가하고 캐시에서 제거합니다.

git rm --cached .env
echo ".env*" >> .gitignore
git commit -m "remove leaked env"

교훈: AI 생성 코드에서 시크릿 패턴을 반드시 스캔해야 합니다.

사례 3: 1인 쇼핑몰 CRM 고객 5만건 유출 (2025.11)

Bolt로 만든 고객 관리 페이지에서 /api/customers 엔드포인트에 인증이 없었습니다. URL만 알면 전체 고객 목록을 가져갈 수 있는 상태로 6개월간 운영됐습니다.

공격자는 인증을 뚫는 게 아니라, 인증이 없다는 걸 발견합니다. AI는 화면에 데이터를 뿌리는 프론트엔드 코드는 잘 만들지만, 그 데이터를 내려주는 백엔드 API에 "누가 요청했는가"를 확인하는 미들웨어를 자주 빠뜨립니다. 공격자는 브라우저 개발자 도구의 Network 탭에서 페이지가 호출하는 API 경로를 그대로 읽고, 그 경로에 로그인 없이 직접 요청을 보냅니다.

# 취약 — 인증 미들웨어 없음
app.get('/api/customers', async (req, res) => {
  const rows = await db.query('SELECT * FROM customers');
  res.json(rows);        // 누구나 전체 고객 조회
});

# 안전 — 요청자 검증 후 본인 데이터만
app.get('/api/customers', requireAuth, async (req, res) => {
  const rows = await db.query(
    'SELECT * FROM customers WHERE owner_id = $1', [req.user.id]);
  res.json(rows);
});

직접 확인하는 법. 로그아웃 상태(또는 시크릿 창)에서 앱이 호출하는 API 경로에 직접 접속해 봅니다. 데이터가 그대로 나오면 인증이 없는 것입니다.

# 인증 토큰 없이 호출 — 데이터가 나오면 취약
curl https://your-crm.com/api/customers

원인: AI가 프론트엔드에서 호출하는 API를 만들면서 인증 미들웨어를 추가하지 않았습니다.

그래서 뭘 해야 하나(우선순위 1). 모든 데이터 조회·수정 API 앞에 인증 미들웨어를 강제하고, 조회 결과를 요청자 소유 데이터로 필터링합니다. 인증만 있고 소유권 검증이 없으면 로그인한 아무나 남의 고객 목록을 id만 바꿔 열람하는 IDOR 취약점으로 이어집니다.

교훈: 모든 API 엔드포인트에 인증 여부를 점검해야 합니다.

사례 4: 학원 CRM 학생 개인정보 검색엔진 노출 (2026.01)

바이브코딩으로 만든 학원 관리 시스템의 학생 목록 페이지가 robots.txt 미설정으로 Google에 색인됐습니다. 학생 이름, 연락처, 수강 정보가 검색 결과에 노출된 사례입니다.

이게 왜 특히 위험한가. API 노출은 경로를 알아야 하지만, 검색엔진 색인은 공격자가 찾아올 필요도 없이 피해자가 검색으로 걸어 들어오게 만듭니다. 공격자는 site: 연산자와 특정 키워드를 조합한 이른바 "구글 도킹"으로 노출 페이지를 대량 수집합니다. 예: site:*.example.com "학생 목록" 연락처. 한 번 색인되면 페이지를 지워도 검색 캐시에 한동안 남습니다.

직접 확인하는 법. 자기 도메인을 구글에 site:내도메인.com으로 검색해 내부 페이지가 뜨는지 봅니다. 그리고 민감 페이지가 색인 차단·인증 보호되고 있는지 응답을 확인합니다.

# 민감 페이지가 로그인 없이 200을 반환하는지 (302로 로그인 리다이렉트가 정상)
curl -I https://your-crm.com/students
# robots.txt 존재 여부
curl https://your-crm.com/robots.txt

원인: AI가 SEO는 신경 썼지만 민감 페이지의 색인 차단은 고려하지 않았습니다.

그래서 뭘 해야 하나. robots.txt는 "정중한 요청"일 뿐 강제력이 없습니다. 진짜 방어는 두 겹입니다. (1) 민감 페이지에 인증을 강제해 로그인 없이는 200이 아니라 로그인 화면으로 보냅니다. (2) 보조로 noindex 헤더/메타태그를 추가합니다.

# 응답 헤더로 색인 차단 (robots.txt보다 확실)
X-Robots-Tag: noindex, nofollow

인증이 근본 대책이고, noindex는 이미 뚫린 페이지의 검색 노출을 줄이는 보조 수단이라는 우선순위를 기억해야 합니다.

교훈: 관리자/내부 페이지는 반드시 noindex 처리와 인증 보호를 적용해야 합니다.

사례 5: SaaS CRM 관리자 페이지 무인증 접근 (2026.02)

/admin 경로에 비밀번호 없이 접근 가능한 상태로 배포된 CRM입니다. 고객 데이터 수정, 삭제, 내보내기가 누구에게나 열려있었습니다.

공격자는 관리자 경로를 추측하지 않습니다, 목록을 돌립니다. /admin, /dashboard, /manage, /wp-admin 같은 뻔한 경로는 자동화 스캐너의 기본 사전에 들어 있습니다. 봇은 신규 도메인을 발견하면 이 사전을 초 단위로 훑고, 200 응답에 관리 UI가 뜨면 그대로 데이터 내보내기 버튼을 누릅니다. 인증이 없으면 여기서 끝입니다, 익스플로잇조차 필요 없습니다.

흔한 착각. "경로를 /x9f2-panel처럼 어렵게 바꿨으니 안전하다"는 생각은 위험합니다. 이건 인증이 아니라 숨김일 뿐이고, 자바스크립트 번들·사이트맵·리퍼러 로그로 경로가 새어 나갑니다. 아래처럼 인증이 인가와 분리돼야 합니다.

# 취약 — 경로만 숨기고 인증 없음
app.get('/x9f2-panel', renderAdmin);

# 안전 — 로그인 + 관리자 권한 이중 검증
app.get('/admin', requireAuth, requireRole('admin'), renderAdmin);

직접 확인하는 법. 로그아웃 상태에서 관리자 경로에 접속해 관리 화면이나 데이터가 보이면 즉시 조치 대상입니다.

curl -I https://your-crm.com/admin
# 200 + 관리 UI = 위험 / 302 로그인 리다이렉트 = 정상

원인: AI가 관리자 페이지를 만들면서 인증 래퍼를 생략했습니다.

그래서 뭘 해야 하나(우선순위 1). (1) 관리자 라우트 전체에 인증 + 역할 검증을 강제합니다. (2) 관리자 로그인에 접속 IP 제한이나 2단계 인증을 추가합니다. (3) 경로 변경은 어디까지나 보조입니다. 세 가지 중 인증·인가가 없으면 나머지는 의미가 없습니다.

교훈: 관리자 경로는 예측 불가능한 URL과 강력한 인증을 모두 적용해야 합니다.

다섯 사고를 관통하는 하나의 패턴

사고 원인은 서로 달라 보이지만 뿌리는 같습니다. AI 코딩 도구는 "작동하는 코드"를 만들지 "안전한 코드"를 만들지 않는다는 것입니다. RLS 활성화, 인증 미들웨어, 시크릿 분리, 색인 차단, 권한 검증, 이 다섯 가지는 화면에 아무 변화도 주지 않기 때문에, "잘 되네" 하고 배포하면 정확히 그 부분만 빠진 채 프로덕션에 올라갑니다. 그리고 법적 책임은 AI가 아니라 개인정보처리자(사업주)에게 있습니다. 개인정보 유출 시 최대 5,000만원 과태료와 형사처벌 대상이 됩니다.

내 CRM은 안전한가요?

위 5가지 사고의 공통점은 점검 없이 배포했다는 것입니다. 반대로 말하면, 배포 전 단 한 번의 점검으로 다섯 사고 모두 막을 수 있었다는 뜻입니다. RLS 미설정, 시크릿 노출, 인증 없는 API, 민감 페이지 색인, 관리자 무인증, 모두 외부에서 URL 하나로 탐지 가능한 항목입니다.

보안 전문기업 SENTRIX가 만든 CodeScan에서 URL 하나로 30초 만에 주요 취약점을 확인할 수 있습니다. 코드를 열지 않아도, 공격자가 보는 것과 같은 관점에서 내 CRM의 노출 상태를 점검합니다.

→ 지금 무료로 CRM 보안 진단 받기

CRM 보안사고 사례분석 바이브코딩 개인정보유출

내 사이트도 점검해보세요

URL 하나면 21개 항목을 30초에 무료 점검합니다. 회원가입·카드 없이.

추천 상품
웹서비스 런칭 전 보안 세팅
런칭 전에 반드시 해야 하는 보안 설정을 원격으로 직접 해드립니다. HTTPS, 환경변수 분리, 보안 헤더…
220,000원 150,000원

AI 코딩 보안 체크리스트 받기

AI 코딩 보안 체크리스트(PDF)를 무료로 받아보세요.