"MV3 의 보안 모델은 까칠할 정도로 의견이 강해 — 그게 버그가 아니라 feature."
Extension Sandbox
모든 Chrome extension 은 자기 renderer process 에서 돌아, 상호작용하는 host page 와 격리. Extension 은 chrome.* API 와 사적 origin (chrome-extension://<id>/) 에 접근하지만, host page 의 JavaScript context 에 직접 손 못 대. 통신은 의도된 채널로만 — message / isolated world 에 injected 된 content script / Chrome 의 tab API.
이 격리가 extension 이 user-script injector 보다 안전한 전체 이유. Host page 가 extension storage 를 손쉽게 못 읽고, extension 이 host 의 global scope 를 실수로 오염시킬 수도 없어.
MV3 의 Content Security Policy
MV3 는 extension page (popup / options / side panel) 에 빡센 default CSP 를 박아:
script-src 'self'; object-src 'self';
해석: script 는 extension package 자체에서만 실행. inline <script> 태그 안 됨, eval() 안 됨, new Function() 안 됨, handler 에 JavaScript URI 안 됨. Lesson 4 의 CSP gotcha 가 이 default 의 직접적 결과.
CSP 를 더 빡세게 (rare) 만들 수는 있지만, 푸는 건 빡세게 제한. 'unsafe-eval' 은 완전 금지. 'unsafe-inline' 은 script 에 대해 금지. WebAssembly compilation 진짜 필요하면 'wasm-unsafe-eval' 허용.
host_permissions — 어떤 page 를 만질 수 있어
API-capability 인 permissions list 와 별개로, host_permissions 는 extension 이 DOM read 또는 script inject 가능한 URL 을 선언. 두 패턴:
- 좁게 — 특정 origin list:
["https://news.ycombinator.com/*", "https://*.github.com/*"]. Chrome 이 install 시 user 한테 정확히 어떤 site 가 영향받는지 보여줌. - 광범위 —
["<all_urls>"]. 살벌한 install 경고 발동: "모든 website 의 모든 data 를 읽고 변경." Extension 이 진짜로 어디든 page access 필요할 때만 (ClipDeck 은 결국 필요 — selection capture 가 어느 page 에서든 동작해야).
중간 길은 API permissions list 에 activeTab — just-in-time grant: user 가 toolbar icon 클릭하면 Chrome 이 현재 tab 의 URL + DOM access 를 일시적으로 부여, tab navigation 시 만료. Install 시 경고 없음, 광범위 surface 도 없음.
Remote code 금지
MV3 는 network 로 JavaScript fetch 후 실행 금지. 구체적으로:
fetch("https://...")후 response 에eval()안 됨.- Extension HTML page 에
<script src="https://cdn.example.com/foo.js">안 됨. new Function(remoteString)안 됨.
허용되는 거: network 로 fetch 한 data (JSON / text / image) 를 data 로 다루기. 경계선은 실행. Server 가 extension 한테 뭘 렌더하라고 알려 — OK. Server 가 extension 한테 뭘 실행하라고 알려 — 금지.
chrome.permissions API — 필요할 때 요청
optional_permissions 또는 optional_host_permissions 에 선언된 permission 은 extension 이 runtime 에 chrome.permissions.request 로 요청 가능. Chrome 이 consent prompt 띄움, user 가 accept 또는 deny. 모든 거 미리 선언해서 install 시 user 겁먹게 하는 거의 정중한 대안.
ClipDeck 은 모든 permission 이 required-and-declared 로 유지 — 사적 tailnet 의 single-soul utility 한테는 유용한 optional-permission flow 없음. 근데 API 가 존재한다는 거 알기는 — fleet-distributable extension 설계할 때, 모든 Mac 을 install 시 겁먹게 하기 싫을 때 중요해.
<script> 태그나 onclick= handler 검색하는 게 복구 경로.