Files
networkSetup/docs/code-design/16-smart-app-control-signing-scope.md
T
jychoi4andClaude Opus 5.5 7f5540f148 docs: design the EXE installer UI and code signing scope
- Design 14: WiX MSI + Burn with a C# BA host and WebView2 web UI,
  default screen catalog, installer-ui.json and the WebView2 fallback.
- Design 16: Smart App Control checks and what must be signed.
- Manual: beginner guide to Azure Artifact Signing.
- Link the decision from designs 09 and 10 and record it.

Refs #15

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:08:50 +09:00

10 KiB

16 스마트 앱 컨트롤 검사 대상과 서명 범위

2026-11-09 작성. 스마트 앱 컨트롤(Smart App Control, 이하 SAC)이 켜진 PC에서 설치한 제품이 동작하려면 무엇을 서명하고 무엇을 배포하지 말아야 하는지 정리한 참조 문서다. 서명 시스템(EXE 출력의 서명 단계, 05 릴리스 생성)을 설계할 때 입력으로 쓴다. 이 문서는 조사 결과이며 구현이나 SAC 실제 시험 통과를 뜻하지 않는다. 정책 결정은 별도 변경 기록으로 남긴다.

SAC 판정 순서

  1. Microsoft 클라우드 평판 서비스가 안전 여부를 확신할 수 있으면 그 판정대로 허용하거나 차단한다. 유효한 서명이 있어도 악성 판정이면 차단된다.
  2. 확신할 수 없으면 서명을 본다. 유효한 서명이 있으면 허용하고, 서명이 없거나 유효하지 않으면 차단한다.
  3. 앱별·파일별 예외를 둘 수 없다. 사용자 선택지는 SAC를 끄는 것뿐이다. 최근 업데이트부터 끈 뒤 다시 켤 수 있다.

SmartScreen은 진입 실행 파일 하나만 평판을 보지만, SAC는 운영체제 로더와 스크립트 엔진이 불러오는 모든 코드를 검사한다. 서명된 설치기가 서명 없는 코드를 풀어 놓는 방식은 통과하지 못한다.

서명 요건

요건 내용
신뢰 루트 Microsoft 신뢰 루트 프로그램(Trusted Root Program)에 속한 루트로 이어져야 한다. 사용자나 관리자가 직접 등록한 루트(개발용 인증서 포함)는 인정되지 않는다.
다이제스트 SHA-256 이상을 쓴다(signtool sign /fd sha256).
키 알고리즘 RSA를 쓴다. ECC는 지원되지만 호환성을 위해 피한다.
타임스탬프 SAC 자체 요건으로 명시된 자료는 없다. 인증서 만료 뒤에도 서명이 유효하도록 반드시 붙인다(/tr <TSA URL> /td sha256).
서명 후 불변 서명 뒤 리소스·버전 정보를 수정하면 서명이 깨진다. 모든 후처리는 서명 전에 끝낸다.
스크립트 서명 WinVerifyTrust로 검증하며, 서명 루트가 대상 PC의 신뢰 루트 저장소에 있어야 한다. 공인 루트는 이 조건을 충족한다.

검사 대상 분류

A. 실행 코드(PE) — 반드시 서명

확장자가 아니라 파일 헤더(MZ와 PE 서명)로 판별한다. 운영체제 로더는 확장자와 관계없이 이미지를 불러올 때 검사한다.

  • Microsoft가 명시한 확장자: .exe, .com, .dll, .rll, .ocx, .sys
  • MotW 차단 목록에도 있는 PE 확장자: .cpl, .drv, .scr, .vxd
  • 제품 고유 확장자 예(EG-BIM): .irx, .tx, .txv, .txr
  • .NET 어셈블리(관리 코드 DLL)도 PE이므로 같은 기준으로 서명한다.

B. Windows Installer — 서명

  • .msi, .msp: 서명한다. MSI가 설치 중 임시 폴더에 푸는 사용자 지정 작업(Custom Action) DLL·EXE도 A와 같은 기준으로 미리 서명한다.
  • .mst: App Control의 검사 대상이다. 서명 방법과 필요 여부는 확인이 필요하다.

C. 패키지 — 패키지 서명

  • .appx, .appxbundle, .msix, .msixbundle: 패키지 서명으로 처리한다. 패키지 안의 PE를 개별 서명해야 하는지는 SAC 시험으로 확인한다.

D. 스크립트(App Control 연동 스크립트 호스트) — 서명하거나 배포하지 않음

호스트 확장자 서명이 없을 때
PowerShell .ps1, .psm1, .psd1 차단되지 않고 제한 언어 모드(Constrained Language Mode)로 실행된다. 기능이 조용히 실패할 수 있다. 진입 스크립트가 불러오는 모듈과 dot-source 파일도 모두 서명해야 한다.
Windows Script Host(wscript.exe, cscript.exe) .vbs, .js, .wsf 차단된다.
Windows Script Host(인코딩 스크립트) .vbe, .jse 배포하지 않는다.

E. 사용 금지

  • .hta(mshta.exe): 스크립트 검사가 켜진 App Control 정책이 하나라도 있으면 모든 실행이 차단된다. SAC 환경에서도 같다고 보고 배포하지 않는다.
  • MSXML을 통한 스크립트 실행(XSL 스크립트 등): 위와 같은 이유로 쓰지 않는다.

F. 직접 통제 밖 — 서명 대상 아님, 단 실행되는 하위 프로그램은 검사됨

  • .bat, .cmd(cmd.exe): App Control이 직접 통제하지 않으며 서명할 수도 없다. 배치 파일이 실행하는 EXE와 DLL은 검사된다.
  • 앱이 스스로 해석하는 데이터·스크립트(LISP, CUI, DCL, 도면, 이미지 등): 검사 대상이 아니다.
  • App Control과 연동하지 않는 타사 스크립트 엔진(Python, Java 등): 엔진 실행 파일은 A 기준으로 검사되지만, 그 엔진이 실행하는 스크립트는 통제되지 않는다.

G. 인터넷에서 받은 파일(MotW)에 대한 차단 목록

웹 표식(Mark of the Web, MotW)이 붙은 아래 확장자는 열기 자체가 차단되고 무시 선택지가 없다. 목록은 고정이며 레지스트리로 바꿀 수 없다. 2026-04 기준 자료이므로 서명 시스템에는 갱신 가능한 데이터로 둔다.

.appref-ms, .appx, .appxbundle, .bat, .chm, .cmd, .com, .cpl, .dll, .drv, .gadget, .hta, .iso, .js, .jse, .lnk, .msc, .msp, .ocx, .pif, .ppkg, .printerexport, .ps1, .rdp, .reg, .scf, .scr, .settingcontent-ms, .sys, .url, .vb, .vbe, .vbs, .vhd, .vhdx, .vxd, .wcx, .website, .wsf, .wsh

배포와 업데이트에 적용하는 규칙:

  • 배포물은 서명된 .exe 또는 .msi로 직접 내려받게 한다. .iso, .vhd, .vhdx로 감싸지 않는다.
  • 업데이트가 받는 파일에 이 목록의 확장자를 쓰지 않는다. 패치는 서명된 설치 파일 형태로 받아 실행한다.
  • MotW를 지워서 차단을 피하는 방식은 쓰지 않는다.
  • 설치기가 디스크에 쓴 파일에는 보통 MotW가 붙지 않는다. 따라서 설치된 .chm, .bat 등은 이 목록의 영향을 받지 않는 것으로 본다. 이 판단은 SAC 시험으로 확인한다.

서명 시스템 반영 요구사항

  1. PE 판별: 수집한 모든 파일을 헤더로 검사해 PE를 찾는다. 확장자 목록만으로 판정하지 않는다(05 릴리스 생성의 기존 원칙).

  2. 확장자 분류 데이터: B~G 분류를 코드에 고정하지 않고 버전이 붙은 데이터로 둔다. 분류 결과를 서명 보고서에 기록한다.

  3. 파일별 정책: 기존 sign-owned, verify-vendor, not-applicable을 유지한다. 서명 없는 타사 PE(오픈소스 등)를 처리할 정책은 결정이 필요하다.

  4. 거부 규칙: 정식 빌드에서 아래를 발견하면 설명과 함께 거부한다.

    • 서명할 수 없거나 서명되지 않은 PE
    • D 분류의 서명 없는 스크립트
    • E 분류 파일
    • 배포물 형식이 G 목록에 해당하는 경우

    오류 코드는 구현 시 정하고 src/README.md에 적는다.

  5. 서명 검증: 서명 후 모든 대상 파일을 다시 검증하고 아래 항목을 기록한다. 허용할 루트 인증서의 지문은 계획에 고정한다.

    • 다이제스트가 SHA-256 이상인지
    • 체인과 루트 지문
    • 타임스탬프 유무
    • 서명자
  6. 실행 중 생성 코드 점검표: 정적 검사로 찾을 수 없으므로, 제품마다 아래 질문을 확인 항목으로 둔다.

    • 업데이트가 내려받는 파일은 무엇인가
    • 자체 압축 해제 EXE를 만드는 기능이 있는가
    • 임시 폴더에 DLL을 풀어서 쓰는가
    • 실행 중에 코드를 컴파일해 디스크에 저장하는가

EG-BIM 조사 결과

2026-11-09 이 PC에 설치된 EG-BIM(C:\Program Files\Baron\EG-BIM)을 읽기 전용으로 조사했다. SAC를 켠 실제 실행 시험은 하지 않았다.

항목 결과
PE 파일 965개. 서명 유효 620개, 서명 없음 344개, 판정 오류 1개(IntelliConvert.com)
바론 서명 파일 6개(Grimi.exe, Kkureomi.exe, LoadFile.exe, EGBIM.Drawer.Splash.exe, Nyng.PlotWindow.exe, PlotStyleTableEditor.exe)
바론 인증서 GlobalSign GCC R45 CodeSigning CA 2020 발급, 루트 GlobalSign Code Signing Root R45(AuthRoot 저장소에 있음), 2026-08-10~2027-08-11, 온라인 폐기 확인 통과, 타임스탬프 있음
서명 없는 PE 확장자 .dll 294, .irx 31, .exe 9, .tx·.txv·.txr 10, .com 1
그 밖의 SAC 관련 파일 .chm 9개, .bat 1개(Nyng.bat). .ps1, .vbs, .js, .hta, .msi는 없음
실행 중 생성 코드 후보 Extractor.exe(자체 압축 해제 스텁으로 보임), BaronSoftware.Update.dll(업데이트)

SAC 시험 항목(미실행)

SAC가 켜진 Windows 11 VM 스냅샷에서 실행하고 CodeIntegrity/Operational(3076, 3077, 3089)과 AppLocker/MSI and Script(8028, 8029, 8037, 8038) 이벤트를 수집한다.

  • 모든 PE를 서명한 빌드의 설치·실행·주요 기능·업데이트·제거
  • .irx, .tx 등 비표준 확장자 PE가 검사·차단되는지
  • 서명된 .dll, .msp에 MotW가 붙었을 때 G 목록 차단이 서명으로 풀리는지
  • MSIX 내부 PE를 개별 서명하지 않아도 되는지
  • 설치된 .chm, .bat이 영향받지 않는지
  • 첫 실행과 두 번째 실행의 시작 시간 차이

근거