바이브코딩할 때 반드시 알아야 할 보안, 품질, 디버깅 주의점
AI가 생성한 코드는 동작은 하지만 안전하지 않을 수 있습니다. 다음 5가지를 반드시 확인하세요.
AI가 예시 코드에 API 키를 직접 넣는 경우가 흔합니다.
// 위험한 코드
const supabase = createClient(
"https://abc.supabase.co", // URL이 코드에 직접!
"eyJhbGciOiJIUzI1NiIs..." // 키가 코드에 직접!
);// 안전한 코드
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);API 키, 시크릿, 비밀번호를 절대 코드에 하드코딩하지 마세요.
반드시 환경변수(.env.local)를 사용하세요.
AI가 문자열 결합으로 SQL을 만들 때가 있습니다.
// 위험: 문자열 결합
const { data } = await supabase
.rpc('search_users', { query: `%${userInput}%` });
// 안전: 파라미터 바인딩 (Supabase는 기본적으로 안전하지만 rpc 사용 시 주의)
const { data } = await supabase
.from('users')
.ilike('name', `%${userInput}%`);사용자 입력을 그대로 HTML에 렌더링하면 위험합니다.
// 위험: dangerouslySetInnerHTML
<div dangerouslySetInnerHTML={{ __html: userComment }} />
// 안전: React 기본 이스케이핑
<div>{userComment}</div>
// HTML 필요 시: sanitize 라이브러리 사용
import DOMPurify from 'dompurify';
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userComment) }} />// 위험: 모든 출처 허용
const corsHeaders = { "Access-Control-Allow-Origin": "*" };
// 안전: 특정 도메인만 허용
const corsHeaders = {
"Access-Control-Allow-Origin": "https://myapp.vercel.app"
};// 위험: 입력값 검증 없음
export async function POST(req: Request) {
const { email, amount } = await req.json();
await chargeUser(email, amount); // amount가 음수면?
}
// 안전: Zod로 검증
import { z } from 'zod';
const schema = z.object({
email: z.string().email(),
amount: z.number().positive().max(1000000),
});
export async function POST(req: Request) {
const body = schema.parse(await req.json());
await chargeUser(body.email, body.amount);
}코드 작성 후 이 프롬프트를 사용하세요:
"이 프로젝트의 보안을 검토해줘.
특히 API 키 노출, SQL 인젝션, XSS, CORS 설정, 입력 검증을 체크해줘."
바이브 코딩의 가장 큰 함정은 **"동작하니까 넘어가자"**입니다. AI가 만든 코드가 동작한다고 해서 좋은 코드는 아닙니다.
주기적으로 이 프롬프트를 사용하세요:
"지금까지 작성된 코드를 전체적으로 리뷰해줘.
코드 중복, 불필요한 의존성, 성능 문제, 구조적 문제를 찾아줘."
AI에게 기능을 요청하면 테스트를 작성하지 않는 경우가 많습니다. 명시적으로 요청해야 합니다.
# 기능과 함께 테스트 요청
> "로그인 API를 만들어줘. 유닛 테스트도 함께 작성해줘.
- 정상 로그인 케이스
- 잘못된 비밀번호 케이스
- 존재하지 않는 이메일 케이스"## 테스트 규칙
- 새 API 라우트마다 최소 3개의 테스트 케이스 작성
- 테스트 파일 위치: __tests__/ 폴더
- 테스트 러너: Jest
AI는 비슷한 패턴을 반복 생성하는 경향이 있습니다. 100줄짜리 비슷한 코드가 5개 파일에 있다면 추상화가 필요합니다.
> "이 5개 파일에서 공통 패턴을 추출해서 재사용 가능한 유틸 함수로 만들어줘"> "이 에러가 발생했어:
[에러 메시지 전문 복사]
고쳐줘."이것만으로 80%는 해결됩니다.
에러 메시지만으로 해결이 안 되면:
> "lib/auth.ts와 app/api/login/route.ts를 읽고,
왜 인증이 실패하는지 분석해줘."같은 방식으로 계속 실패하면:
> "이 방식은 계속 안 되니까, 완전히 다른 접근법으로 다시 구현해줘.
이전 코드는 삭제하고 처음부터."AI가 같은 수정을 반복하며 문제를 해결하지 못하면:
/clear 또는 새 세션)Claude Code가 같은 파일을 반복 수정하며 해결이 안 될 때:
Ctrl+C로 중단git diff로 변경사항 확인git checkout -- [파일]로 원복AI가 라이브러리를 추천하면 설치 전에 확인하세요:
# npm에서 확인할 것
> "[패키지명]의 npm 주간 다운로드 수, 최근 업데이트 날짜, GitHub 스타 수를 알려줘"| 체크 항목 | 안전 기준 |
|---|---|
| 주간 다운로드 | 10,000+ |
| 최근 업데이트 | 6개월 이내 |
| GitHub 스타 | 1,000+ |
| 오픈 이슈 수 | 해결율 50%+ |
| 라이선스 | MIT, Apache 2.0, BSD |
AI는 가끔 실제로 존재하지 않는 패키지명을 만들어냅니다 (할루시네이션). npm install이 실패하면 해당 패키지가 실존하는지 먼저 확인하세요.
| 상황 | 바이브코딩 | 직접 코딩 |
|---|---|---|
| 새 프로젝트 초기 구축 | O | |
| 반복적인 CRUD | O | |
| UI 컴포넌트 생성 | O | |
| 복잡한 알고리즘 | O | |
| 성능 최적화 | O | |
| 대규모 리팩토링 | O | |
| 보안 크리티컬 로직 | O | |
| 기존 코드 이해 | O (설명 요청) |
바이브코딩으로 만든 코드를 이해하지 못하면:
바이브코딩으로 빠르게 결과물을 만들되, 핵심 부분은 AI에게 설명을 요청하세요:
"방금 만든 인증 로직을 초보자도 이해할 수 있게 설명해줘.
각 함수가 무슨 역할을 하고, 데이터가 어떻게 흐르는지."
이렇게 하면 바이브코딩의 속도와 학습을 동시에 얻을 수 있습니다.
프로젝트를 배포하기 전에 확인하세요: