AI 코드가 "작동한다"는 건 "안전하다"가 아니다
Stanford 연구(2023)에서 GitHub Copilot 사용자가 비사용자보다 보안 취약점이 있는 코드를 더 많이 작성한다는 결과가 나왔다. AI 코드를 그대로 믿기 때문이다.
AI 코딩 도구를 10년 가까이 써온 입장에서, AI가 반복적으로 만들어내는 취약한 코드 패턴들이 있다. 이걸 알고 있으면 코드 리뷰 시 빠르게 잡을 수 있다.
AI가 자주 만드는 취약한 패턴
패턴 1: 하드코딩된 시크릿
# AI가 예시로 자주 만드는 코드
db_password = "admin123"
api_key = "sk-proj-xxxx"
secret_key = "mysecretkey123"
# 올바른 방법
import os
db_password = os.environ.get('DB_PASSWORD')
api_key = os.environ.get('API_KEY')
패턴 2: SQL 파라미터화 미적용
# AI가 종종 만드는 취약한 코드
query = f"SELECT * FROM users WHERE username = '{username}'"
cursor.execute(query)
# SQL Injection 공격: username = "' OR '1'='1"
# 안전한 코드
cursor.execute("SELECT * FROM users WHERE username = %s", (username,))
패턴 3: 인증 검증 누락
// AI가 빠르게 API를 만들 때 자주 누락
app.get('/api/admin/users', async (req, res) => {
const users = await User.findAll(); // 인증 없이 전체 사용자 목록 반환
res.json(users);
});
// 인증 미들웨어 추가 필요
app.get('/api/admin/users', authenticate, requireAdmin, async (req, res) => {
const users = await User.findAll();
res.json(users);
});
패턴 4: 에러 처리에서 민감 정보 노출
// AI가 만드는 에러 핸들러
app.use((err, req, res, next) => {
res.status(500).json({ error: err.message, stack: err.stack });
// 스택 트레이스에 서버 경로, DB 설정 노출 가능
});
// 안전한 버전
app.use((err, req, res, next) => {
console.error(err); // 서버 로그에만 기록
res.status(500).json({ error: 'Internal Server Error' });
});
AI 코드 보안 리뷰를 AI에게 시키는 법
AI로 만든 코드를 다시 AI에게 보안 리뷰 맡기는 게 효과적이다. 단, 프롬프트가 중요하다.
아래 코드를 OWASP Top 10 기준으로 보안 검토해줘.
특히 다음 항목을 집중적으로 봐:
1. 입력값 검증 및 SQL Injection
2. 인증/인가 누락
3. 하드코딩된 시크릿
4. 에러 처리에서의 정보 노출
5. 안전하지 않은 의존성
[코드 붙여넣기]
코드 레벨 보안 검토와 별개로, 배포된 서비스의 설정 취약점은 CodeScan으로 점검하는 걸 루틴으로 만들어두면 상호 보완이 된다.