Claude Code나 Cursor로 빠르게 앱을 만들 수 있어도, 생성된 코드의 안전성은 별도로 검증해야 합니다. 초판에 있던 “버그 밀도 1.7배”, “로직 오류 30% 증가” 수치는 적용 범위와 원 연구를 확인할 수 없어 삭제했습니다. 아래 체크리스트는 OWASP GenAI Security Project 같은 공개 보안 지침과 함께 사용하세요.

저도 바이브코딩으로 여러 프로젝트를 만들면서 보안 실수를 꽤 겪었어요. 그 경험을 바탕으로 실전 보안 체크리스트 7가지를 정리해 봤습니다.
1. API 키와 시크릿이 코드에 하드코딩되어 있지 않은지 확인
AI에게 “API 연동해줘”라고 프롬프트를 던지면, 종종 API 키를 코드에 직접 넣는 예시를 생성해요. 이건 GitHub에 푸시하는 순간 전 세계에 공개되는 거나 마찬가지예요.
# ❌ AI가 자주 생성하는 위험한 패턴
api_key = "sk-abc123456789"
client = OpenAI(api_key=api_key)
# ✅ 환경 변수로 분리
import os
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
체크 방법: 프로젝트 루트에서 grep -r "sk-" --include="*.py"로 하드코딩된 키를 검색하고, .gitignore에 .env가 포함되어 있는지 확인하세요.
2. 사용자 입력값 검증 (SQL Injection, XSS 방지)
바이브코딩으로 만든 웹앱에서 가장 흔한 취약점이에요. AI가 생성한 코드가 사용자 입력을 그대로 쿼리에 넣는 경우가 많거든요.
# ❌ SQL Injection 취약
query = f"SELECT * FROM users WHERE name = '{user_input}'"
# ✅ 파라미터 바인딩 사용
cursor.execute("SELECT * FROM users WHERE name = %s", (user_input,))
React나 Next.js 프론트엔드라면 dangerouslySetInnerHTML 사용 여부도 반드시 확인해야 해요. AI가 마크다운 렌더링 코드를 생성할 때 이걸 쓰는 경우가 있어요.
3. 인증과 권한 체크가 모든 엔드포인트에 적용되었는지 확인
AI에게 “게시판 CRUD 만들어줘”라고 하면 기능은 잘 만들지만, 다른 사용자의 글을 수정/삭제하는 것을 막는 권한 체크를 빠뜨리는 경우가 많아요.
// ❌ 누구나 삭제 가능
app.delete('/api/posts/:id', async (req, res) => {
await Post.findByIdAndDelete(req.params.id);
});
// ✅ 작성자 본인만 삭제 가능
app.delete('/api/posts/:id', authMiddleware, async (req, res) => {
const post = await Post.findById(req.params.id);
if (post.author.toString() !== req.user.id) {
return res.status(403).json({ error: 'Forbidden' });
}
await Post.findByIdAndDelete(req.params.id);
});
제가 바이브코딩으로 만든 첫 번째 앱에서 이 실수를 했어요. 다행히 배포 전에 발견했지만, 프로덕션에 나갔으면 큰일 날 뻔했습니다.
4. 의존성(dependencies) 보안 감사
AI가 package.json이나 requirements.txt에 추가하는 패키지가 안전한지 확인해야 해요. 간혹 존재하지 않는 패키지명을 만들어내는 “환각(hallucination)” 현상도 있고, 오래된 버전의 패키지를 지정하기도 해요.
# Python 의존성 보안 검사
pip install safety
safety check
# Node.js 의존성 보안 검사
npm audit
# 또는
pnpm audit
특히 AI가 추천한 패키지가 npm이나 PyPI에 실제로 존재하는지, 최근 업데이트가 있었는지 꼭 확인하세요.
5. 에러 메시지에 민감한 정보가 노출되지 않는지 확인
AI가 생성하는 에러 핸들링 코드는 디버깅에는 편하지만, 프로덕션에서는 위험할 수 있어요. 스택 트레이스나 DB 정보가 사용자에게 그대로 보이면 공격자에게 힌트를 주는 셈이에요.
# ❌ 상세 에러를 클라이언트에 노출
@app.errorhandler(Exception)
def handle_error(e):
return str(e), 500 # DB 연결 문자열 등 노출 가능
# ✅ 프로덕션용 에러 핸들링
@app.errorhandler(Exception)
def handle_error(e):
app.logger.error(f"Unhandled error: {e}", exc_info=True)
return {"error": "서버 오류가 발생했습니다."}, 500
6. CORS와 CSP 설정 확인
바이브코딩으로 API 서버를 만들 때, AI가 개발 편의를 위해 CORS(Cross-Origin Resource Sharing)를 전체 허용(*)으로 설정하는 경우가 많아요.
// ❌ 모든 출처 허용
app.use(cors());
// ✅ 특정 도메인만 허용
app.use(cors({
origin: ['https://myapp.com', 'https://admin.myapp.com'],
credentials: true
}));
배포 전에 반드시 허용 도메인을 제한하고, Content-Security-Policy 헤더도 설정하는 것을 권장해요.
7. 자동화된 보안 스캔을 CI/CD에 통합
사람이 매번 코드를 리뷰하는 데는 한계가 있어요. GitHub Actions에 보안 스캔을 추가하면 매 커밋마다 자동으로 취약점을 잡아줘요.
# .github/workflows/security.yml
name: Security Scan
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
uses: returntocorp/semgrep-action@v1
with:
config: p/owasp-top-ten
- name: Check for secrets
uses: trufflesecurity/trufflehog@main
with:
extra_args: --only-verified
Semgrep은 OWASP Top 10 취약점을 자동으로 탐지하고, TruffleHog은 코드에 포함된 시크릿(API 키, 비밀번호 등)을 찾아줘요. 둘 다 무료로 사용할 수 있어요.
실전 보안 점검 요약
| 체크 항목 | 도구 | 자동화 가능 |
|---|---|---|
| 하드코딩된 시크릿 | TruffleHog, git-secrets | ✅ |
| SQL Injection / XSS | Semgrep, ESLint 보안 룰 | ✅ |
| 권한 체크 누락 | 수동 리뷰 + 테스트 | ⚠️ 일부 |
| 의존성 취약점 | npm audit, safety | ✅ |
| 에러 정보 노출 | Semgrep 커스텀 룰 | ✅ |
| CORS 설정 | 수동 리뷰 | ⚠️ |
| CI/CD 보안 스캔 | GitHub Actions | ✅ |
Q. 바이브코딩으로 만든 앱도 프로덕션에 배포해도 되나요?
네, 하지만 위의 체크리스트를 반드시 거쳐야 해요. AI가 생성한 코드는 “초안”으로 생각하고, 보안 리뷰를 거친 후에 배포하는 것이 안전해요. 특히 사용자 데이터를 다루는 앱이라면 더 신중해야 합니다.
Q. AI 코딩 도구 중 보안에 가장 강한 도구는 뭔가요?
Claude Code는 코드 생성 시 보안 취약점을 자동으로 경고하는 기능이 있어서 비교적 안전한 편이에요. 다만 어떤 도구를 쓰든 Semgrep 같은 SAST(정적 분석) 도구를 함께 사용하는 것을 권장해요.
Q. 보안 지식이 없어도 바이브코딩을 할 수 있나요?
기본적인 앱은 만들 수 있지만, 프로덕션 배포를 위해서는 최소한 OWASP Top 10 취약점에 대한 이해가 필요해요. 이 글의 체크리스트를 따라하는 것만으로도 가장 흔한 보안 실수의 80%는 예방할 수 있어요.
Q. 기존 바이브코딩 프로젝트에 보안 스캔을 추가하려면?
위 7번의 GitHub Actions 설정을 복사해서 .github/workflows/security.yml에 붙여넣으면 바로 적용돼요. 첫 스캔에서 발견되는 취약점 수에 놀라실 수도 있지만, 하나씩 고쳐나가면 됩니다.