보안, 신뢰성, 유지보수성
- 8.1 보안 취약점
- 8.2 보안 감사
- 8.3 테스팅 프레임워크
- 8.4 성능 최적화
- 8.5 코드 리뷰
AI 생성 코드가 프로덕션에 갈 때 반드시 거쳐야 하는 품질 관문이 있어. 보안, 테스트, 성능, 코드 리뷰 — 이 네 가지를 AI 시대에 어떻게 적용할지가 핵심이지. 이 부분을 무시하면 앞의 모든 게 무의미해지거든.
AI가 생성한 코드에서 발견되는 보안 취약점 유형을 체계적으로 보면:
인젝션 공격 — AI가 SQL 쿼리를 생성할 때 파라미터 바인딩 대신 문자열 연결을 쓰는 경우가 있어. 특히 복잡한 동적 쿼리에서 이런 패턴이 나타나지. NoSQL 인젝션, 커맨드 인젝션도 마찬가지야.
인증/인가 결함 — AI가 로그인 기능은 만들어주는데, 세션 관리가 취약하거나, 비밀번호 해싱을 약한 알고리즘으로 하거나, 토큰 만료를 너무 길게 설정하는 경우. 특히 인가(authorization) 로직에서 문제가 많아. "이 사용자가 이 리소스에 접근할 권한이 있는가"를 제대로 체크하지 않는 코드를 생성하곤 하거든.
민감 데이터 노출 — 에러 응답에 스택 트레이스가 포함되거나, API 응답에 불필요한 필드(비밀번호 해시, 내부 ID 등)가 포함되는 경우. AI가 개발 편의를 위해 디버그 정보를 넣는데, 프로덕션에서는 이게 취약점이 돼.
의존성 취약점 — AI가 추천하는 라이브러리에 알려진 보안 취약점이 있을 수 있어. 학습 데이터 시점에서는 안전했지만 이후에 CVE가 발견된 경우지.
CORS 설정 오류 — AI가 개발 편의를 위해 Access-Control-Allow-Origin: *을 설정하는 경우가 많아. 개발 환경에서는 상관없지만 프로덕션에서는 위험하지.
핵심 메시지는 이거야 — AI는 "동작하는 코드"를 만드는 데 최적화되어 있지, "안전한 코드"를 만드는 데 최적화되어 있지 않아. 보안은 별도의 의식적 노력이 필요해.
AI 생성 코드에 대한 보안 감사를 어떻게 할 것인가 보면:
자동화된 도구 활용:
- SAST(정적 분석) — SonarQube, Semgrep, CodeQL 같은 도구로 코드를 스캔. AI가 생성한 코드도 동일하게 스캔 대상에 포함
- DAST(동적 분석) — OWASP ZAP 같은 도구로 실행 중인 앱을 테스트
- 의존성 스캔 — npm audit, Snyk, Dependabot으로 취약한 의존성 확인
AI를 활용한 보안 감사: 흥미로운 전략이 있어 — AI가 만든 코드를 다른 AI 세션에서 보안 리뷰 시키는 거야. "이 코드에서 OWASP Top 10 기준으로 보안 취약점을 찾아줘"라고 하면 놀라울 정도로 잘 찾아줘. 생성할 때는 놓치는 것도 리뷰할 때는 잡는다는 게 아이러니하지.
보안 체크리스트: AI 생성 코드에 적용할 최소한의 보안 체크리스트야:
- 모든 입력에 검증/새니타이즈가 적용되어 있는가
- SQL 쿼리에 파라미터 바인딩이 쓰이고 있는가
- 인증된 엔드포인트에 인가 체크가 있는가
- 민감 데이터가 로그나 응답에 노출되지 않는가
- CORS, CSP 같은 보안 헤더가 적절히 설정되어 있는가
- 시크릿이 코드에 하드코딩되어 있지 않은가
AI 시대의 테스트 전략을 재정립할 필요가 있어. 핵심 주장은 — AI가 코드를 만드는 시대에 테스트의 가치가 더 올라갔다는 거야.
이유는 간단해. 자기가 짠 코드는 어떻게 동작하는지 알지만, AI가 짠 코드는 모를 수 있잖아. 테스트는 "이 코드가 내 의도대로 동작하는지"를 기계적으로 확인해주는 장치야.
AI 시대에 테스트 피라미드의 비중이 좀 달라져:
- 유닛 테스트 — AI가 빠르게 대량 생성 가능. 커버리지 확보에 효과적
- 통합 테스트 — AI 생성 코드에서 가장 중요해. 컴포넌트 간 연결이 제대로 되는지 확인
- E2E 테스트 — 사용자 시나리오 기반으로 전체 흐름 검증. AI에게 시나리오를 주고 테스트 코드를 생성시키면 되지
속성 기반 테스트(Property-Based Testing): 특정 입력이 아니라 "어떤 입력이든 이 속성을 만족해야 한다"는 방식의 테스트야. AI 생성 코드의 엣지 케이스를 찾는 데 효과적이지. fast-check 같은 라이브러리로 구현 가능해.
뮤테이션 테스트: 코드를 의도적으로 변형(뮤테이션)시켰을 때 테스트가 이를 잡아내는지 확인하는 거야. 테스트의 품질을 검증하는 방법이지. AI 생성 테스트가 정말 의미 있는지 확인할 때 유용해.
AI가 생성하는 코드는 보통 "정확하지만 최적은 아닌" 수준이야. 흔한 성능 문제들을 보면:
- N+1 쿼리 — ORM 코드에서 가장 흔하게 나타나는 문제. 목록을 가져오고 각 항목에 대해 추가 쿼리를 실행하는 패턴. AI가 이걸 자연스럽게 생성하지
- 불필요한 리렌더링 — React에서 메모이제이션 없이 모든 상태 변경마다 전체가 리렌더링되는 패턴
- 메모리 누수 — 이벤트 리스너 해제 누락, 클린업 함수 빠짐, 클로저로 인한 참조 유지
- 번들 크기 — 필요 없는 라이브러리 전체를 import하거나, 트리 셰이킹이 안 되는 방식으로 코드를 짜는 경우
AI를 활용한 성능 최적화 전략:
- "이 코드에서 성능 문제가 될 수 있는 부분을 찾아줘" — AI가 잠재적 병목을 짚어줘
- "이 쿼리를 최적화해줘. 현재 1000건의 데이터에서 2초 걸리는데 100ms 이내로 만들어야 해" — 구체적인 목표를 주면 더 나은 결과
- 프로파일링 결과를 AI에게 주고 분석을 요청하면 효과적이지
AI 시대의 코드 리뷰는 전보다 더 중요해졌어.
AI가 코드를 생성하면서 코드 리뷰해야 할 양이 늘었거든. 그런데 AI가 생성한 코드는 "그럴듯해 보이지만 미묘하게 틀린" 경우가 있어서, 리뷰어의 주의력이 더 필요하지.
AI 생성 코드 리뷰 시 집중해야 할 포인트:
- 비즈니스 로직의 정확성 — AI가 요구사항을 잘못 해석한 경우를 잡아내기
- 엣지 케이스 처리 — null, 빈 배열, 동시 접근, 타임아웃 같은 예외 상황
- 아키텍처 적합성 — 이 코드가 기존 프로젝트 구조와 맞는지
- 과도한 복잡성 — AI가 불필요하게 복잡한 솔루션을 제안한 경우 단순화
- 보안 — 위에서 다룬 보안 체크리스트
AI를 코드 리뷰에 활용하기: AI에게 1차 리뷰를 시키고 인간이 2차 리뷰를 하는 계층적 리뷰 방식이 효과적이야. AI가 스타일, 포매팅, 명백한 버그를 잡아주면, 인간은 설계 결정, 비즈니스 로직, 보안에 집중할 수 있지.
정리
8장에서 기억할 거 세 가지:
- AI는 "동작하는 코드"를 만들지, "안전한 코드"를 만들지 않아. 보안은 별도의 의식적 노력이 필요하고, AI 생성 코드에 대한 보안 감사는 필수야
- AI가 코드를 만드는 시대에 테스트의 가치가 더 올라갔어. 자기가 짜지 않은 코드의 동작을 보장하는 유일한 방법이 테스트거든
- 코드 리뷰는 AI가 1차, 인간이 2차로 계층적으로 해. AI가 기계적인 부분을 잡아주면 인간은 판단이 필요한 부분에 집중할 수 있지