본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 23. 10:11

AI가 생성한 코드에 0~100점 사이의 점수를 매겨보았습니다. 대부분의 저장소는 30점 미만이었습니다.

요약

AI가 생성한 코드의 보안 취약점과 품질을 0~100점 사이의 점수와 등급으로 평가하는 새로운 코드 스캐너 도구를 소개합니다. SQL 인젝션, 하드코딩된 비밀 값 등 다양한 취약점에 대해 가중치 기반의 감점 시스템과 유머러스한 비판(Roast) 메시지를 제공합니다.

핵심 포인트

  • AI 생성 코드의 보안 취약점을 점수와 등급으로 정량화
  • 취약점 유형별 가중치 적용 및 중복 패턴 감점 완화 로직
  • SQL 인젝션, 하드코딩된 비밀 값 등 주요 보안 이슈 탐지
  • 사용자 경험을 위한 유머러스하고 직설적인 피드백 제공

만약 당신의 코드가 학교 성적표처럼 — 하지만 아주 잔혹할 정도로 솔직하게 — 점수를 받는다면 어떨까요?

저는 정확히 그것을 만들었습니다. 당신의 코드를 읽고 다음을 반환하는 스캐너입니다:

  • 0에서 100 사이의 점수
  • S에서 F- 사이의 등급
  • "이제 당신의 데이터는 모두의 데이터입니다"와 같은 메시지
  • 취약점별로 다르게 다가오는 (뼈를 때리는) 비판(Roast)

실제 AI가 생성한 저장소(Repos)들에 실행했을 때 어떤 일이 일어났는지 소개합니다.

등급 시스템 (The Grade System)

등급 (Grade)점수 (Score)캐릭터 (Character)분위기 (Vibe)
S95–100🦄"신화적입니다. 액자에 넣어 벽에 걸어두세요."
...

점수는 무작위가 아닙니다. 모든 취약점(Vulnerability)에는 가중치가 적용된 감점이 있습니다:

SQL_INJECTION_RISK    → -28점
COMMAND_INJECTION     → -28점
HARDCODED_SECRET      → -22점
...

동일한 버그 유형이 반복되나요? 감점 폭은 줄어듭니다 (60%, 40%, 20%) — 따라서 하나의 나쁜 패턴이 당신의 전체 점수를 불공정하게 매장할 수는 없습니다.

취약점별로 다르게 다가오는 비판 (The Roasts Hit Different Per Vulnerability)

이 부분은 사람들이 스크린샷을 찍어 공유하는 부분입니다.

💉 SQL_INJECTION_RISK (SQL 인젝션 위험)

"SELECT * FROM users WHERE hacker=1 — 이미 대기열에 올라왔습니다"
"당신 덕분에 전 세계에 무료 DB 접근 권한을 제공하네요"
"당신의 DB는 누구나 읽을 수 있습니다. 축하합니다"

🔑 HARDCODED_SECRET (하드코딩된 비밀 값)

"봇들이 5초 안에 GitHub의 비밀 값을 수집합니다"
"코드 안에 있군요. 더 이상 비밀이 아닙니다."
"누군가 이미 그것을 사용하고 있을지도 모릅니다"

💾 MISSING_WRITE (쓰기 누락 - 바이브 코딩의 전형)

"INSERT 없이 save(). AI가 만든 쓰레기(Slop)의 정점"
"아무것도 저장하지 않는 save() — 반전이네요"
"AI가 구현(Implementation)을 구현하는 것을 잊었습니다"

⏳ FAKE_ASYNC (가짜 비동기)

"await 없는 async. 이벤트 루프(Event loop)가 울고 있습니다"
"함수가 아닌 장식으로서의 async 키워드"
"비동기 옷을 입은 동기(Synchronous) 코드"

🏗️ STUB_SKELETON (스텁/스켈레톤 구조)

"return {} — AI가 구현 도중에 포기했습니다"
"근육은 없고 뼈대뿐입니다. 장식용 코드"
"이 함수는 정교하게 만들어진 '무(無)'입니다"

🖥️ COMMAND_INJECTION (커맨드 인젝션)

"당신 덕분에 무료 서버 루트(Root) 권한을 드립니다"
"rm -rf / 명령어가 실행되기까지 단 하나의 페이로드(Payload)뿐입니다"
_"SSH 키를 나눠주는 것보다 더 위험합니다"

실제 테스트: 이 코드는 몇 점을 받을까요?

import sqlite3, subprocess

API_KEY = "sk-prod-abc123"  # 이런!
...

이 코드를 AINAScan으로 돌려보았습니다. 분석 결과는 다음과 같습니다:

BLOCK: HARDCODED_SECRET     L3   → -22 pts
BLOCK: SQL_INJECTION_RISK   L7   → -28 pts
BLOCK: COMMAND_INJECTION    L11  → -28 pts
...

100점 만점에 6점. 오타 하나만 없었어도 보안 사고가 발생했을 수준입니다.

잔혹한 아이러니는 무엇일까요? 정확히 이런 패턴이 실제 '바이브 코딩 (vibe-coded)' 저장소에서 나타난다는 점입니다. 누군가 ChatGPT에게 "사용자 프로필 API를 작성해줘"라고 요청했습니다. AI는 SQL 인젝션 (SQL injection), 하드코딩된 키 (hardcoded keys), 그리고 아무것도 저장하지 않는 save_profile() 함수를 생성했습니다. AI가 백엔드 개발자 흉내를 내고 있었던 것입니다.

버그 목록보다 점수가 더 효과적인 이유

대부분의 보안 스캐너는 문제점들을 벽처럼 쌓아놓고 쏟아냅니다. 아무도 그것들을 읽지 않죠.

하지만 단 하나의 숫자는 상황을 바꿉니다:

  • "우리 코드베이스 점수는 73점입니다" → 실제 팀 단위의 대화로 이어짐
  • "지난 스프린트 이후 점수가 81점에서 64점으로 떨어졌습니다" → 실질적인 책임 소재 파악 가능
  • "이 PR(Pull Request)로 인해 점수가 12점 하락했습니다" → 구체적인 코드 리뷰의 기준점 역할

게다가, 동일한 파일은 항상 동일한 점수를 받습니다 (SHA-256 중복 제거). 버그를 수정하고 다시 스캔하면 점수가 올라가는 것을 볼 수 있습니다. 이러한 피드백 루프는 긍정적인 의미에서 중독성이 있습니다.

점수를 가장 크게 깎아먹는 3가지 바이브 코딩 버그

1. FAKE_ASYNC (-각각 6점)

# ChatGPT가 생각하는 "비동기 (async)"
async def process_items(items):
    results = []
...

await가 없다면 async 키워드는 아무런 역할도 하지 않습니다. 이벤트 루프 (event loop)를 차단하고 있는 것입니다. 이는 AI에게 "비동기로 만들어줘"라고 요청했을 때 생성되는 가장 흔한 패턴 1위입니다.

해결책: await asyncio.to_thread(expensive_sync_operation, item)를 추가하거나, async를 제거하세요.

2. MISSING_WRITE (-각각 10점)

# AI가 생각하는 "저장 (saving)"
def save_order(order_data: dict) -> dict:
    order_id = generate_id()
...

SQL도 없고, 파일 쓰기도 없고, 캐시 설정도 없습니다. 함수는 존재하고 영속성 (persistence)을 암시하는 이름을 가지고 있지만, 실제로 영속적인 작업은 아무것도 수행하지 않습니다. 이는 AI가 구현 (implementation) 단계에 들어가기 전, 인터페이스(contract)부터 생성할 때 발생합니다.

해결책: 실제로 무언가에 기록하세요. db.execute("INSERT INTO orders ...", (...))와 같은 코드가 시작점이 될 수 있습니다.

3. STUB_SKELETON (-8점씩 감점)

# 복잡한 로직에 대한 AI의 "구현"
def calculate_risk_score(user: dict, portfolio: list) -> float:
    # 포트폴리오를 기반으로 사용자 위험 점수 계산
...

float 타입의 dict를 반환합니다. AI가 시그니처(signature)와 독스트링(docstring)은 생성했지만, 실제 로직 구현은 포기했습니다. 그런데도 그냥 배포(Ships)합니다.

실제 작동 방식 (기술적인 부분)

세 가지 레이어로 구성되며, 그 중 어느 것도 정규 표현식 (regex)을 사용하지 않습니다.

레이어 1 — 9개 언어에 걸친 오염 추적 (Taint tracking)
소스 (request.args, sys.argv, 폼 입력값)로부터 오염된 변수 (tainted variables) 집합을 구축합니다. 할당 과정을 통해 이들을 추적합니다. 이 변수들이 위험한 싱크 (sinks) (execute(), subprocess.run(), eval())에 도달하는지 확인합니다.

레이어 2 — AST 구조 분석 (AST structural analysis)
바이브 코딩 (vibe-coding) 패턴을 감지합니다: 쓰기 작업이 없는 save*라는 이름의 함수, await가 없는 async def, 매개변수가 반환 값에 전혀 영향을 미치지 않는 함수 (정의-사용 그래프 (def-use graphs) 사용) 등을 찾아냅니다.

레이어 3 — 인과적 영향력 점수 산정 (Causal impact scoring)
발견된 사항을 지식 그래프 (133K+ 인과 관계 체인)와 교차 참조하여 실제 세계에 미치는 영향을 추정합니다. SQL 인젝션(SQL injection) → 데이터 유출(data exfiltration)은 그래프 상에서 0.94의 확률을 가집니다. 이것이 28점의 감점이 발생하는 이유입니다.

지원 언어: Python, JavaScript, TypeScript, Go, Ruby, Java, Kotlin, PHP, C/C++

사용해 보기

👉 AINAScan에 코드를 붙여넣으세요 — 몇 초 만에 점수를 확인할 수 있습니다

또는 직접 curl을 사용하세요 (무료 테스트 키 제공, 가입 불필요):

curl -X POST https://pleasing-transformation-production-90c2.up.railway.app/v1/scan \
  -H 'X-API-Key: vg_free_test' \
  -F 'file=@your_code.py'

어떠한 데이터도 저장되지 않습니다. 코드는 메모리 내에서 실행되며 스캔 후 즉시 폐기됩니다.

당신의 점수는 얼마인가요?

댓글로 남겨주세요.

Dev.to 독자들의 점수 분포를 보고 싶습니다. 제 추측으로는 우리 대부분은 B-C 범위에 속할 것 같습니다. 완전히 망가진 수준은 아니지만, 그렇다고 깨끗하지도 않은 상태 말이죠. S-티어(S-tier)인 분들은 드뭅니다. F-클럽(F- club)은 누구도 인정하고 싶지 않을 만큼 규모가 큽니다.

당신은 🦄인가요, 아니면 💣인가요?

직접 테스트하고 확인해 보세요.

48개의 패턴, 9개의 언어, github.com/moonsehwan/aina-scan의 오픈 소스 코어

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0