← 블로그 목록
AI 보안코드 검증SQL 인젝션프로덕션취약점

AI 생성 코드 프로덕션 투입 전 반드시 확인할 보안 체크리스트 7가지

AI 생성 코드의 SQL 인젝션, XSS, 시크릿 노출 등 보안 취약점을 프로덕션 투입 전 점검하는 7가지 체크리스트와 자동 검증 방법을 코드 예시로 정리했습니다.

Vibeollio 팀-

AI 생성 코드 프로덕션 투입 전 반드시 확인할 보안 체크리스트 7가지

ChatGPT, Claude, GitHub Copilot 같은 AI 코드 생성 도구는 개발 속도를 높이지만, 생성된 코드가 항상 보안 기준을 만족하지는 않습니다. 특히 SQL 인젝션, XSS, 하드코딩된 시크릿 같은 취약점이 의도치 않게 포함될 수 있습니다. 프로덕션 환경에 배포하기 전에 체계적인 보안 검증이 필수입니다.

1. SQL 인젝션 취약점 점검

AI 생성 코드에서 가장 흔한 실수는 사용자 입력을 직접 쿼리에 연결하는 것입니다.

위험한 코드 예시:

# ❌ 위험: 직접 문자열 연결
user_id = request.args.get('id')
query = f"SELECT * FROM users WHERE id = {user_id}"
result = db.execute(query)

사용자가 id=1 OR 1=1 같은 값을 입력하면 모든 사용자 데이터가 노출됩니다.

안전한 코드:

# ✅ 안전: 파라미터화된 쿼리 사용
user_id = request.args.get('id')
query = "SELECT * FROM users WHERE id = ?"
result = db.execute(query, (user_id,))

자동 점검 방법:

  • bandit (Python): bandit -r . | grep sql
  • SonarQube: 정적 분석으로 쿼리 패턴 감지
  • SQLMap: 실제 SQL 인젝션 테스트

2. XSS(Cross-Site Scripting) 방어 확인

AI는 HTML 템플릿에서 사용자 데이터를 이스케이프하지 않은 채로 렌더링하곤 합니다.

위험한 코드:

<!-- ❌ 위험: 사용자 입력이 그대로 렌더링 -->
<div>{{ user_comment }}</div>

사용자가 <script>alert('hacked')</script>를 댓글로 입력하면 모든 방문자의 브라우저에서 실행됩니다.

안전한 코드:

<!-- ✅ 안전: 자동 이스케이프 -->
<div>{{ user_comment | escape }}</div>

<!-- 또는 Vue/React 사용 -->
<div>{userComment}</div> {/* 기본 이스케이프 */}

자동 점검:

  • npm audit: JavaScript 의존성 취약점 검사
  • OWASP ZAP: 동적 XSS 스캔
  • 린터 설정: ESLint의 no-v-html 규칙

3. 하드코딩된 시크릿(API 키, 비밀번호) 탐지

AI는 예제 코드에서 실제 시크릿을 포함시킬 수 있습니다.

위험한 코드:

# ❌ 위험: 코드에 API 키 노출
API_KEY = "sk-1234567890abcdef"
db_password = "admin123"

response = requests.get(
    "https://api.example.com/data",
    headers={"Authorization": f"Bearer {API_KEY}"}
)

Git 히스토리에 남으면 누구나 접근할 수 있습니다.

안전한 코드:

# ✅ 안전: 환경 변수 사용
import os
from dotenv import load_dotenv

load_dotenv()
API_KEY = os.getenv("API_KEY")
db_password = os.getenv("DB_PASSWORD")

if not API_KEY:
    raise ValueError("API_KEY 환경 변수가 설정되지 않았습니다")

.env 파일:

API_KEY=sk-1234567890abcdef
DB_PASSWORD=admin123

.gitignore:

.env
*.pem
*.key

자동 점검:

  • truffleHog: Git 히스토리에서 시크릿 스캔
  • detect-secrets: 코드베이스 내 시크릿 탐지
  • git-secrets: 커밋 전 시크릿 차단

4. CORS(Cross-Origin Resource Sharing) 설정 검증

AI 생성 백엔드 코드는 CORS를 너무 개방적으로 설정하곤 합니다.

위험한 코드:

# ❌ 위험: 모든 도메인 허용
from flask_cors import CORS

app = Flask(__name__)
CORS(app)  # 모든 출처에서 요청 허용

이 설정은 Origin: *로 응답해 CSRF 공격에 취약합니다.

안전한 코드:

# ✅ 안전: 특정 도메인만 허용
from flask_cors import CORS

app = Flask(__name__)

CORS(app, resources={
    r"/api/*": {
        "origins": ["https://trusted-domain.com"],
        "methods": ["GET", "POST"],
        "allow_headers": ["Content-Type"],
        "supports_credentials": True
    }
})

자동 점검:

  • 코드 리뷰: CORS 설정이 명시적으로 정의되었는지 확인
  • 브라우저 개발자 도구: Network 탭에서 Access-Control-Allow-Origin 헤더 검증

5. 인증 및 인가 우회 확인

AI는 인증 로직을 간단하게 생성해 우회 가능한 상태로 남길 수 있습니다.

위험한 코드:

# ❌ 위험: 클라이언트 토큰 검증 없음
@app.route('/admin/delete', methods=['POST'])
def delete_user():
    user_id = request.json.get('user_id')
    # 인증 확인 없이 바로 삭제
    db.delete_user(user_id)
    return {"status": "deleted"}

누구나 이 엔드포인트로 요청을 보내 데이터를 삭제할 수 있습니다.

안전한 코드:

from functools import wraps
import jwt

def require_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        token = request.headers.get('Authorization')
        if not token:
            return {"error": "Unauthorized"}, 401
        
        try:
            payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
            if payload.get('role') != 'admin':
                return {"error": "Forbidden"}, 403
        except jwt.InvalidTokenError:
            return {"error": "Invalid token"}, 401
        
        return f(*args, **kwargs)
    return decorated

@app.route('/admin/delete', methods=['POST'])
@require_auth
def delete_user():
    user_id = request.json.get('user_id')
    db.delete_user(user_id)
    return {"status": "deleted"}

자동 점검:

  • OWASP ZAP: 인증 우회 시뮬레이션
  • 코드 리뷰: 모든 보호된 엔드포인트에 @require_auth 데코레이터 확인

6. 의존성 취약점 스캔

AI가 추천한 라이브러리 버전에 알려진 취약점이 있을 수 있습니다.

확인 방법:

# Python
pip install safety
safety check

# Node.js
npm audit
npm audit fix

# Ruby
bundle audit check --update

예시 출력:

┌─────────────────────────────────────────────┐
│ Django 3.0.0 has known vulnerability CVE... │
│ Update to 3.2.5 or later                   │
└─────────────────────────────────────────────┘

7. 입력 검증 및 레이트 제한

AI 코드는 사용자 입력을 충분히 검증하지 않거나 브루트포스 공격을 방어하지 않을 수 있습니다.

위험한 코드:

# ❌ 위험: 입력 길이 제한 없음
@app.route('/search')
def search():
    query = request.args.get('q')
    results = db.search(query)  # 매우 긴 쿼리로 DoS 가능
    return results

안전한 코드:

from flask_limiter import Limiter
from marshmallow import Schema, fields, ValidationError

limiter = Limiter(app, key_func=lambda: request.remote_addr)

class SearchSchema(Schema):
    q = fields.Str(required=True, validate=lambda x: len(x) <= 100)

@app.route('/search')
@limiter.limit("30 per minute")  # 분당 30회 제한
def search():
    try:
        args = SearchSchema().load(request.args)
    except ValidationError as err:
        return {"error": err.messages}, 400
    
    results = db.search(args['q'])
    return results

AI 코드 보안 검증 자동화 파이프라인

프로덕션 배포 전 이 체크리스트를 CI/CD에 통합하면 효과적입니다:

# .github/workflows/security-check.yml
name: Security Checks
on: [push, pull_request]

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Run Bandit (Python)
        run: pip install bandit && bandit -r . -f json -o bandit-report.json
      
      - name: Run Safety (Dependencies)
        run: pip install safety && safety check --json
      
      - name: Scan Secrets
        run: pip install detect-secrets && detect-secrets scan
      
      - name: OWASP Dependency Check
        uses: dependency-check/Dependency-Check_Action@main

이 파이프라인은 커밋할 때마다 자동으로 보안 취약점을 검사합니다.

Vibeollio에서 AI 보안 프로젝트 공유하기

AI 생성 코드의 보안 검증 자동화 도구나 보안 감시 솔루션을 개발 중이라면 Vibeollio에 프로젝트를 등록해 더 많은 개발자에게 알릴 수 있습니다. 보안 취약점 탐지 스크립트, 정책 템플릿, 또는 AI 코드 감시 서비스 등을 공유하면 커뮤니티 피드백을 받고 사용자를 확보할 수 있습니다.