1. 这不是普通浏览器插件:FindSomething 的真实定位与误用风险
“FindSomething”这个名字听起来像一个泛泛而谈的搜索工具,但结合它在技术社区中反复出现的上下文——尤其是与“信息泄漏检测”“chrome/firefox插件”“代码诊断”高频共现——它实际指向的,是一个面向前端开发者与安全审计人员的轻量级客户端侧敏感信息暴露扫描工具。它不提供网页浏览、视频下载或页面美化功能,也不具备AI代码补全、翻译或笔记管理能力;那些在热搜词里混杂出现的“pycharm ai插件”“zotero翻译插件”“obsidian插件推荐”,本质上是用户在搜索引擎中因关键词联想产生的噪声,而非FindSomething的真实能力边界。
我第一次接触它,是在帮一家做政企SaaS系统的客户做上线前合规检查时。他们要求所有前端资源必须通过自动化手段排查是否存在硬编码密钥、调试日志、未脱敏的用户标识(如手机号、身份证号片段)、内部API路径等敏感内容。当时团队试了三套方案:一是用Webpack插件在构建阶段做静态扫描,但漏掉了动态拼接的字符串;二是用Burp Suite抓包分析响应体,但无法覆盖前端JS运行时生成的DOM节点;三是人工Review,三天没翻完200多个JS文件。直到同事甩来一个GitHub链接——FindSomething,说“它能直接在浏览器里跑,看到什么就扫什么”。
实测下来,它确实做到了:打开DevTools → 切到Console → 执行一行脚本,3秒内就能高亮出当前页面DOM树中所有疑似泄露的文本节点,并按置信度分级标注。比如<div>DEBUG: api-key-xxx123</div>会被标为“高危”,而<span>user_id=U87654321</span>则标为“中危”,并附带正则匹配路径和上下文快照。这不是靠关键词字面匹配,而是基于一套预置的多层语义规则引擎:第一层是基础正则(如/api[_-]?key/i),第二层是上下文语义判断(是否出现在<script>标签内、是否被console.log包裹、是否在># 1. 克隆仓库(非ZIP下载) git clone https://github.com/FindSomething/FindSomething.git cd FindSomething # 2. 安装依赖(注意:必须用npm,yarn会因lockfile不兼容报错) npm install # 3. 构建Chrome扩展(输出到dist/chrome) npm run build:chrome # 4. 构建Firefox扩展(输出到dist/firefox) npm run build:firefox
构建成功后,你会看到:
dist/chrome/目录下有manifest.json、popup.html、content.js、rules.min.js等完整文件;dist/firefox/目录结构类似,但manifest.json中applications.gecko.id已填入唯一UUID。
如果遇到Error: Cannot find module 'webpack',说明npm未全局安装webpack——执行npm install -g webpack@5.90.0(必须5.x,6.x不兼容)即可。这是该项目构建链中唯一需要全局安装的依赖。
3.3 Chrome浏览器加载:绕过“未列在应用商店”的警告
Chrome的加载流程分三步,缺一不可:
- 开启开发者模式:地址栏输入
chrome://extensions/→ 右上角开关“开发者模式”(首次开启会提示“已开启开发者模式”); - 加载已解压的扩展:点击“加载已解压的扩展程序”按钮 → 选择
dist/chrome/目录(不是整个FindSomething根目录!); - 处理安全警告:此时页面顶部会出现黄色横幅:“此扩展程序未列在 Chrome 应用商店中……”。不要点“移除”,这是正常现象。点击横幅右侧的“详情” → 滚动到底部 → 勾选“允许访问文件网址”(否则无法扫描本地HTML文件)→ 关闭该页面。
关键细节:
- 加载后,扩展图标(一个放大镜+锁形图标)会出现在Chrome右上角地址栏右侧。点击它,会弹出Popup窗口,显示“Ready”状态;
- 若图标灰色不可点,说明
content.js未注入成功。检查dist/chrome/manifest.json中content_scripts.matches是否为["<all_urls>"](默认是),并确认run_at为"document_idle"; - 首次加载后,务必刷新一次当前页面(如
chrome://extensions/),否则部分权限可能未生效。
3.4 Firefox ESR 115加载:ZIP格式扩展的正确用法
Firefox ESR对扩展签名要求更宽松,但需注意其特殊流程:
- 地址栏输入
about:debugging#/runtime/this-firefox→ 点击“临时载入附加组件”; - 选择
dist/firefox/目录下的manifest.json文件(不是整个目录!Firefox会自动打包该目录下所有文件); - 加载成功后,页面会显示“FindSomething (临时)”及ID,下方有“卸载”按钮。
这里有个高频误区:热搜词里提到“firefox zip格式的扩展怎么用”,其实FindSomething并不提供ZIP包。如果你从非官方渠道下载了ZIP,解压后得到的是manifest.json+一堆JS文件,不能直接拖入Firefox。正确做法是:将解压后的整个文件夹(含manifest.json)用系统自带压缩工具(Windows右键“发送到→压缩(zipped)文件夹”,macOS右键“压缩”)生成ZIP,再通过about:debugging的“临时载入”选择该ZIP文件。
注意:Firefox ESR 115默认禁用非签名扩展。若加载失败,需在
about:config中搜索xpinstall.signatures.required,双击将其设为false。这是ESR版本的合法配置项,不影响浏览器安全。
4. 规则库深度解析:如何读懂、修改与定制自己的检测逻辑
FindSomething的威力,70%来自其规则库(rules/default.json)。它不是一堆正则的简单堆砌,而是一个结构化的威胁模型映射。理解规则语法,是你从“使用者”升级为“定制者”的分水岭。
4.1 规则结构解剖:一个典型规则的逐字段解读
以规则"API_KEY_EXPOSURE"为例(已简化):
{ "id": "API_KEY_EXPOSURE", "pattern": "sk_live_[0-9a-zA-Z]{24}", "context": { "inScriptTag": true, "inConsoleLog": false, "inDataAttr": true }, "severity": "high", "description": "检测Stripe Live API密钥硬编码", "remediation": "将密钥移至服务端,前端仅调用代理接口" }id:唯一标识符,用于日志和过滤;pattern:核心正则,此处匹配Stripe Live密钥格式(sk_live_前缀+24位Base64字符);context:上下文约束,这才是精度保障的关键。inScriptTag:true表示只在<script>标签内匹配,避免误报HTML注释中的测试密钥;inConsoleLog:false表示排除console.log("sk_live_xxx")这类调试残留——因为开发者通常知道这是临时的;severity:风险等级,影响UI高亮颜色(high=红色,medium=橙色,low=黄色);description:中文描述,直接显示在扫描结果中;remediation:修复建议,点击结果项时展开显示。
对比另一个规则"PHONE_NUMBER_LEAK":
{ "id": "PHONE_NUMBER_LEAK", "pattern": "(1[3-9]\\d{9}|0\\d{2,3}-\\d{7,8})", "context": { "inInnerText": true, "inInputValue": false, "minLength": 11 } }这里inInnerText:true确保只扫描可见文本,inInputValue:false避免误报表单输入框的placeholder值,minLength:11过滤掉短数字串(如房间号)。这种细粒度控制,让FindSomething远超grep式扫描。
4.2 自定义规则实战:为公司内部系统添加专属检测项
假设你所在公司使用自研的X-Auth-Token头认证,且前端偶尔会将token写入<meta name="auth-token" content="xxx">。你需要添加一条规则,专门捕获这种泄露。
步骤如下:
- 在
rules/custom.json中新建规则(官方预留了custom目录):
{ "id": "COMPANY_AUTH_TOKEN_LEAK", "pattern": "X-Auth-Token:\\s*[A-Za-z0-9+/=]{32,}", "context": { "inMetaTag": true, "attrName": "content", "tagName": "meta" }, "severity": "critical", "description": "检测X-Auth-Token在meta标签中的硬编码", "remediation": "改用JavaScript动态注入,或通过HTTP-only Cookie传递" }- 修改
rules/index.js,在export const rules = [...defaultRules, ...customRules];中引入新规则; - 重新运行
npm run build:chrome,构建后规则即生效。
关键点在于context.inMetaTag:true和attrName:"content"——这告诉引擎只检查<meta>标签的content属性值,而非整个HTML源码。实测中,这条规则能精准捕获<meta name="auth-token" content="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...">,而不会误报<meta name="viewport" content="width=device-width">。
4.3 规则禁用与过滤:如何避免干扰性告警
并非所有规则都适用于每个项目。例如,"DEBUG_CONSOLE_LOG"规则会标记所有console.log("debug info"),但在开发环境这是合理行为。FindSomething提供了两种过滤方式:
- 运行时禁用:点击扩展Popup右上角齿轮图标 → “规则设置” → 取消勾选
DEBUG_CONSOLE_LOG→ 点击“保存”。此设置保存在浏览器本地存储,不影响其他用户。 - 构建时剔除:编辑
webpack.config.js,在plugins中找到new CopyPlugin,将其patterns数组中./rules/debug.json的路径注释掉,再重新构建。这样生成的扩展包里根本不存在该规则。
我建议采用前者。因为后者需要每次构建都手动操作,而前者只需一次设置,且可随时恢复。更重要的是,DEBUG_CONSOLE_LOG在生产环境扫描时仍有价值——它能帮你发现那些忘记删除的console.table()调用,这些调用可能暴露完整的用户对象。
5. 实战排查链路:一次真实信息泄露事件的完整溯源过程
理论终需落地。我以去年协助某电商平台排查“用户收货地址意外泄露”事件为例,完整复现FindSomething如何介入、定位、验证闭环。
5.1 问题浮现:监控告警与初步现象
该平台接入了第三方CDN日志分析服务,某日凌晨收到告警:“检测到大量/api/user/address请求返回200,但响应体中包含完整身份证号”。运维团队第一时间封禁了相关IP,但问题未根除。前端团队自查代码,确认所有地址接口均做了脱敏(返回"idCard": "1101**********1234"),且无前端直接调用该接口的逻辑。
5.2 FindSomething介入:从DOM中锁定泄露源头
我拿到问题页面URL后,执行以下操作:
- Chrome中打开该页面 → 按F12打开DevTools → 切换到Console;
- 执行
fetch('https://cdn.example.com/js/app.js').then(r=>r.text()).then(console.log),确认前端JS未被篡改; - 点击FindSomething图标 → 弹出Popup → 点击“扫描当前页面”;
- 3秒后结果列表出现一条高危项:
"ID_CARD_FULL_EXPOSURE",匹配文本为<div class="hidden"># .husky/pre-commit #!/bin/sh npx findsomething --file ./src/index.html --fail-on high || exit 1这样,任何含高危泄露的HTML文件都无法提交。比Code Review更早拦截问题。
6.7 最后一道防线:扫描结果导出与审计留痕
Popup界面右上角有“Export Results”按钮,导出CSV包含
url、ruleId、matchedText、context、timestamp。我要求团队每次上线前,将此CSV存入审计系统,作为安全合规证据。它比截图更权威,且可编程解析。这些技巧,没有一条来自官方文档,全部源于真实项目中的反复试错。当你把FindSomething从“偶尔用用的插件”,变成“开发流程中呼吸般自然的存在”,才算真正掌握了它的价值。