프로젝트 문의 ↗
← 모든 아티클
보안 / LIBETE NOTES

바이브코딩으로 만든 앱, 보안 확인 없이 출시하면 안 되는 이유

AI로 만든 앱을 사람에게 열기 전에 확인할 보안 세 가지와, 운영 중인 서비스에서 실제로 뚫렸던 자리를 정리합니다.

먼저 읽는 핵심

키·쓰기 권한·인증 세 자리를 출시 전에 확인합니다. 데이터베이스 보안 스위치는 켜는 것만으로 쓰기를 막지 않습니다. 켜뒀는데도 남의 데이터가 고쳐지던 실제 사례를 함께 적었습니다.

혼자 만들어서 돌려보는 단계까지는 AI로 충분히 옵니다. 문제는 그다음입니다. 사람에게 주소를 보내는 순간, 그 앱은 내 컴퓨터에서 도는 코드가 아니라 아무나 접근할 수 있는 서버가 됩니다.

이 글은 "AI로 만들면 위험하다"는 이야기가 아닙니다. 저희도 AI로 빠르게 만들어 운영하고 있습니다. 다만 열기 전에 봐야 하는 자리는 정해져 있고, 저희는 그중 하나를 실제로 놓쳤습니다. 그 이야기를 포함해 정리합니다.

CHECKPOINTS AI로 만든 앱이 반복해서 뚫리는 세 자리

바이브코딩으로 만든 앱을 모아 점검한 조사들에서 고위험 취약점과 키 노출이 반복해서 보고됩니다. 실제 침해가 확인된 게 아니라 점검으로 드러난 취약 상태라는 점은 감안해야 하지만, 지적되는 자리는 대체로 셋으로 모입니다.

  • 앱에 들어간 접속 키가 공개돼도 되는 종류인가
  • 데이터베이스에 아무나 쓰기를 할 수 없게 막혀 있는가
  • 중요한 요청에 "이 사람이 맞는지" 확인이 걸려 있는가

문제는 이 셋 다 눈에 보이지 않는다는 점입니다. 화면은 멀쩡히 돌고, 내가 쓸 때는 아무 일도 일어나지 않습니다. 사용자가 생긴 뒤에야 드러납니다.

KEYS 접속 키에는 두 종류가 있습니다

AI가 짜준 코드에는 보통 키가 두 개 들어갑니다. 하나는 앱 안에 들어가도 되는 공개 키, 다른 하나는 서버에만 있어야 하는 관리자 키입니다.

공개 키는 브라우저 개발자 도구로 누구나 볼 수 있습니다. 그게 설계상 정상입니다. 대신 전제가 하나 붙습니다. 그 키로는 아무것도 마음대로 못 하게 데이터베이스 쪽에서 막아놨다는 전제입니다.

여기서 많이 어긋납니다. "이 키는 공개용"이라는 말만 듣고 안심하는데, 정작 막아놨어야 할 쪽을 안 막는 경우입니다. 공개 키는 비밀이 아니라는 게 문제가 아니라, 그 키로 할 수 있는 일을 제한하지 않은 게 문제입니다.

관리자 키는 다릅니다. 이건 모든 제한을 무시하고 통과하는 열쇠라, 앱 코드에 들어가면 그 순간 데이터베이스 전체가 열립니다. 서버 환경변수에만 두고, 저장소에 올라가 있지 않은지도 확인해야 합니다.

INCIDENT 데이터베이스 보안을 켜뒀는데도 남의 데이터가 고쳐졌습니다

저희가 실제로 겪은 일입니다.

요즘 많이 쓰는 데이터베이스에는 "행 단위 보안" 이라는 기능이 있습니다. 표의 줄 하나하나에 "누가 이걸 읽고 쓸 수 있는지" 규칙을 걸어두는 장치입니다. 흔히 RLS라고 부르고, 설정 화면에서 스위치 하나로 켭니다.

운영 중인 앱이 있었습니다. 사용자가 이미 수백 명 쓰고 있었고, 그 스위치는 켜져 있었습니다. 초록불이 들어와 있으니 당연히 막혀 있다고 생각했습니다.

막혀 있지 않았습니다. 앱에 들어 있는 공개 키만으로 랭킹 점수를 고치고, 남의 닉네임을 바꾸고, 친구 관계와 기록을 조작할 수 있는 상태였습니다.

그 스위치는 "규칙을 적용하겠다"는 선언일 뿐, 규칙 자체가 아닙니다. 흔한 오해와 달리, 규칙을 하나도 안 써두면 기본값은 전부 거부라 오히려 다 막힙니다. 열리는 건 반대쪽입니다. 사실상 "아무나 통과"에 가까운 허술한 규칙이 하나 걸려 있거나, 모든 제한을 건너뛰는 관리자 키로 요청이 나가는 경우죠. 저희는 둘 중 정확히 어느 쪽이었는지 규칙을 파고들기보다, 아래처럼 쓰기 경로 자체를 닫는 쪽을 택했습니다.

더 까다로운 건 로그인이 없는 앱입니다. 규칙은 보통 "본인 줄만 고칠 수 있음"처럼 씁니다. 그런데 로그인 개념이 없으면 그 "본인"을 가리킬 수단 자체가 없습니다. 규칙을 제대로 쓰고 싶어도 쓸 수가 없는 겁니다.

TESTING 확인해봤는데 괜찮았다면, 그 확인 방법부터 의심해야 합니다

이 건에서 제일 뼈아팠던 건 구멍 자체가 아니라 확인 방법이 틀렸던 것입니다.

권한이 막혔는지 보려고 데이터를 고치는 요청을 직접 보내봤습니다. 성공 응답이 왔습니다. "역시 열려 있구나" 하고 막는 작업을 했고, 끝난 뒤 같은 방법으로 다시 확인했습니다. 또 성공 응답이 왔습니다. 막았는데 안 막힌 줄 알고 한참을 헤맸습니다.

원인은 요청을 빈 내용으로 보낸 것이었습니다. 바꿀 값이 하나도 없으니 서버는 고칠 게 없다고 판단하고, 권한을 확인하는 단계까지 가지도 않은 채 성공을 돌려줬습니다. 실제 값을 하나 넣어 다시 보내자 그제서야 권한 없음이 떴습니다.

확인할 때 지킬 것은 셋입니다.

  • 빈 요청으로 시험하지 않습니다. 실제로 바꿀 값을 넣어서 보냅니다
  • 막기 전과 후의 응답이 달라지는지 봅니다. 둘 다 같다면 시험 방법이 틀렸을 가능성이 큽니다
  • 로그인하지 않은 상태에서 시험합니다. 내 계정으로는 당연히 되는 일이 많습니다

"테스트해봤는데 괜찮았다"가 아무것도 보장하지 않는 경우가 생각보다 흔합니다.

CHECKLIST 개발자가 아니어도 할 수 있는 보안 체크리스트 네 가지

출시 전에 직접 해볼 수 있는 순서입니다.

  • 브라우저 개발자 도구를 열고 네트워크 탭에 키가 보이는지 봅니다. 보이는 건 정상이지만, 그게 공개용 키인지는 확인해야 합니다
  • 로그아웃한 상태에서 다른 사람의 데이터가 보이는지 확인합니다
  • 계정 삭제나 데이터 삭제처럼 되돌릴 수 없는 기능이 확인 절차 없이 실행되지 않는지 봅니다
  • 저장소에 관리자 키나 비밀번호가 올라가 있지 않은지 검색해 봅니다

여기서 하나라도 걸리면 사람을 받기 전에 손봐야 합니다. 이미 사용자가 있는 상태에서 고치는 것보다 훨씬 쉽습니다.

CONCLUSION 그래서 AI로 만들면 안 되나요

아닙니다. 저희도 그렇게 만듭니다.

다만 AI는 돌아가는 코드를 잘 만들지, 공격당하지 않는 코드를 알아서 만들어주지는 않습니다. 돌아가는 것과 열어도 되는 것은 다른 문제입니다. 그 사이를 메우는 게 출시 전 점검이고, 대부분은 몇 시간이면 끝납니다.

혹시 이미 사람을 받고 있는데 위 네 가지가 확인되지 않은 상태라면, 그 점검부터 하시길 권합니다. 저희도 그렇게 찾았습니다.

YOUR NEXT VERSION

당신의 다음 버전,
함께 만들어볼까요?

프로젝트 이야기하기 ↗