配置文件解析
我们来看一下metamask中manifest文件的定义:
{
// 浏览器工具栏按钮配置
"action": {
// 不同尺寸的图标路径(单位:像素),这是为了适配不同设备和环境
"default_icon": {
"16": "images/icon-16.png",
"19": "images/icon-19.png",
"32": "images/icon-32.png",
"38": "images/icon-38.png",
"64": "images/icon-64.png",
"128": "images/icon-128.png",
"512": "images/icon-512.png"
},
"default_title": "MetaMask", // 鼠标悬停提示文本
"default_popup": "popup-init.html" // 点击按钮弹出的页面
},
// 开发者信息(通常留官网链接)
"author": "https://metamask.io",
// 后台服务配置(MV3必须使用Service Worker)
"background": {
"service_worker": "scripts/app-init.js" // 后台入口文件
},
// 键盘快捷键配置
"commands": {
// 旧版API兼容(为了兼容firefox,这里的兼容代码是本人贡献的o(* ̄▽ ̄*)o
"_execute_browser_action": {
"suggested_key": {
"windows": "Alt+Shift+M",
"mac": "Alt+Shift+M",
"chromeos": "Alt+Shift+M",
"linux": "Alt+Shift+M"
}
},
// MV3标准快捷键
"_execute_action": {
"suggested_key": {
"default": "Alt+Shift+M",
"windows": "Alt+Shift+M",
"mac": "Alt+Shift+M",
"chromeos": "Alt+Shift+M",
"linux": "Alt+Shift+M"
}
}
},
// 内容脚本配置(注入到网页的JS)
"content_scripts": [
{
"matches": ["file://*/*", "http://*/*", "https://*/*"], // 注入目标URL模式
"js": [ // 按顺序注入的脚本,脚本的详细作用后续会讲
"scripts/disable-console.js", // 禁用危险API
"scripts/lockdown-install.js", // 安全沙箱初始化
"scripts/lockdown-run.js", // 执行环境隔离
"scripts/lockdown-more.js", // 增强安全策略
"scripts/contentscript.js" // 主业务逻辑
],
"run_at": "document_start", // 注入时机:DOM加载前
"all_frames": true // 注入所有iframe
},
{ // 特殊处理Trezor硬件钱包,不需要了解
"matches": ["*://connect.trezor.io/*/popup.html*"],
"js": ["vendor/trezor/content-script.js"]
}
],
// 国际化配置
"default_locale": "en", // 默认语言
"description": "__MSG_appDescription__", // 从_locales目录读取翻译
// 需要访问的域名白名单(重要!钱包必须包含RPC节点域名)
"host_permissions": [
"http://localhost:8545/", // 本地开发节点
"file://*/*", // 本地文件协议
"http://*/*", // 所有HTTP网站(慎用)
"https://*/*", // 所有HTTPS网站
"ws://*/*", // WebSocket连接
"wss://*/*" // 加密WebSocket
],
// 应用图标(用途同action.default_icon但独立配置)
"icons": {
"16": "images/icon-16.png",
"19": "images/icon-19.png",
"32": "images/icon-32.png",
"38": "images/icon-38.png",
"48": "images/icon-48.png",
"64": "images/icon-64.png",
"128": "images/icon-128.png",
"512": "images/icon-512.png"
},
"manifest_version": 3, // 必须显式声明使用MV3
"name": "__MSG_appName__", // 国际化应用名称
// 可选权限(运行时请求)
"optional_permissions": ["clipboardRead"], // 读取剪贴板
// 必须声明的权限(安装时请求)
"permissions": [
"activeTab", // 获取当前标签页权限
"alarms", // 定时任务(替代setTimeout)
"clipboardWrite", // 写入剪贴板(复制地址)
"notifications", // 桌面通知(交易状态提醒)
"scripting", // 动态执行脚本(DApp交互)
"storage", // 本地存储(用户配置)
"unlimitedStorage", // 突破5MB存储限制(交易记录)
"webRequest", // 网络请求拦截(API签名)
"offscreen" // 后台渲染(复杂计算隔离)
],
// 沙箱页面配置(安全隔离)
"sandbox": {
"pages": ["snaps/index.html"] // 高风险功能隔离执行
},
// 应用短名称(菜单栏显示)
"short_name": "__MSG_appName__",
// 内容安全策略(关键安全配置)
"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'none'; frame-ancestors 'none'; font-src 'self';", // 主页面策略
"sandbox": "sandbox allow-scripts; script-src 'self' 'unsafe-inline' 'unsafe-eval'; object-src 'none'; default-src 'none'; connect-src *; font-src 'self';" // 沙箱页面特殊策略
},
// 允许外部网页通信(DApp连接必须)
"externally_connectable": {
"matches": ["http://*/*", "https://*/*"], // 允许连接的网站
"ids": ["*"] // 允许所有扩展ID(钱包互操作)
},
// 最低Chrome版本要求(基于API兼容性)
"minimum_chrome_version": "115" // 需要Chrome 115+支持wasm等特性
}
以下是 Chrome 扩展中 content_security_policy 配置的详细解析,特别针对区块链钱包开发场景的安全设计:
主扩展页面策略 (extension_pages)
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'none'; frame-ancestors 'none'; font-src 'self';"
1. script-src 'self' 'wasm-unsafe-eval'
-
'self'
只允许加载扩展包内的脚本(如popup.js,background.js),禁止:- 内联脚本(如
<script>alert(1)</script>) - 远程 CDN 脚本(如
<script src="https://code.jquery.com/jquery.min.js">)
- 内联脚本(如
-
'wasm-unsafe-eval'
允许 WebAssembly 执行(区块链钱包必需):// 例如加密库使用 WASM const wasmModule = await WebAssembly.compile(wasmBinary);
2. object-src 'none'
- 禁止加载插件内容(如 Flash、Java Applet):
<!-- 以下内容会被拦截 --> <object data="flash.swf"></object> <embed src="malicious.pdf">
3. frame-ancestors 'none'
- 防止点击劫持(Clickjacking):
- 禁止其他网站通过
<iframe>嵌入你的扩展页面 - 避免恶意网站诱导用户误操作扩展界面
- 禁止其他网站通过
4. font-src 'self'
- 仅允许加载扩展包内的字体文件(如
.woff2):@font-face { src: url(chrome-extension://__EXT_ID__/fonts/main.woff2); /* 允许 */ src: url(https://fonts.com/risk.woff2); /* 被拦截 */ }
沙箱页面策略 (sandbox)
主要针对Metamask的扩展程序snap做权限限制,这里不做讲解
学习交流请添加vx: gh313061
下期预告:钱包的初始化(入口文件加载)