본문 바로가기

빠른 개발의 대가: 바이브 코딩 AI 코드, “돌아간다”는 “안전하다”가 아니다

728x90

  • AI 코딩 시대, 보안은 자동으로 따라오지 않는다

“바이브 코딩”이 뭔데, 왜 보안이 이슈가 되나?

바이브 코딩(Vibe Coding)은 개발자가 자연어로 “이 기능 만들어줘”라고 말하면 LLM 기반 생성형 AI가 즉시 실행 가능한 코드를 만들어주는 방식으로, 회원가입/로그인/인증 같은 기능부터 웹앱 개발까지 빠르게 만들어 생산성이 커졌습니다.

300x250

핵심 문제는 “동작하는 코드 = 안전한 코드”가 아니라는 점입니다.
보안업계는 AI가 만든 코드가 문법/기능은 그럴듯해도 입력값 검증 누락, 과도한 권한 부여, 인증 우회 가능성, 예외 처리 중 내부정보 노출 같은 전통적 취약점을 포함하는 사례가 많다고 지적합니다.

핵심 요약

AI 생성 코드의 45%가 보안 테스트 실패

LLM이 생성한 코드 샘플 분석결과 전체 45%가 보안 테스트를 통과하지 못했고, OWASP 10대 취약점을 다수 내포했다고 합니다.

언어별 실패율 높음

  • Java: 72% (가장 높음)
  • Python: 38%
  • JavaScript: 43%
  • C#: 45%

XSS 방어 실패가 특히 심각

XSS에 대해 AI 생성 코드의 86%가 적절한 방어 로직을 구현하지 못했다고 나옵니다.

모델이 고도화돼도 “보안 코딩 성능”은 개선이 거의 없음

“기능적 정확성과 문법 완성도는 향상되지만, 보안 취약점을 줄이는 진전은 거의 없다”는 평가입니다.

확산 범위: 사내를 넘어 공급망으로 번짐

AI 생성 코드는 이미 사내 개발을 넘어 오픈소스/외주/서드파티 소프트웨어로 빠르게 확산 중이며, AI를 직접 쓰지 않는 기업도 공급망을 통해 AI가 작성한 취약 코드에 노출될 수 있다고 강조합니다.

대응 방향: “기본 불신 + 자동 검증 내재화”

AI 생성 코드를 기본적으로 신뢰하지 말고, SAST/DAST 포함 자동 검증을 개발 프로세스에 내재화하고, CI/CD 단계에서 보안 점검·배포 통제를 자동화해야 합니다.

왜 이런 문제가 구조적으로 생기나?

원인 A — AI의 최적화 목표가 “보안”이 아니라 “작동/완성”에 가까움
AI는 사용자가 요구한 기능을 빨리 “돌아가게” 만드는 데 강합니다. 반대로 보안은 비기능 요구사항(NFR)이라, 프롬프트/정책/검증이 없으면 빠지기 쉽습니다.

원인 B — 보안은 ‘컨텍스트(정책/권한/데이터 분류/위협모델)’가 없으면 코딩으로만 해결 불가
예: “관리자만 접근”, “개인정보 마스킹”, “내부망 전용” 같은 규칙은 조직별로 다릅니다. AI는 조직 정책을 모르니, 일반적인(그리고 종종 위험한) 기본 구현을 내놓기 쉽습니다.

원인 C — 속도 격차: 사람이 리뷰/테스트로 따라잡기 어려움
AI는 코드를 폭발적으로 생성합니다. “생성 속도를 사람이 따라잡기 어렵다 → 자동화된 점검/통제 체계 필요”로 연결합니다.

실제로 어떤 보안 사고로 이어질 수 있나? (공격 시나리오)

시나리오 1: 입력 검증 누락 → SQLi / Command Injection / SSRF

  • “검색 API 만들어줘” → 쿼리 파라미터를 그대로 DB에 붙임
  • “URL fetcher 만들어줘” → 내부 메타데이터(클라우드)로 SSRF 가능

시나리오 2: XSS 방어 실패 → 세션 탈취/계정 장악

  • 댓글/게시판/관리자 콘솔에서 저장형 XSS 발생
  • 관리자 쿠키/토큰 탈취 → 관리자 기능 악용

시나리오 3: 과도한 권한/인증 우회 → IDOR/권한상승

  • “내 글 수정 API”인데 userId를 파라미터로 받아 그대로 수정
  • JWT 검증을 “있으면 통과”처럼 구현

시나리오 4: 예외 처리 중 내부정보 노출

  • stack trace, SQL error, 내부 경로/키 정보가 응답에 출력
  • 공격자가 구조를 학습해 더 정교하게 공격

시나리오 5: 공급망 확산

  • 외주/오픈소스에 AI 생성 취약 코드가 섞임
  • 우리 조직은 AI 안 써도 “가져다 쓰는 순간” 노출

보안 관점 가이드

(원칙 1) AI 생성 코드는 “기본 불신(Default Deny)”

규정 문구 예시

  • “AI 생성/수정 코드 및 AI 추천 패치/스니펫은 외부 코드 반입과 동일 등급으로 취급한다.”
  • “보안 점검(SAST/DAST/리뷰) 통과 전까지 운영 반영 금지.”

(원칙 2) “보안 요구사항을 프롬프트에 강제 포함”

프롬프트 템플릿(예시)

  • “입력값 검증(allowlist), 출력 인코딩, 인증/인가(least privilege), 비밀정보는 환경변수/Secret Manager, 에러 응답은 표준 포맷으로 내부정보 제외, 로깅은 민감정보 마스킹, OWASP Top 10 고려해서 코드를 작성해줘.”

(원칙 3) 자동 검증을 CI/CD에 “내재화(Embedded)”

사람의 선의에 맡기지 말고, 파이프라인에서 자동으로 걸러야 합니다.

점검 포인트 체크리스트

아래 항목은 AI 코드 여부와 상관없이 “특히 AI 코드에서 잘 터지는 지점” 위주입니다.

인증/인가

  • 엔드포인트마다 “인증 필수/불필요”가 명확한가?
  • 리소스 접근 시 소유권 검증(IDOR 방지)이 있는가?
  • 관리자 기능은 권한 체크가 서버에서 강제되는가?

입력/출력 처리

  • 입력값 검증이 “denylist”가 아니라 allowlist/타입 기반인가?
  • HTML/JS 컨텍스트별 출력 인코딩이 있는가? (XSS)
  • 파일 업로드는 확장자+MIME+매직바이트+저장경로+AV 스캔이 있는가?

비밀정보/설정

  • 키/토큰이 코드/로그/에러에 노출되지 않는가?
  • 기본 계정/기본 비밀번호/테스트용 백도어가 없는가?

예외/로깅

  • 에러 응답에 stack trace/쿼리/내부 경로가 포함되지 않는가?
  • 감사로그에 누가/언제/무엇을 했는지 남는가? (PII 마스킹 포함)

의존성/공급망

  • 신규 라이브러리 추가 시 승인/취약점 스캔이 있는가?
  • SBOM 생성/저장/추적이 되는가?

CI/CD에 바로 넣는 자동화 예시 (SAST/DAST/Dependency)

아래는 “개념”이 아니라 그대로 적용 가능한 뼈대 예시입니다.

GitHub Actions 예시(개념 뼈대)

name: security-gates
on: [push, pull_request]

jobs:
  sast-deps:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # 1) 의존성 취약점 스캔 (예: Trivy)
      - name: Trivy FS scan
        uses: aquasecurity/trivy-action@0.20.0
        with:
          scan-type: fs
          format: table
          exit-code: 1
          severity: CRITICAL,HIGH

      # 2) SAST (예: Semgrep)
      - name: Semgrep
        uses: returntocorp/semgrep-action@v1
        with:
          config: "p/owasp-top-ten"

  dast:
    runs-on: ubuntu-latest
    needs: sast-deps
    steps:
      # 3) DAST (예: OWASP ZAP) - 테스트 URL에 대해 스캔
      - name: ZAP baseline
        uses: zaproxy/action-baseline@v0.12.0
        with:
          target: "https://staging.example.com"
          fail_action: true

포인트는 “도구가 뭐냐”보다 실패 시 배포를 막는 게이트(gate)를 두는 것입니다.

AI가 자주 만드는 취약 구현 vs 안전한 구현

XSS 방지: “출력 인코딩”을 강제하기

위험 패턴(문자열을 그대로 HTML로 삽입)

res.send(`<div>${comment}</div>`);

안전 방향(템플릿 엔진의 auto-escape 사용 + DOM 조작 시 textContent)

// 서버 템플릿 엔진(예: Nunjucks/Handlebars 등) auto-escape 켜기 권장
// 프론트에서 DOM 반영 시:
element.textContent = comment; // innerHTML 금지

IDOR 방지: “userId를 파라미터로 믿지 않기”

위험 패턴

# user_id를 요청 파라미터로 받아 해당 사용자의 데이터를 수정
update_post(user_id=request.args["userId"], post_id=pid, body=body)

안전 방향(세션/JWT에서 인증된 사용자 기준 + 소유권 체크)

user_id = auth_context.user_id  # 토큰에서 추출
post = get_post(pid)

if post.owner_id != user_id:
    raise Forbidden()

update_post(user_id=user_id, post_id=pid, body=body)

예외 처리: “내부정보 노출 금지”

위험 패턴

except Exception as e:
    return {"error": str(e)}, 500

안전 방향(표준 에러코드 + 내부 로그에만 상세)

except Exception:
    logger.exception("Unhandled error")  # 내부 로그에만 stacktrace
    return {"error": "INTERNAL_ERROR"}, 500

현실적인 단계

🟢 1단계: 가이드라인 선포

  • AI 생성 코드는 “외부 반입 코드” 등급
  • 운영 반영은 보안 게이트 통과 필수

🟡 2단계: 파이프라인 게이트

  • Dependency Scan + SAST 최소 세트
  • PR 머지 조건: High/Critical 0개(또는 예외 승인)

🟠 3단계: DAST + 시크릿/토큰 누출 탐지

  • 스테이징 자동 스캔
  • Git leaks 탐지(예: gitleaks) 추가

🔴 4단계: 공급망(SBOM) + 정책 기반 승인

  • SBOM 생성/보관
  • 외주/서드파티 납품물에도 동일 기준 적용

실무용 템플릿 구성

  • “AI 코드 사용 보안 가이드(사내 정책 문서)”
  • PR 리뷰 체크리스트(권한/입력/에러/로그/시크릿/의존성)
  • CI/CD 보안 게이트 표준안(도구 후보 + 실패 기준 + 예외 승인 절차)
728x90
그리드형(광고전용)

댓글