바이브 코딩으로 만든 앱이 작동하긴 하죠. 출시 전 테스트해 봐야 할 것들
Your vibe-coded app works. Here’s what I would test before launch
핵심 요약
AI로 만든 앱의 기능은 작동해도 보안과 예외 처리가 취약할 수 있으므로, 출시 전 필수 체크리스트를 확인하세요.
- 서버 측 권한 검증 — 클라이언트 UI에서 숨기는 것만으로는 부족하며 서버에서 반드시 인증해야 함
- 데이터베이스 보안 — Supabase나 Firebase의 접근 정책이 너무 관대하지 않은지 확인해야 함
- 결제 로직 검증 — 결제 성공 페이지 도달 여부가 아닌 API나 웹훅을 통한 검증이 필수적임
- 예외 상황 테스트 — 실패한 결제, 중복 제출, 권한 없는 데이터 접근 등 악용 사례를 대비해야 함
최근에 보안, UX, 제품 관점에서 '바이브 코딩(vibe-coded)'으로 만든 웹 앱들을 좀 뜯어보고 있다.
재밌는 건 핵심 기능은 보통 잘 돌아간다는 점이다.
문제는 그 주변에서 터진다.
회원가입은 되는데 계정 복구가 안 된다. 유효한 카드로 결제는 되는데, 결제 실패하면 사용자가 그대로 화면에 갇혀버린다. 대시보드 UI에서는 다른 고객 데이터를 숨겨놨는데, API를 찔러보면 데이터가 그대로 다 튀어나온다.
우리가 계속 목격하는 패턴들은 대충 이렇다.
1. 인터페이스에만 있고 서버에는 없는 권한 관리
관리자 버튼은 일반 사용자한테 안 보이게 숨겨놨는데, 정작 그 뒤에 있는 엔드포인트는 사용자 권한을 확인조차 안 한다. 계정 ID나 레코드 ID만 살짝 바꿔도 다른 고객 데이터에 접근할 수 있는 경우도 허다하다.
React에서 뭘 숨기는 건 접근 제어가 아니다. 민감한 작업은 무조건 서버에서 권한 검증을 거쳐야 한다.
2. Supabase나 Firebase 규칙을 그냥 설정 과정 정도로 치부함
데이터베이스 접근 권한을 널널하게 풀어놔서 앱이 돌아가는 거다. 그러고는 읽기/쓰기 정책을 다 열어둔 채로 그대로 프로덕션에 올린다.
로그아웃 상태에서 DB 접근 테스트를 해봐라. 다른 유저로 로그인해서도 해보고. 다른 계정 소유의 레코드를 읽거나 수정할 수 있는지 꼭 확인해라.
3. 브라우저가 중요한 상태값을 다루게 둠
역할, 구독 상태, 크레딧, 기능 접근 권한 같은 걸 localStorage나 클라이언트 사이드 상태로 제어하는 꼴을 자주 본다.
브라우저가 바꿀 수 있는 건 뭐든 '믿을 수 없는 값'으로 취급해야 한다. 유료 결제 여부, 역할, 잔액, 권한 같은 건 무조건 서버에서 검증된 상태값을 가져와야 한다.
4. 결제 성공과 결제 검증을 혼동함
브라우저가 결제 성공 페이지에 도달했다는 이유만으로 유료 플랜을 풀어주는 앱들이 있다. 그 리다이렉트는 얼마든지 재현하거나 조작할 수 있다.
결제는 반드시 결제 대행사 API나 서명된 웹훅(webhook)을 통해 검증된 후에만 권한을 줘야 한다.
이것도 꼭 테스트해라:
- 결제 실패 및 중단 상황
- 웹훅 중복 전달
- 업그레이드 및 다운그레이드 흐름
- 취소 및 갱신
- 환불
- 결제 확인 지연
5. 프론트엔드에 섞여 들어간 시크릿 키
AI가 짠 코드는 서버랑 클라이언트 파일 사이를 정신없이 오간다. 가끔 개인 API 키가 브라우저 번들이나 로그, 공개 환경 변수에 그대로 박혀 있는 경우가 있다.
레포지토리만 보지 말고 배포된 자바스크립트 파일까지 다 뒤져봐라. 최신 소스에서 지웠어도 예전 배포본에는 키가 남아있을 수 있다.
6. 해피 패스(happy path)만 번지르르하고 복구는 개판임
흔한 UX 문제들:
- 에러 나면 폼 데이터 다 날아감
- 화면 멈춘 것처럼 보이는 로딩 상태
- 다음 할 일이 없는 텅 빈 화면
- 세션 만료돼서 사용자 붕 띄워버리기
- "뭔가 잘못되었습니다" 같은 뻔한 에러 메시지
- 버튼 두 번 눌러서 중복 제출되는 거
- 모바일에서 중요한 버튼 다 가려지는 레이아웃
이거 그냥 보기 싫은 정도가 아니다. 전환율, 고객 문의량, 그리고 사용자가 이 제품을 믿을 수 있을지 결정짓는 아주 중요한 문제들이다.


