freehire 安全实践清单:gitleaks 防泄密、PII 脱敏、Tracer 知情同意与 Fail-Closed 设计
freehire 安全实践清单gitleaks 防泄密、PII 脱敏、Tracer 知情同意与 Fail-Closed 设计【免费下载链接】freehirefreehire — the open-source search engine for job seekers项目地址: https://gitcode.com/GitHub_Trending/fr/freehirefreehire 是一个开源的求职者搜索引擎the open-source search engine for job seekers。它把简历、职位和 LLM 分析放在同一条数据链路上因此隐私与安全问题格外关键。本文整理 freehire 的四套安全工程用 gitleaks 双通道拦截泄密、在 CV 到达外部模型前完成 PII 脱敏、Tracer 链接的知情同意设计以及贯穿全站的 Fail-Closed失败即拒绝原则帮助你理解一个真实项目如何把安全默认值落到代码里。一、gitleaks一次提交两道防线泄密的本质是时间问题凭据一旦进入远端仓库历史重写历史也换不回没泄露过。freehire 的做法是在两个时刻各设一道检查。1. 提交前pre-commit 钩子预防lefthook.yml 中的 gitleaks 钩子扫描--staged内容——即即将提交的确切内容。它有几条值得学习的设计无 glob 限制秘密不是某种文件类型真正危险的密钥往往在没人记得列出的文件里缺二进制即失败注释里写得很直白——一个悄悄跳过的扫描器比没有扫描器更糟它让提交看起来被检查过。gitleaks 未安装时钩子直接exit 1而同一文件里的 govulncheck 却允许跳过只告警两者对比就是预防与报告的区别失败即阻止注释称它是这个文件里唯一阻止事情发生而非仅仅报告的钩子。2. 提交后CI 全量历史扫描兜底gitleaks.yml 在 push / PR / 每日定时触发特点是fetch-depth: 0——浅克隆恰好会隐藏某人想藏的那个提交。它还有两个精巧机制机制解决的问题金丝雀测试canary没发现泄漏无法区分扫描器在正常工作和扫描器已被允许列表废掉于是先向临时目录植入一个伪凭据验证规则集仍能报警断言提交数 ≥ 1gitleaks 读不到仓库时会输出 0 commits scanned 并以 0 退出一个浅克隆就能造成什么都没查却全绿的假象另外下载的二进制会先校验 SHA256 再执行校验完整性而不是因为 URL 看起来对就信任它扫描结果用--redact输出避免把发现的凭据原样写进公开的 CI 日志。配套的 .gitleaks.toml 有一条纪律允许列表只放行行的形状从不放行路径——按路径豁免等于对该文件整体关闭扫描而测试文件恰恰是真实 token 最可能被当仿真夹具粘贴进去的地方。二、PII 脱敏CV 先过安检再进 LLMfreehire 会用 LLM 做简历结构化提取和职位匹配分析。为了让姓名、邮箱、电话永远不离开自己的边界去外部模型提供商项目在 services/pii-filter 自建了一个本地检测端点双引擎检测正则打底邮箱/电话/URL/handle高精度且免费∪ 本地openai/privacy-filter模型ONNX 量化、CPU 运行负责正则搞不定的姓名和地址见 KIND_MAP可逆占位符redactor.go 把每个 PII 值替换为编号占位符如[REDACTED_NAME_1]Redact进 prompt、Restore出结果分析结果里仍是真实值词边界优先只对整词型值姓名/地址尝试\b边界匹配防止把普通词误伤成占位符fail-closed 自检Build结束后会重新检查掩码后的文本里是否还残留任何已检测值有残留就拒绝返回宁可失败也不放行半脱敏的文本。模型权重只从官方仓库拉取README 特别注明曾出现过恶意 typosquat 仿冒仓库。完整设计决策见 design.md没有检测器 ⇒ 简历不进 LLM正则单独不构成姓名检测的合格兜底。回滚方案就是去掉PII_FILTER_URL——服务退化为无分析而不是退化为裸奔。三、Tracer 链接知情同意写在规格里freehire 的 CV 可以把出站链接替换为追踪短链让候选人知道谁打开过我的简历。这套功能cv-tracer-links 规格把隐私考虑写进了每一条需求默认关闭只能本人开启tracer_links_enabled默认为 false且被明确排除在 AI 代理的 PATCH 操作面之外——同意追踪第三方是候选人自己的权利代理不能代签不可撤销/误撤销该开关不属于 CV 版本历史撤销一次无关的文档编辑不会连同意一起撤销不留原始 IP访客身份是IP UA 的带盐哈希无法通过枚举地址空间反推密钥未配置时该功能不允许开启而非降级成明文记录防开放重定向跳转目标只能来自服务端存储的 token绝不读取调用方传入的任何 URL 片段数据最小留存机器人流量在点击时一次性打标改规则不重写历史sweep-tracer-clicks 每天删除超过 180 天的点击记录——注释称这是隐私承诺的留存义务而非顺手清洁删除 CV 会连带抹掉全部 token 和点击数据。四、Fail-Closed把拒绝服务当作默认安全态贯穿以上模块的是同一个模式故障时拒绝而不是带病运行。随手可以列举的几处SSRF 防护safehttp.go 的守卫运行在 dialer 的 Control 钩子里在 DNS 解析之后拿到具体 IP 才判定从而封死 DNS-rebinding看起来是公网、解析到 127.0.0.1的主机nilIP 一律视为拦截鉴权中间件middleware.go 中用户 ID 缺失或角色加载失败一律按未授权处理PII 检测器Build返回 error 而非只有正则的半成品脱敏器扫描器本身gitleaks 钩子在二进制缺失时失败而不是假装扫描过。五、其他配套清单 依赖漏洞govulncheck.yml 每日定时 PR 触发SECURITY.md 定义了漏洞报告通道、范围内项认证绕过、SSRF、注入、密钥暴露等与范围外项供应链加固CI 中所有下载的二进制先校验摘要再执行模型侧防线LLM 的富化输出必须通过固定受控词表的Sanitize/Validate校验后才能入库提示注入被定义为预期且被过滤的而非漏洞。结语freehire 的安全观可以浓缩为一句话每一道控制都假设下一道会缺席。gitleaks 钩子假设有人会用--no-verifyCI 假设有人从未装钩子正则假设模型会漏检模型假设定值检测器宕机Tracer 假设运营者会忘删数据所以用 180 天定时清扫兜底。对新手而言这种每个环节都 fail-closed的思维方式比任何单一工具都更值得带走。【免费下载链接】freehirefreehire — the open-source search engine for job seekers项目地址: https://gitcode.com/GitHub_Trending/fr/freehire创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考