Chrome扩展身份校验失败时禁用扩展的最佳实现方案
Chrome扩展付费身份校验最优实现方案
原有代码存在的核心问题
- 公开存储的授权列表明文暴露,所有付费用户的ID可被任意获取,存在隐私泄露和被批量伪造的风险
- 子串匹配逻辑存在误判漏洞,若某用户ID是另一个授权ID的子串,会出现非法用户被误放行的情况
- 无网络异常兜底逻辑,请求存储地址失败时默认跳过校验会直接导致防护失效
- 无完整的阻断逻辑,仅输出日志无法禁止用户使用扩展功能
优化实现方案
1. 授权存储逻辑优化
放弃用Pastebin存储明文授权列表,推荐两种可选方案:
- 自主搭建简单的后端接口,接收用户ID参数后返回单独的授权状态,避免全量授权列表外泄
- 若要继续使用公开存储,需将授权列表用对称加密算法加密后再上传,校验时本地解密后匹配,密钥硬编码在扩展代码中,避免明文泄露
2. 校验逻辑优化
优化后的校验代码如下:
// 扩展全局授权状态,默认未授权 let isExtensionAuthorized = false; // 授权校验主逻辑 chrome.identity.getProfileUserInfo({ 'accountStatus': 'ANY' }, async function (info) { const currentUserId = info.id?.trim(); // 无法获取用户ID直接阻断 if (!currentUserId) { blockExtensionUsage(); return; } try { const res = await fetch('你的授权数据存储地址'); if (!res.ok) throw new Error('授权请求失败'); const encryptAuthList = await res.text(); // 解密授权列表,需和你加密时的算法对应 const authList = decryptAuthList(encryptAuthList).split('\n').map(id => id.trim()).filter(Boolean); if (authList.includes(currentUserId)) { isExtensionAuthorized = true; // 校验通过,初始化扩展所有正常功能 initExtensionFunctions(); } else { blockExtensionUsage(); } } catch (err) { // 网络异常、解密失败等场景默认阻断,避免被绕过 blockExtensionUsage(); } }); // 扩展功能初始化入口,仅校验通过后执行 function initExtensionFunctions() { // 你的扩展原有业务逻辑全部移到这里执行 }
3. 全链路阻断逻辑实现
校验不通过时执行blockExtensionUsage函数,实现完全禁用扩展的效果,逻辑如下:
function blockExtensionUsage() { // 替换点击扩展图标弹出的页面为未授权提示页 chrome.action.setPopup({ popup: './unauthorized.html' }); // 卸载所有已注册的内容脚本,停止注入页面 chrome.scripting.unregisterContentScripts(); // 清空所有扩展定时任务 chrome.alarms.clearAll(); // 关闭所有已打开的扩展内部页面 chrome.tabs.query({ url: `chrome-extension://${chrome.runtime.id}/*` }, tabs => { tabs.forEach(tab => tab.id && chrome.tabs.remove(tab.id)); }); // 禁用所有扩展右键菜单 chrome.contextMenus.removeAll(); }
4. 防破解加固建议
- 对校验逻辑代码做混淆处理,避免用户直接修改判断条件绕过校验
- 不要长时间缓存校验结果,每次扩展唤醒、重启时都重新发起校验
- 不要将授权状态存储在localStorage、chrome.storage等可被用户手动修改的存储位置,优先用内存变量存储
内容的提问来源于stack exchange,提问作者exec85
相关产品推荐
相关产品推荐

