03 · Security — 보안 용어
이 챕터: Electron의 보안은 Chromium 보안 + Node 격리 + OS 코드 서명의 3중 적층. 여기는 그 3중을 가리키는 용어 26개. 참고 챕터: 05-security, 06-packaging-distribution
allowRunningInsecureContent
HTTPS 페이지에서 HTTP 리소스를 로드하게 허용하는 webPreferences 플래그. 기본 false.
켜면 MITM이 JS 한 줄을 끼워 넣어
ipcRenderer를 호출할 수 있다 — 절대 켜지 말 것. 켜야 한다는 요구는 거의 항상 legacy HTTP API 때문 — 그것부터 고치는 게 답.
관련: [webSecurity], [CSP], [Mixed Content]
참고 챕터: 05-security
Authenticode
Microsoft의 Windows 코드 서명 표준. PE 바이너리(.exe, .dll, .msi)에 서명 + 타임스탬프.
서명 없으면 [SmartScreen]이 “알 수 없는 게시자” 경고를 띄운다. signtool/osslsigncode로 서명. EV 인증서로 서명하면 reputation 누적 없이 즉시 SmartScreen 통과. 타임스탬프는 인증서 만료 후에도 서명을 유효하게 만드는 핵심 — 빠뜨리면 1년 뒤 빌드가 다 깨진다.
관련: [Code Signing], [EV Certificate], [SmartScreen]
참고 챕터: 06-packaging-distribution
Code Signing
바이너리에 서명자 신원과 무결성을 새기는 OS 차원의 절차.
macOS: codesign + [Developer ID] + [Hardened Runtime] + [Notarization]. Windows: signtool + [Authenticode] (+ EV). Linux: 표준 없음 (배포 서명·gpg에 의존). 셋이 한 묶음: 서명 → 타임스탬프 → (macOS는) 노타라이즈. 하나라도 빠지면 사용자가 못 연다.
관련: [Authenticode], [Developer ID], [Notarization], [Hardened Runtime]
참고 챕터: 06-packaging-distribution
CORS (Cross-Origin Resource Sharing)
브라우저가 다른 origin의 fetch/XHR에 적용하는 표준 정책.
Electron의 renderer도 기본적으로 브라우저 규칙을 따른다. 단, Electron은
session.webRequest.onHeadersReceived로 응답 헤더를 조작 가능 — 임시로 CORS를 우회할 수 있다는 점이 양날의 검. 외부 origin 로드 시 우회는 최소 범위, 최소 기간만.
관련: [webSecurity], [session]
참고 챕터: 05-security
CSP (Content-Security-Policy)
페이지가 어떤 origin의 어떤 리소스를 로드할 수 있는지 선언하는 HTTP 헤더/메타 태그.
Electron에서는 모든 페이지에 엄격한 CSP가 사실상 필수. 권장 베이스:
default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'. 외부 CDN을 쓰지 말고 자체 번들.'unsafe-inline'/'unsafe-eval'사용은 왜 필요한지 PR에 적고, 가능하면 제거.
관련: [webSecurity], [allowRunningInsecureContent]
참고 챕터: 05-security
DEP (Data Execution Prevention)
OS가 데이터 페이지를 실행 페이지로 못 만들게 막는 메모리 보호. Windows/Linux/macOS 모두 지원.
Electron은 V8 JIT 때문에 부분적으로 RWX 페이지가 필요 → 완전 DEP는 불가능. 하지만 사용자 코드 영역은 DEP 보호 — buffer overflow 공격을 한 단계 막는다.
관련: [Hardened Runtime], [ASLR]
참고 챕터: 05-security
Delta Update (보안 측면)
[04-packaging-distribution]에 정의된 증분 업데이트. 보안 관점에서는 서명 검증이 더 까다롭다.
Squirrel.Windows의 nupkg delta는 전체 패키지의 서명에 의존. 부분 변조가 서명을 깨도록 전체 해시 기반이어야 안전. 자체 구현 시 가장 흔한 실수.
관련: [Code Signing], [autoUpdater]
참고 챕터: 06-packaging-distribution
Developer ID
macOS의 외부 배포용 인증서 (App Store 외). Apple Developer Program 가입 후 발급.
Developer ID Application(앱 서명) +Developer ID Installer(.pkg 서명)의 두 종류. App Store 배포는 Mac App Distribution 인증서로 별도. Developer ID로 서명 + Notarization 통과해야 [Gatekeeper]가 첫 실행을 허락한다.
관련: [Code Signing], [Gatekeeper], [Notarization]
참고 챕터: 06-packaging-distribution
Entitlements
macOS 앱이 어떤 보호 자원에 접근할지 선언하는 plist. 코드 서명에 함께 새겨진다.
com.apple.security.cs.allow-jit(V8 JIT 위해 필수),com.apple.security.device.camera,com.apple.security.device.microphone,com.apple.security.files.user-selected.read-write(sandbox 앱에서 사용자 선택 파일 접근). [Hardened Runtime] + entitlements 조합으로 미세하게 권한 부여.
관련: [Hardened Runtime], [Code Signing]
참고 챕터: 06-packaging-distribution
EV Certificate (Extended Validation)
일반 OV 코드 서명 인증서보다 엄격한 신원 검증을 거친 인증서.
Windows에서 SmartScreen reputation을 즉시 획득 — OV로 서명하면 수천 명이 다운로드한 뒤에야 reputation이 쌓이는데, EV는 그 단계를 건너뛴다. 가격이 비싸고(연 200~600 USD) HSM/USB 토큰 의무가 일반적. 2023년 이후 전 인증서가 HSM 의무화 (CA/B Forum 변경).
관련: [Authenticode], [SmartScreen]
참고 챕터: 06-packaging-distribution
Fuses
Electron 바이너리에 컴파일 후 켜거나 끄는 보안 토글. @electron/fuses 패키지로 조작.
예:
RunAsNode(false로 끄면ELECTRON_RUN_AS_NODE환경변수로 Node 셸 진입 차단),EnableNodeCliInspectArguments(false면--inspect디버거 차단),OnlyLoadAppFromAsar(asar 외부 코드 로드 금지),LoadBrowserProcessSpecificV8Snapshot. 빌드 후npx @electron/fuses ...로 적용. production 빌드에 반드시 적용해야 디버거 우회 공격이 막힌다.
관련: [asar], [V8 Snapshot]
참고 챕터: 05-security, 06-packaging-distribution
Gatekeeper
macOS의 첫 실행 검증 시스템. 인터넷에서 받은 파일을 격리하고 서명·노타라이즈 여부를 본다.
다운로드된 파일에 [quarantine] 확장 속성이 붙고, 첫 실행 시 Gatekeeper가 Developer ID 서명 + Notarization을 확인. 둘 다 통과 못 하면 “확인되지 않은 개발자” 경고로 차단.
spctl --assess --verbose Foo.app로 사전 점검.
관련: [Developer ID], [Notarization], [quarantine attribute]
참고 챕터: 06-packaging-distribution
Hardened Runtime
macOS의 추가 보안 런타임. 코드 서명 시 옵트인. Notarization의 전제 조건.
켜면 dyld injection, 미서명 라이브러리 로드, JIT 메모리(기본) 등이 막힌다. Electron의 V8 JIT을 위해
com.apple.security.cs.allow-jitentitlement를 반드시 부여.--options runtime을 codesign에 줘서 활성화.
관련: [Entitlements], [Notarization], [Code Signing]
참고 챕터: 06-packaging-distribution
Mixed Content
HTTPS 페이지가 HTTP 리소스를 섞어 로드하는 상황. 브라우저/Electron 기본 차단.
[allowRunningInsecureContent]로 우회 가능하지만 MITM에 그대로 열린다. Electron 앱이 외부 콘텐츠를 임베드한다면 HTTPS-only 강제 + CSP
upgrade-insecure-requests.
관련: [CSP], [allowRunningInsecureContent]
참고 챕터: 05-security
Notarization
Apple이 서명된 바이너리를 자기 서버로 보내 멀웨어 스캔을 받는 절차. macOS 10.15+ 필수.
xcrun notarytool submit Foo.dmg --apple-id ... --team-id ... --wait→ ticket을 받아xcrun stapler staple Foo.dmg로 첨부. ticket이 오프라인에서도 Gatekeeper에 보이게 된다. 흔한 함정: Hardened Runtime이 꺼져 있거나, entitlements가 부족하거나, JIT 허용 없이 V8을 쓰면 거절.
관련: [Hardened Runtime], [Developer ID], [Gatekeeper]
참고 챕터: 06-packaging-distribution
Origin (Electron 관점)
페이지의 scheme + host + port. 보안 결정의 가장 작은 단위.
Electron의
file://은 unique origin —file://끼리는 origin이 같지 않다. 그래서file://에서 fetch가 막힌다. 해결책: 커스텀app://scheme을protocol.registerSchemesAsPrivileged로 standard + secure로 등록 → CSP·CORS·service worker 다 정상 동작.
관련: [protocol (Electron module)], [CSP], [CORS]
참고 챕터: 05-security
quarantine attribute (macOS)
브라우저·메일이 다운로드 파일에 붙이는 확장 속성 (com.apple.quarantine).
이게 붙은 파일을 처음 열 때 [Gatekeeper]가 발동.
xattr -d com.apple.quarantine Foo.app으로 제거 가능(개발 중 디버깅용). 사용자가 서명 안 된 앱을 강제로 열 때 “이 파일 정말 열까요?” 다이얼로그가 뜨는 이유.
관련: [Gatekeeper], [Notarization]
참고 챕터: 06-packaging-distribution
remote module (deprecated)
Renderer에서 Main의 객체를 프록시 호출하던 모듈. Electron 14에서 제거.
const { BrowserWindow } = require('@electron/remote')시절 — XSS 한 번에 Main의app.quit()까지 호출됐다. 모든 새 코드는 [contextBridge] + IPC로 대체. 흔적이 남아 있다면 기술 부채 1순위.
관련: [contextBridge], [ipcMain], [nodeIntegration]
참고 챕터: 03-ipc-bridge, 05-security
Same-Origin Policy
브라우저의 기본 격리 규칙. 다른 origin의 DOM·쿠키·storage에 접근 금지.
Electron renderer에도 적용. [webSecurity: false]로 끄지 말 것 — 끄면 같은 페이지에 임베드된 광고 iframe이 메인 페이지 storage를 읽을 수 있다.
관련: [Origin], [CORS], [webSecurity]
참고 챕터: 05-security
setPermissionRequestHandler
Renderer가 카메라·마이크·알림·지오로케이션을 요청할 때 허락/거절을 결정하는 핸들러.
session.setPermissionRequestHandler((webContents, permission, callback) => callback(permission === 'media')). 기본은 전부 허락 — 외부 콘텐츠를 로드한다면 반드시 화이트리스트. 잊으면 임의 페이지가 카메라를 켤 수 있다.
관련: [session], [systemPreferences]
참고 챕터: 05-security
SmartScreen
Microsoft Defender의 다운로드 평판 검사. Windows 8+.
새 바이너리/새 서명자는 다운로드 수가 적어 “이 앱을 알 수 없습니다” 경고. [EV Certificate]는 이 단계를 건너뛴다. [Authenticode] 서명만으로도 reputation은 서명자별로 누적 — 일반 OV는 수천 다운로드 + 수 주가 필요.
관련: [Authenticode], [EV Certificate]
참고 챕터: 06-packaging-distribution
Stapler
[Notarization]에서 받은 ticket을 바이너리에 첨부하는 도구. xcrun stapler staple.
ticket을 첨부하면 Gatekeeper가 오프라인 상태에서도 노타라이즈 여부를 확인 가능. 빠뜨리면 인터넷 없는 환경에서 첫 실행이 실패. dmg/zip/app 모두에 가능.
관련: [Notarization], [Gatekeeper]
참고 챕터: 06-packaging-distribution
Timestamp (코드 서명)
서명 시점을 제3자 TSA가 보증하는 절차. 인증서 만료 후에도 서명을 유효하게 만든다.
signtool/codesign에
/tr http://timestamp.digicert.com같은 TSA URL 제공. 빠뜨리면 인증서 만료일 = 서명 만료일 → 1~3년 뒤 배포된 바이너리가 갑자기 “유효하지 않은 서명”이 된다.
관련: [Authenticode], [Code Signing]
참고 챕터: 06-packaging-distribution
webSecurity
renderer의 same-origin policy를 적용할지 결정하는 플래그. 기본 true.
false로 끄면file://페이지가 임의의 외부 origin을 fetch 가능 — XSS와 외부 데이터 유출의 콤보 폭격. 끄지 말 것. 정말 필요하면 외부 콘텐츠를 별도 BrowserView에 격리.
관련: [Same-Origin Policy], [allowRunningInsecureContent], [CSP]
참고 챕터: 05-security
will-navigate / setWindowOpenHandler
Renderer가 외부 URL로 이동하거나 새 창을 열려고 할 때 가로채는 webContents 이벤트.
webContents.on('will-navigate', (e, url) => { if (외부_origin) e.preventDefault() })로 phishing 차단.webContents.setWindowOpenHandler(({ url }) => { shell.openExternal(url); return { action: 'deny' } })로 새 창은 기본 브라우저로 위임. 안 막으면 renderer 안에서 임의 사이트가 열려 보안 모델이 무너진다.
관련: [shell (Electron module)], [Origin]
참고 챕터: 05-security