AI 코드 보안 검사: 실행 전 7가지 위험 신호 점검

최종 업데이트 2026.10.12

AI가 만든 JavaScript를 실행하기 전 하드코딩 비밀값과 위험한 sink 등 7가지 신호를 로컬 실습으로 점검합니다.

AI가 만든 JavaScript는 실행 전에 하드코딩 비밀값, 위험한 HTML 삽입, 동적 코드 실행 등 7가지 신호를 먼저 점검해야 합니다.

AI 코딩 도구가 만들어 준 짧은 함수는 바로 브라우저나 서버에서 실행하기 쉽습니다. 하지만 코드가 짧다는 사실은 안전하다는 뜻이 아닙니다. 이 글은 2026년 10월 8일 기준 OWASP의 XSS 방어 지침과 OWASP Top 10:2025를 읽고, 그중 초기에 눈으로 확인할 수 있는 일곱 가지 신호를 계정·토큰·외부 저장소 없이 로컬 실습으로 검증한 기록입니다. 목표는 보안 감사를 자동화했다고 주장하는 것이 아니라, 실행 전에 멈추고 사람이 검토할 항목을 빠르게 좁히는 것입니다.

AI가 만든 코드를 실행 전에 점검하는 보안 리뷰 일러스트
대표 이미지. AI 코드 실행 전 위험 신호를 찾고 사람이 검토하는 순서를 상징적으로 표현했습니다.

왜 AI 코드에는 실행 전 정적 점검이 필요한가

생성형 AI는 요구사항을 코드로 바꾸는 속도를 높이지만, 입력의 신뢰 경계와 운영 권한까지 대신 결정해 주지는 않습니다. 같은 코드 조각이라도 브라우저에 표시하는지, 서버에서 처리하는지, 쿠키·토큰과 연결되는지에 따라 위험이 달라집니다. 따라서 “AI가 생성했다”는 출처만으로 안전 여부를 판단하면 안 되고, 실제 데이터 흐름과 실행 맥락을 분리해서 읽어야 합니다.

이번 실습은 그 첫 번째 층만 다룹니다. 예시 코드 안에 보이는 문자열 패턴을 규칙으로 검사하고, 위험 신호가 발견되면 수정 전 상태를 확인합니다. 이 방식은 의존성 취약점, 인증·인가 설계, 서버 측 요청 위조, 운영 환경 설정을 판정하지 못합니다. 대신 실행 전에 빠르게 확인할 수 있는 작은 체크를 반복 가능하게 만들어, 더 깊은 리뷰로 넘길 코드를 선별하는 데 초점을 둡니다.

OWASP는 XSS 방어를 한 가지 만능 기법으로 해결할 수 없으며, 입력 검증과 올바른 출력 인코딩·안전한 sink를 조합해야 한다고 설명합니다. 2025년 Top 10도 Injection, Cryptographic Failures, Security Misconfiguration, Software Supply Chain Failures처럼 서로 다른 원인 범주를 구분합니다. 그러므로 아래 일곱 개 통과 결과를 전체 보안 승인으로 읽어서는 안 됩니다.

이번에 만든 일곱 가지 검사와 한계

로컬 랩에는 실제 비밀값이 아닌 DEMO_KEY_DO_NOT_USE 문자열과 일부러 위험하게 작성한 코드가 기본으로 들어 있습니다. 첫째는 소스에 문자열 비밀값을 직접 넣는지, 둘째는 사용자 값을 innerHTML에 넣는지 확인합니다. 셋째는 eval() 같은 동적 코드 실행을 찾고, 넷째는 외부 요청에 http://가 남아 있는지 봅니다.

다섯째는 토큰·비밀번호·secret을 localStorage에 쓰는지, 여섯째는 입력에 trim()과 길이 비교가 있는지, 일곱째는 target="_blank" 링크에 rel="noopener noreferrer"가 함께 있는지를 검사합니다. 각 규칙은 설명 가능한 정규식과 문자열 비교로만 구성했습니다. 즉, 이 도구가 “위험 없음”을 말하더라도 복잡한 흐름 속에서 우회된 위험이나 의미상 잘못된 검증을 찾았다고 볼 수 없습니다.

특히 하드코딩 비밀값 검사는 예시 패턴을 찾는 출발점일 뿐입니다. 환경 변수나 secret manager를 읽는 코드도 권한·노출·로그 기록을 별도로 검토해야 합니다. textContent가 HTML sink를 대체하는 경우에도 URL·스크립트·스타일 문맥은 각각 다른 검증이 필요합니다. 검사 결과의 숫자는 보안 점수가 아니라, 다음 리뷰에서 확인할 작업 목록으로 취급해야 합니다.

직접 실행 결과: 위험 예시에서 안전 예시로

2026년 10월 8일 Windows 독립 Chromium의 1200×675 viewport에서 실습을 실행했습니다. 시작 화면에는 “DEMO ONLY”라고 표시된 학습용 JavaScript가 보였고, 네트워크 요청·로그인·API 키·실제 저장소 쓰기는 사용하지 않았습니다. 같은 세션에서 안전 예시 불러오기를 누른 뒤 7개 항목 검사를 눌렀습니다. 결과 화면은 일곱 항목 모두 통과, 위험 신호 없음, 정적 규칙 7개 중 7개 통과로 바뀌었습니다.

AI 코드 보안 점검 로컬 랩의 위험 예시 시작 화면
2026-10-08 독립 Chromium 시작 화면. 실제 비밀값이 아닌 DEMO ONLY 코드와 일곱 가지 점검 항목을 표시한 로컬 실습입니다.
AI 코드 보안 점검 로컬 랩에서 일곱 항목이 모두 통과한 결과 화면
같은 세션의 결과 화면. 안전 예시를 불러온 뒤 정적 규칙 7개 중 7개가 통과하고 위험 신호 없음으로 표시됩니다.
독립 Chromium에서 안전 예시를 불러온 다음 검사를 실행해 시작 화면이 결과 화면으로 바뀌는 실제 작동 영상입니다. 제품 보안 스캐너나 실제 저장소 실행 영상은 아닙니다.

이 결과가 보여 주는 것은 버튼 입력에 따라 고정된 문자열 규칙이 결과 목록과 통과 수를 갱신했다는 사실입니다. 따라서 “AI가 만든 코드를 안전하게 승인했다”거나 “OWASP 기준을 모두 통과했다”고 표현할 수 없습니다. 관찰 가능한 범위는 자체 작성한 fixture의 두 상태 전환과 일곱 규칙의 결과뿐입니다.

OWASP 지침과 코드 수정을 연결하는 법

첫 번째 연결점은 HTML에 문자열을 넣는 방식입니다. OWASP의 XSS 문서는 사용자 입력을 코드가 아니라 데이터로 표시해야 하며, JavaScript에서 일반 요소에 텍스트를 표시할 때 textContent 같은 안전한 방법을 사용할 수 있다고 설명합니다. 그렇다고 모든 상황에서 innerHTML을 기계적으로 금지한다는 뜻은 아닙니다. 정말 HTML을 렌더링해야 한다면 허용할 태그와 속성을 정의한 sanitizer, 출력 문맥, 테스트 케이스를 함께 정해야 합니다.

두 번째 연결점은 URL과 새 창입니다. 링크 주소가 사용자 입력에서 온다면 URL 스킴과 호스트를 별도로 검증해야 하고, 새 창을 여는 링크에는 opener 격리를 검토해야 합니다. 이번 규칙은 noopener가 있는지 문자열로만 확인하므로, 실제 링크가 허용된 목적지로 연결되는지는 판정하지 않습니다. 이처럼 정적 검사는 보안 원칙을 코드 리뷰의 질문으로 번역하는 도구이지, 모든 실행 경로의 증명서가 아닙니다.

세 번째 연결점은 민감정보와 암호화입니다. 로컬 저장소에 token을 넣지 않는다고 해서 인증 설계가 끝나지 않습니다. 브라우저에 어떤 데이터가 남는지, 서버가 어떤 cookie 정책을 쓰는지, 로그와 오류 메시지가 무엇을 포함하는지를 따로 확인해야 합니다. OWASP Top 10:2025의 Cryptographic Failures와 Authentication Failures가 별도 범주인 이유도 이 검토 층이 하나가 아니기 때문입니다.

실무에서 검사를 확장하는 순서

먼저 입력을 읽기 전용으로 수집합니다. 저장소 전체를 자동 실행하거나 외부 서비스에 붙이지 말고, 변경하려는 파일·언어·실행 위치를 사람이 정합니다. 다음으로 발견된 위험 신호에 파일 위치와 데이터 출처를 붙입니다. 같은 innerHTML도 상수 마크업인지 사용자 입력인지에 따라 우선순위가 달라지므로, 단순 매칭 결과를 바로 취약점으로 확정하지 않습니다.

그다음 안전한 수정 예시를 별도 fixture로 만들고, 수정 전후 결과가 달라지는지 확인합니다. 이번 랩은 안전 예시에서 textContent, JSON.parse, HTTPS, 짧은 입력 길이 제한, sessionStorage, noopener noreferrer를 사용했습니다. 이 예시는 하나의 가능한 방향일 뿐이며, 실제 애플리케이션의 프레임워크·브라우저 지원 범위·데이터 수명에 맞춰 다시 검토해야 합니다.

마지막으로 정적 결과를 동적 테스트와 결합합니다. 테스트 환경에서 대표적인 입력 경계, 권한 없는 요청, 오류 응답, 외부 링크 이동, 로그·저장소 노출을 확인하고, 의존성·빌드·배포 파이프라인도 점검합니다. AI 생성 코드라면 프롬프트와 결과를 그대로 신뢰하지 말고, 사람이 승인한 변경만 실행 경계로 넘기는 것이 좋습니다.

한계와 실패 조건 및 주의사항

다음 상황에서는 7/7 결과가 나와도 배포를 승인하지 않습니다. 코드가 동적으로 생성돼 정규식이 실제 sink를 놓칠 때, 사용자 입력이 여러 함수와 템플릿을 거쳐 흐를 때, 외부 URL·토큰·권한 범위를 확인하지 못했을 때, 제3자 패키지와 빌드 스크립트를 읽지 않았을 때, 또는 테스트 데이터에 실제 개인정보가 섞였을 때입니다. 실행 가능한 코드라면 정적 규칙보다 먼저 격리된 테스트 환경과 최소 권한을 준비해야 합니다.

이번 직접 검증은 전문 침투 테스트도, SAST 제품 비교도 아닙니다. 자체 작성한 로컬 랩이 두 코드 fixture를 표시하고 일곱 문자열 규칙의 상태를 바꾼 것만 확인했습니다. OWASP 문서의 범주와 권고를 참고했지만 OWASP 도구를 실행하거나 OWASP 인증을 받은 결과가 아닙니다. 이 한계를 본문과 캡처에 남기는 것이 증거형 콘텐츠의 중요한 일부입니다.

직접 실행 검증일은 2026-10-08이며, 관찰 기록은 시작 화면과 결과 화면의 실제 캡처 2장, 버튼 조작 전후의 작동 영상, 그리고 각 파일의 SHA-256으로 남겼습니다. 이 기록은 로컬 fixture가 동일 조건에서 같은 결과를 내는지 확인하는 재현성 자료이지, 운영 코드의 취약점 부재를 입증하는 자료는 아닙니다.

외부 상태를 바꾸기 전에 stage-only 결과와 사람 승인 경계를 분리하는 방법은 이 사이트의 npm stage-only 토큰과 사람 승인 경계 점검 글에서도 확인할 수 있습니다. 이 내부 링크는 보안 승인이나 품질 보증을 대신하지 않고, 변경 전후를 나누는 운영 원칙을 연결합니다.

공식 출처와 검증일

공식 기준은 2026년 10월 8일 다음 OWASP 1차 자료를 대조했습니다. XSS Prevention Cheat Sheet는 출력 인코딩, HTML sanitization, safe sinks와 문맥별 방어를 설명합니다. OWASP Top 10:2025 소개는 Broken Access Control, Security Misconfiguration, Software Supply Chain Failures, Cryptographic Failures, Injection 등 열 개 범주와 2025년 분류 변경을 설명합니다. 본문의 직접 증거는 이 기준을 읽고 만든 계정 없는 로컬 실습의 결과이며, 실제 제품이나 저장소의 보안 상태를 측정한 결과가 아닙니다.