AI로 만든 앱의 보안 체크리스트: 출시 전에 확인할 것
실제 사람들이 AI로 만든 앱을 쓰기 전에 일곱 가지를 확인하세요. 모든 페이지와 API가 사용자가 누구인지, 무엇을 할 수 있는지 확인하는가. 비밀 키가 서버에만 있고 브라우저나 채팅에는 없는가. 모든 입력이 서버에서 검증되는가. 각 사용자가 자신의 레코드에만 접근할 수 있는가. 로그인과 비용이 드는 API에 요청 제한이 있는가. 의존성이 최신인가. 그리고 문제가 생겼을 때 데이터를 복구할 수 있는가. 아래 체크리스트는 이 각각을 코드를 읽지 않고도 실행할 수 있는 구체적인 테스트로 바꿔 줍니다.
AI 앱 빌더는 기능을 동작하게 만드는 데는 뛰어나지만, 자동으로 신중하게 만들어 주지는 않습니다. 프롬프트에 ‘신중하게’라는 말이 거의 없기 때문입니다. 아래 문제 대부분은 아무도 요청하지 않은 부분에서 생기므로, 해결책은 대개 요청하는 것입니다.
이 체크리스트 사용법
순서대로 진행하면서 각 항목마다 두 가지를 하세요. AI에게 처리되었는지 확인하도록 요청하기와 직접 테스트하기입니다. AI는 권한 확인 코드를 작성할 수 있지만, 실제로 동작하는지는 테스트만이 알려 줍니다. 항목은 다음과 같이 표시합니다.
- 필수(Must) — 다른 사람이 앱을 쓰기 전에 반드시 합니다.
- 권장(Should) — 실제 사용자나 실제 데이터를 다루기 전에 합니다.
- 나중에(Later) — 앱이 성장하면서 챙기면 좋은 항목입니다.
시간이 한 시간뿐이라면 모든 필수 항목부터 하세요.
1. 인증: 이 사람은 누구인가?
인증은 상대가 누구인지 확인하는 과정으로, 보통 로그인을 말합니다. 기본 개념은 인증이란 무엇인가를, 선택지는 앱에 로그인을 추가하는 법을 참고하세요.
- 필수: 비공개 데이터를 보여 주는 모든 페이지는 로그인을 요구해야 합니다. 테스트: 로그아웃한 뒤 비공개 페이지의 URL을 브라우저에 직접 붙여 넣어 보세요.
- 필수: 그 페이지 뒤에 있는 모든 API 엔드포인트도 페이지만이 아니라 로그인을 요구해야 합니다. 테스트: 로그아웃한 상태에서 개발자 도구의 네트워크 탭을 열고, 로그인 상태에서 앱이 보냈던 요청을 다시 보내 보세요.
- 필수: 비밀번호는 느린 비밀번호 해싱 알고리즘으로 해시해 저장하고, 평문으로 저장하면 안 됩니다. OWASP의 비밀번호 저장 지침은 Argon2id를 1순위로 권장하고, scrypt, bcrypt, PBKDF2를 대안으로 제시합니다. AI에게 “비밀번호는 어떻게 저장되나요?”라고 물어보세요.
- 권장: 비밀번호 재설정 링크는 만료되고 한 번만 동작해야 합니다.
- 권장: 세션 쿠키에
Secure,HttpOnly,SameSite가 설정되어 있고, 로그아웃하면 서버에서도 세션이 끝나야 합니다. - 나중에: 2단계 인증을 제공하거나, 이를 지원하는 제공업체를 통한 로그인을 제공하세요.
사용자 데이터를 반환하는 모든 API 경로와 페이지를 확인하세요. 각각은 로그인하지 않은 사용자의 요청을 페이지 코드에서만이 아니라 서버에서 거부해야 합니다. 확인한 경로 목록을 보여 주세요.
2. 권한 부여: 이 사람은 무엇을 할 수 있는가?
권한 부여는 로그인 다음 단계로, 이 특정 사용자가 무엇을 보고 바꿀 수 있는지 결정합니다. 여기서 AI로 만든 앱에 심각한 구멍이 가장 자주 생깁니다. 앱은 겉보기에 제대로 동작합니다. 각 사용자의 대시보드에는 자기 데이터만 보입니다. 하지만 서버에 직접 요청하면 누구의 데이터든 그대로 내줄 수 있습니다.
- 필수: 모든 읽기, 수정, 삭제는 서버에서 해당 레코드가 현재 사용자(또는 소속 팀)의 것인지 확인해야 합니다.
- 필수: 테스트하세요. 계정 A와 B를 만듭니다. A로 로그인해 A의 레코드 하나를 열고, URL이나 네트워크 요청에 있는 ID를 확인합니다. 그다음 B로 로그인해 같은 ID를 요청합니다. B는 A의 데이터가 아니라 오류를 받아야 합니다.
- 필수: 관리자 페이지와 관리자 API 엔드포인트는 서버에서 사용자의 역할을 확인해야 합니다. 관리자 링크를 숨기는 것은 보호가 아닙니다.
- 필수: 사용자가 요청을 조작해서 자기 역할, 가격, 잔액, 소유자 필드를 바꿀 수 없어야 합니다. 테스트: 네트워크 탭에서 프로필 수정 요청이 무엇을 보내는지 보세요.
role이나isAdmin같은 필드가 있다면, 클라이언트에서 그 값을 무시하도록 AI에게 요청하세요. - 권장: URL의 ID는 추측하기 어려워야 합니다(1, 2, 3 대신 무작위 ID). 이것은 권한 확인의 대체재는 아니지만, 확인이 빠졌을 때 피해를 줄여 줍니다.
레코드를 읽거나 바꾸는 모든 엔드포인트에서, 로그인한 사용자가 그 레코드를 소유하거나 접근할 권한이 있는지 서버에서 확인하세요. 아니라면 404를 반환하세요. 그리고 계정 두 개로 이를 어떻게 테스트할지 보여 주세요.
3. 데이터베이스의 행 단위 접근 제어
“행 단위 접근 제어”란 테이블의 각 행(예약 하나, 송장 하나)이 그 행에 속한 사용자에게만 보이도록 하는 것입니다. 이를 강제하는 방법은 두 가지가 흔합니다.
| 방식 | 동작 방식 | 주의할 점 |
|---|---|---|
| 서버 코드에서 | 모든 쿼리에 “소유자가 현재 사용자인” 같은 필터를 포함 | 필터 하나를 빠뜨리면 전부 노출됨 |
| 데이터베이스에서 (예: Postgres 행 단위 보안) | 사용자가 볼 수 없는 행은 데이터베이스가 직접 거부 | 설정이 더 많고, 서버가 올바른 사용자로 연결해야 함 |
두 방식 모두 잘 쓸 수 있습니다. 중요한 것은 다음과 같습니다.
- 필수: 브라우저가 데이터베이스와 직접 통신한다면(일부 호스팅형 데이터베이스 제품은 이를 허용합니다), 모든 테이블에 행 단위 규칙을 켜야 합니다. 그렇지 않으면 공개 키를 가진 누구나 전체 테이블을 읽을 수 있습니다.
- 필수: 쿼리는 브라우저가 보낸 ID가 아니라 현재 사용자나 팀을 기준으로 필터링해야 합니다.
- 권장: 공유 데이터(팀 프로젝트)에는 누가 팀에 속하는지에 대한 명확한 규칙이 있어야 하며, 그 규칙은 한 곳에서 강제되어야 합니다.
4. 비밀 키와 API 키
API 키는 서비스용 비밀번호입니다. Stripe, 이메일, AI 제공업체가 모두 이를 사용합니다. 배경 지식은 환경 변수와 시크릿이란 무엇인가를 참고하세요.
- 필수: 키는 코드에 적지 않고 프로젝트의 환경 변수나 시크릿에 저장합니다.
- 필수: 돈을 쓰거나 비공개 데이터를 읽을 수 있는 키는 서버에서만 사용합니다. 테스트: 실제 사이트를 열고 페이지 소스와 개발자 도구의 JavaScript 파일을 보세요. 키의 앞부분(예:
sk_)을 검색했을 때 나타나면 안 됩니다. - 필수: 키를 채팅, 공개 저장소, 스크린샷에 붙여 넣은 적이 없어야 합니다. 그랬다면 제공업체에서 키를 교체하세요(새 키를 만들고 이전 키를 삭제).
- 권장: 제공업체가 지원한다면 제한된 범위의 키를 사용하세요. 예를 들어 Stripe는 연동에 필요한 권한만 가진 제한 키를 권장합니다.
- 권장: 테스트 키와 라이브 키를 분리하고, 준비가 되었을 때만 라이브 앱에 라이브 키를 사용하세요.
일부 키는 공개용으로 설계되어 있습니다. Stripe의 공개 가능 키(pk_…)나 내 도메인으로 제한된 지도 키가 그렇습니다. 이 규칙은 권한을 부여하는 키에 관한 것이며, 키처럼 보이는 모든 문자열에 해당하는 것은 아닙니다.
5. 입력 검증
사용자가 보내는 모든 것, 즉 양식 필드, 파일 업로드, URL 매개변수는 양식이 허용하는 것만이 아니라 무엇이든 될 수 있습니다.
- 필수: 검증은 브라우저에서만 하지 말고 서버에서 해야 합니다. 브라우저 검사는 편의를 위한 것이고, 누구나 건너뛸 수 있습니다.
- 필수: 데이터베이스 쿼리는 사용자 입력을 문자열로 이어 붙이지 않고 매개변수를 사용해야 합니다(SQL 인젝션 방지). AI에게 이를 확인해 달라고 요청하세요.
- 필수: 사용자가 입력한 텍스트는 HTML로 실행되지 않고 텍스트로 표시되어야 합니다. 테스트: 이름에
<b>hello</b>를 입력해 보세요. 굵은 글씨가 아니라 태그가 그대로 보여야 합니다. - 권장: 파일 업로드는 형식과 크기를 확인하고, 업로드된 파일이 앱의 메인 도메인에서 실행 가능한 페이지로 제공되지 않아야 합니다.
- 권장: 사용자에게 보이는 오류는 간단해야 합니다(“문제가 발생했습니다”). 자세한 오류는 서버 로그에만 남기세요.
- 권장: Stripe 같은 서비스의 웹훅은 동작하기 전에 제공업체의 서명을 검증해야 합니다. 웹훅이란 무엇인가를 참고하세요.
모든 양식과 API 엔드포인트에 서버 측 검증을 추가하세요. 필수 필드, 길이, 형식, 허용 값을 확인하고, 그 밖의 값은 분명한 메시지와 함께 거부하세요. 내부 오류 세부 정보를 사용자에게 보여 주지 마세요.
6. 요청 제한과 악용 방지
요청 제한은 일정 기간 동안 한 사람이 보낼 수 있는 요청 수를 제한합니다. 이것이 없으면 누구든 하루 종일 비밀번호를 추측하고, 가입 양식을 마비시키고, 유료 API로 요금을 올릴 수 있습니다.
- 필수: 로그인, 가입, 비밀번호 재설정은 IP 주소별, 계정별로 요청 수를 제한해야 합니다.
- 필수: 호출당 비용이 드는 기능(AI 모델 요청, SMS, 이메일)에는 사용자별 한도가 있어야 하고, 로그인이 필요해야 합니다.
- 권장: 공개 양식(문의, 대기자 명단)에는 스팸 방지 장치를 두세요. 요청 제한, 숨겨진 허니팟 필드, 또는 CAPTCHA를 사용할 수 있습니다.
- 권장: 유료 제공업체에서 지출 한도나 알림을 설정하세요. 그래야 버그나 공격자가 무제한 청구서를 만들 수 없습니다.
7. 의존성
앱은 오픈소스 패키지로 만들어지며, 패키지에는 알려진 취약점이 있기도 합니다.
- 권장: AI에게 알려진 취약점을 확인하고 영향받는 항목을 업데이트하도록 요청하세요(JavaScript 프로젝트라면
npm audit또는 패키지 관리자의 동등한 도구). - 권장: 앱이 더 이상 쓰지 않는 패키지는 제거하세요.
- 권장: 사용자가 아주 적은 패키지나 인기 패키지의 오타처럼 보이는 이름을 조심하세요.
- 나중에: 한두 달마다 다시 확인하거나, 코드가 GitHub에 있다면 자동 알림을 켜세요.
8. 백업과 복구
보안에는 실수에서 회복할 수 있는 능력도 포함됩니다. 실수가 당신의 것이든, AI의 것이든, 공격자의 것이든 마찬가지입니다.
- 필수: 데이터가 어디에 저장되는지, 백업되는지 알고 있어야 합니다. 짐작하지 말고 호스트의 문서에서 확인하세요.
- 권장: 중요한 데이터는 주기적으로 직접 내보내 두세요(예: CSV 내보내기 기능이나 데이터베이스 덤프). 별도 장소에 보관하세요.
- 권장: 코드는 버전 관리에 두어 어떤 버전이든 복원할 수 있게 하세요.
- 권장: 파괴적인 작업(계정 삭제, 프로젝트 삭제)에는 확인을 요구하고, 일정 기간 되돌릴 수 있는 ‘소프트 삭제’를 고려하세요.
- 나중에: 복원을 한 번은 실제로 테스트하세요. 한 번도 복원해 본 적 없는 백업은 계획이 아니라 바람일 뿐입니다.
9. 출시 전
- 필수: 라이브 사이트는 어디서나 HTTPS를 사용해야 합니다.
- 필수: 개발 중에 만든 샘플 데이터, 테스트 계정, 디버그 페이지를 제거하세요.
- 권장: 어떤 데이터를 수집하고 왜 수집하는지 밝힌 개인정보처리방침이 있어야 합니다. 개인 정보를 수집한다면 많은 지역에서 이것이 필요합니다. 보유하지 않은 인증(SOC 2, HIPAA)을 주장하지 마세요.
- 권장: 보안 문제를 알릴 수 있는 연락 방법이 있고, 모든 키를 신속하게 교체하는 방법을 알고 있어야 합니다.
보안을 넘어 출시 전 전반적인 점검이 필요하다면 AI 프로토타입을 실제 서비스로 옮기는 법을 참고하세요.
전문가 검토가 필요한 때
체크리스트는 흔한 실수를 잡아 주지만 전문가를 대신할 수는 없습니다. 카드 번호를 호스팅형 결제 페이지가 아니라 직접 처리하거나, 건강, 금융, 아동 데이터를 보관하거나, 보안 설문을 요구하는 기업에 판매하거나, 유출로 심각한 피해를 입을 수 있다면 검토 비용을 지불하는 것을 고려하세요. 코드를 내보낼 수 있으면 이런 검토가 훨씬 쉬워집니다.
Mythex로 만들 때의 보안
Mythex에는 보안 스캔 패널이 없으므로 위 체크리스트가 따라야 할 절차입니다. 도움이 되는 방법은 다음과 같습니다.
- 프로젝트 시크릿. 프로젝트 설정 → 시크릿에서 키를 저장하거나, 에이전트가 채팅에 보여 주는 시크릿 카드를 이용하세요. 그러면 키가 코드와 메시지 밖에 머뭅니다. 라이브 앱의 시크릿을 바꾼 뒤에는 다시 게시하세요.
- 계획 모드와 질문 모드. 편집 없이 권한을 검토하도록 에이전트에 요청하세요. 예: “질문 모드에서 모든 API 경로와 각 경로가 수행하는 권한 확인을 나열해 줘.”
- **
/test**는 에이전트가 사용자처럼 미리보기를 클릭해 보게 합니다. 2번 항목의 계정 두 개 테스트에 유용합니다. - 체크포인트로 문제를 일으킨 변경을 되돌릴 수 있습니다.
자세한 내용은 문서의 내가 만든 앱의 보안과 환경 변수와 시크릿을 참고하세요. 다음으로 사용자 계정을 추가할 계획이라면 앱에 로그인을 추가하는 법을 읽어 보세요.
자주 묻는 질문
AI로 만든 앱은 보안이 더 약한가요?
본질적으로 그렇지는 않습니다. 다만 AI 빌더는 기능이 동작하도록 만드는 데 최적화되어 있고, 아무도 요청하지 않으면 보안 점검은 쉽게 빠집니다. 가장 흔한 빈틈은 서버에서 권한 확인이 빠져 있는 것과, 브라우저가 읽을 수 있는 곳에 API 키가 들어가 있는 것입니다.
AI로 만든 앱에서 가장 중요한 보안 점검은 무엇인가요?
사용자 한 명으로 로그인한 뒤 다른 사용자의 데이터를 보거나 바꿔 보세요. 앱 페이지를 통해서도, URL의 ID를 바꾸는 방식으로도 확인합니다. 이런 접근 제어 실패는 OWASP Top 10:2025 웹 애플리케이션 보안 위험 목록에서 1위로 꼽힙니다.
AI로 만든 앱의 API 키는 어디에 두어야 하나요?
프로젝트의 환경 변수나 시크릿에 넣고, 서버 쪽 코드에서만 사용해야 합니다. 돈을 쓰거나 비공개 데이터를 읽을 수 있는 키는 브라우저 코드, 채팅, Git 저장소 어디에도 나타나면 안 됩니다.
출시 전에 보안 감사가 필요한가요?
위험이 낮은 데이터를 다루는 작은 앱이라면 이 체크리스트를 따라 점검하는 것으로 충분한 출발점이 됩니다. 결제를 직접 처리하거나, 건강, 금융, 아동 데이터를 다루거나, 계약상 보안 요구사항이 있다면 자격을 갖춘 전문가에게 검토를 받으세요.