PyInstaller onefile exe가 윈도우 디펜더에 오탐 차단될 때 뚫은 방법: 우회 말고 신뢰도부터 올렸다

PyInstaller로 만든 onefile exe가 Microsoft Defender에 막히면, 먼저 해야 할 일은 ‘백신을 속이는 우회’가 아니라 빌드 산출물을 덜 수상하게 만들고, 오탐 신고와 서명까지 정리하는 것입니다. 특히 --onefile, UPX 압축, 콘솔 숨김, 임시 폴더 실행 패턴이 겹치면 정상 앱도 Trojan류로 분류될 수 있습니다.

먼저 –clean –noupx로 새 빌드를 만들고, 차단이 반복되면 Microsoft 오탐 제출까지 이어가세요.

제가 정리한 흐름은 이렇습니다. UPX 제거 → clean 빌드 → spec 파일 최소화 → VirusTotal 확인 → Microsoft Security Intelligence에 오탐 제출 → 필요하면 코드 서명 순서로 가면 가장 안전하고 재현성이 좋았습니다. Claude Code나 Cursor로 빌드 스크립트를 정리할 때도 이 순서를 체크리스트로 넣어두면 덜 헤맵니다.

바로 해볼 것
지금 exe를 다시 만들기 전, --noupx와 clean 빌드부터 적용해 보세요.
오탐 줄이는 체크리스트 보기

왜 onefile exe가 더 자주 걸릴까

PyInstaller의 onefile 모드는 실행 파일 안에 Python 런타임과 라이브러리를 묶고, 실행 시 임시 폴더에 풀어서 동작합니다. 사용자는 파일 하나라 편하지만, 보안 제품 입장에서는 ‘압축된 실행 파일이 자기 자신을 풀고 실행하는 패턴’으로 보일 수 있습니다.

여기에 아이콘 변경, 콘솔 숨김, 네트워크 요청, 자동 업데이트, 브라우저 자동화 같은 기능이 들어가면 위험 점수가 올라갑니다. Playwright, Selenium, requests, pyautogui를 같이 쓴 자동화 도구라면 더 민감하게 잡힐 수 있습니다.

내가 실제로 적용한 빌드 체크리스트

가장 먼저 한 일은 빌드를 단순하게 만드는 것이었습니다. 기존에는 용량을 줄이려고 UPX를 켜고, 배포 폴더를 그대로 덮어쓰며 빌드했습니다. 이 방식은 빠르지만 오탐 원인을 찾기 어렵습니다.

pyinstaller --onefile --clean --noupx --name MyTool app.py

그리고 build, dist, __pycache__를 지운 뒤 새로 만들었습니다. Claude Code에는 “PyInstaller spec에서 불필요한 hiddenimport와 datas를 제거하고, 빌드 명령을 재현 가능하게 정리해줘”라고 요청해 spec 파일을 다이어트했습니다.

만약 exe가 회사 내부용이라면 파일명도 중요합니다. update.exe, helper.exe, service.exe처럼 악성코드에서 자주 쓰이는 이름은 피하고, 제품명과 회사명을 드러내는 이름이 낫습니다.

오탐 확인은 VirusTotal 하나로 끝내지 않았다

VirusTotal은 빠른 참고용으로 좋지만, 거기서 1~3개 엔진이 잡는다고 바로 악성이라는 뜻은 아닙니다. 반대로 0개라고 해서 모든 PC에서 통과한다는 보장도 없습니다. Windows Defender가 실제로 막는다면 Microsoft 쪽에 샘플을 제출하는 게 핵심입니다.

Microsoft Security Intelligence 포털에서 ‘Software developer’로 제출하고, 프로그램 설명, 다운로드 경로, 재현 상황을 짧게 적습니다. 내부 배포 도구라면 “사내 업무 자동화용 Python desktop utility, no persistence, no credential collection”처럼 기능 범위를 명확히 적는 편이 좋습니다.

선택지는 세 가지: 빌드 수정, 코드 서명, 배포 방식 변경

한 번에 모든 걸 할 필요는 없습니다. 개인용·테스트용인지, 고객에게 배포하는 앱인지에 따라 선택이 달라집니다.

방법 효과 비용/난이도 추천 상황
–noupx, –clean, spec 정리 가장 빠르게 오탐 가능성 감소 낮음 개인 도구, 내부 자동화, 초기 테스트
Microsoft 오탐 신고 Defender 탐지명 해제 가능 중간, 대기 필요 특정 탐지명으로 반복 차단될 때
코드 서명 인증서 배포 신뢰도 상승, SmartScreen 완화 비용 있음 외부 고객, 유료 SaaS 보조 앱
Nuitka 또는 MSI 설치형 전환 패키징 패턴 변경 중간~높음 onefile 구조 자체가 계속 문제일 때

구체적인 예: 내부 업무 자동화 exe를 다시 포장한 경우

예를 들어 Python으로 만든 재고 CSV 정리 도구가 있다고 가정해 보겠습니다. pandas로 엑셀을 읽고, requests로 사내 API를 호출한 뒤 결과 파일을 저장하는 단순 앱입니다. 처음에는 --onefile --noconsole에 UPX까지 적용했더니 일부 PC에서 차단됐습니다.

이때 저는 기능을 바꾸기보다 빌드 환경을 먼저 고정합니다. Python 가상환경을 새로 만들고, PyInstaller 버전을 명시하고, --noupx --clean으로 다시 빌드합니다. 그다음 --onedir 버전도 같이 만들어 Defender 반응을 비교합니다. onefile만 막히고 onedir은 통과한다면, 기능보다 패키징 패턴이 원인일 가능성이 큽니다.

이런 사람에게는 이렇게 권합니다

혼자 쓰는 자동화 도구라면

굳이 코드 서명부터 살 필요는 없습니다. --noupx, clean 빌드, 파일명 정리, VirusTotal 확인만으로도 많은 문제가 줄어듭니다. 그래도 막히면 Microsoft에 오탐 제출을 먼저 해보세요.

고객이나 팀에 배포한다면

설치형 배포를 고려하세요. Inno Setup, WiX Toolset, MSIX 패키징을 쓰면 업데이트와 제거 경험도 좋아집니다. 여기에 signtool로 코드 서명을 붙이면 SmartScreen 신뢰를 쌓는 데 도움이 됩니다. 단, 인증서를 샀다고 모든 경고가 즉시 사라지는 것은 아닙니다.

AI 코딩 에이전트로 빌드 자동화한다면

Cursor, Codex, Claude Code에게 “백신 우회 코드”를 만들라고 시키면 방향이 틀어집니다. 대신 “PyInstaller 빌드 재현성 확보, 불필요한 import 제거, 릴리스 체크리스트 작성”을 맡기세요. GitHub Actions에서 Windows 빌드 로그와 해시값을 남기면 나중에 오탐 신고할 때도 설명이 쉬워집니다.

자주 막히는 질문

Q. exe에 압축이나 난독화를 넣으면 더 잘 통과하나요?

대체로 반대입니다. 압축, 난독화, 런타임 언패킹은 보안 제품이 싫어하는 신호입니다. 정당한 앱이라면 투명하게 빌드하고 서명하는 쪽이 안전합니다.

Q. Defender 예외 등록을 사용자에게 안내해도 되나요?

개인 테스트라면 가능하지만, 배포 문서에 “백신을 끄세요”라고 쓰는 건 신뢰를 크게 깎습니다. 먼저 오탐 신고와 빌드 수정으로 해결하고, 예외 등록은 임시 조치로만 안내하는 편이 좋습니다.

Q. PyInstaller 대신 Nuitka로 바꾸면 해결되나요?

해결될 때도 있지만 만능은 아닙니다. Nuitka는 컴파일 방식이 달라 탐지 결과가 바뀔 수 있으나, 네트워크 자동화·브라우저 제어 같은 기능 자체가 민감하면 여전히 검사가 필요합니다.

마지막으로 할 일

지금 막힌 상태라면 exe를 계속 이름만 바꿔 올리지 말고, 해시값과 탐지명을 기록하세요. 그다음 --clean --noupx로 다시 빌드하고, onefile과 onedir 결과를 비교한 뒤 Microsoft에 오탐 제출까지 진행하면 됩니다.

PyInstaller onefile exe가 윈도우 디펜더에 오탐 차단될 때 뚫은 방법은 ‘몰래 지나가기’가 아니라, 보안 제품이 납득할 수 있는 배포물로 만드는 과정에 가깝습니다. 이 흐름을 한 번 릴리스 체크리스트로 만들어두면 다음 자동화 도구를 배포할 때 훨씬 덜 불안합니다.

관련 링크

글쓴이 용기

AI 코딩 에이전트로 직접 빌드하는 개발자. Claude Code·Codex 실사용 후기와 빌더 일지를 씁니다.

지식창고