尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Highlight 会话录制隐私体系解析:highlight-block / highlight-mask / highlight-ignore 与 privacySetting 的完整实践

发布时间:2026/9/25 13:20:28

资讯中心
01
ARTICLE

Highlight 会话录制隐私体系解析:highlight-block / highlight-mask / highlight-ignore 与 privacySetting 的完整实践

Highlight 会话录制隐私体系解析:highlight-block / highlight-mask / highlight-ignore 与 privacySetting 的完整实践
可观测性后端【免费下载链接】highlighthighlight.io: The open source, full-stack monitoring platform. Error monitoring, session replay, logging, distributed tracing, and more.项目地址https://gitcode.com/gh_mirrors/hi/highlight点击查看免费下载本文围绕 Highlight 的浏览器端会话录制隐私控制展开如何用最少的 CSS 类名实现元素屏蔽highlight-block、文本混淆highlight-mask与输入忽略highlight-ignore以及如何通过H.init()的privacySetting选项切换 strict / default / none 三级隐私策略。读完本文你可以对照 Highlight SDK 与 rrweb 的源码实现理解每一处脱敏发生在客户端序列化的哪个环节并据此为自己的产品配置一套可复现、可验证的隐私保护方案。隐私控制的两种入口CSS 类名与 privacySettingHighlight 录制会话时所有脱敏都发生在客户端序列化阶段——敏感数据在离开浏览器之前就已经被移除或替换服务端Highlight 后端从未接收过原始数据。官方文档privacy.md给出的控制手段可以归纳为两条路径元素级标注在 HTML 上添加highlight-block、highlight-mask、highlight-ignore三个 CSS 类分别控制屏蔽内容、混淆文本和忽略输入全局策略在调用H.init()时传入privacySetting取值为strict | default | none设定整页的脱敏强度。从源码结构看SDK 在启动录制时把这两类配置合并传入底层录制器rrwebsdk/highlight-run/src/client/index.tsx 中record()调用显式传入ignoreClass: highlight-ignore、blockClass: highlight-block以及privacySetting、maskAllInputs、maskInputOptions而highlight-mask则是 rrweb 侧的默认值见 __generated/rr/rrweb/rr.js 中record()的默认参数maskTextClass highlight-mask。privacySetting的可选值定义在 sdk/highlight-run/src/client/types/types.tsexport type PrivacySettingOption strict | default | none其官方文档语义docs-content/sdk/client.md为strict屏蔽页面上所有文本和图片是无需手动标注即可保证不录制任何个人信息的做法default只屏蔽匹配常见 PII 正则表达式以及常见输入名的文本和输入数据不屏蔽图片和媒体内容none按页面显示原样记录所有文本和内容。privacySetting的默认值在 SDK 中是defaultsdk/highlight-run/src/client/index.tsx 中this.privacySetting options.privacySetting ?? default。Masking Elements用 highlight-block 屏蔽元素内容最直接的内容清洗方式是给需要忽略的元素加上highlight-blockCSS 类div classhighlight-blockSuper secret sauce/divHighlight 片段会测量被忽略元素的尺寸回放时用占位符替换其内容——即用户能看到该区域有东西布局、尺寸不变但内容不可见。对应实现分两层判定层rrweb 序列化时用_isBlockedElement检查节点是否携带 blockClass匹配规则是element.classList.contains(blockClass)见 __generated/rr/rrweb/rr.js默认绑定record()与snapshot()的默认参数均为blockClass highlight-blockrr.js#L14220、rr.js#L1513因此不需要任何额外配置只要 HTML 里加了这个类名即可生效。注意highlight-block作用于元素及其整个子树适合整块区域如账单明细面板、内部工单卡片级别的屏蔽。Obfuscating Elements用 highlight-mask 混淆文本如果不想完全隐藏区域、只希望把文本打码成乱码可以给元素加highlight-mask类div classhighlight-maskThis is some sensitive data buttonImportant Button/button/div其效果等同于privacySetting: strict的文本混淆即前文图片中看到的随机字符串但只作用于被标记的具体元素。源码中snapshot()的默认参数maskTextClass highlight-maskrr.js#L1515判定函数needMaskingText对元素节点检查classList.contains(maskTextClass)对文本节点则检查其父元素rr.js#L775-L805命中后文本会被maskTextFn替换record()的默认maskTextFn obfuscateTextrr.js#L14231最终在序列化节点时执行textContent2 maskTextFn ? maskTextFn(...) : textContent2.replace(/[\S]/g, *)rr.js#L971-L973。obfuscateText的实现rr.js#L576-L580值得注意它先剔除非 ASCII 字符再按空格拆词对每个词用随机数生成等长的随机字符串因此回放时文本长度和排版基本保持原样观感更接近真实但不可读的内容而不是简单的星号function obfuscateText(text) { text text.replace(/[^ -~]/g, ); text (text?.split( ).map((word) Math.random().toString(20).substring(2, word.length)).join( )) || ; return text; }Ignoring Input用 highlight-ignore 忽略输入内容注意highlight-ignore只适用于input元素。如果想屏蔽其他 HTML 元素的采集请使用highlight-block。对敏感输入框如身份证号、卡号团队往往希望保留输入框本身的外观与交互轨迹光标移动、焦点变化但不记录用户敲入的值。给input加上highlight-ignore即可input classhighlight-ignore namesocial security number /源码中该机制对应 rrweb 的输入监听逻辑record()默认ignoreClass highlight-ignorerr.js#L14222输入事件处理器在捕获到目标元素后先做短路判断——target.classList.contains(ignoreClass)命中则直接return连value都不会读取rr.js#L12164-L12166。SDK 侧同样显式传入该配置record({ ignoreClass: highlight-ignore, blockClass: highlight-block, ... })index.tsx#L764-L766。这与highlight-mask处理输入的区别在于highlight-ignore是输入事件不采集而 mask/privacy 策略是对已序列化值的替换。Network Request Redaction网络层脱敏DOM 之外的另一个数据出口是网络请求。Highlight 开箱即会屏蔽若干已知携带密钥的请求头并提供多级自定义能力。完整配置见 Recording Network Requests and Responses核心要点如下开启请求头/响应体录制networkRecording.recordHeadersAndBody: true默认脱敏的请求头Authorization、Cookie、Proxy-Authorization追加脱敏请求头networkRecording.networkHeadersToRedactURL 黑名单urlBlocklist命中后不记录 header 与 bodyHighlight 默认不记录https://www.googleapis.com/identitytoolkit与https://securetoken.googleapis.com白名单与键级脱敏networkRecording.headerKeysToRecord/bodyKeysToRecord白名单、networkRecording.networkBodyKeysToRedact键级脱敏需highlight.run高于4.1.0自定义 sanitizernetworkRecording.requestResponseSanitizer接收 Request/Response pair返回同类型对象即完成改写返回null则整条请求被丢弃官方不建议滥用丢弃以免调试时缺少请求上下文需highlight.run高于8.1.0。示例来自上述文档H.init(YOUR_PROJECT_ID, { networkRecording: { enabled: true, recordHeadersAndBody: true, requestResponseSanitizer: (pair) { if (pair.request.url.toLowerCase().indexOf(ignore) ! -1) { // 丢弃整条请求/响应不会产生网络日志 return null } // 其余请求正常返回 pair return pair }, }, })Default Privacy Mode默认隐私模式与 PII 正则默认情况下即privacySetting: defaultHighlight 会混淆所有输入以及匹配常见个人信息PII正则的文本。这为地址、电话号码、社保号等数据提供了基线保护图片和媒体内容不受影响。代价是可能误伤与长数字、联系方式模式吻合的非 PII 文本也可能被混淆。如需关闭调用H.init()时将privacySetting设为none。注意default模式仅在 SDK 8.0.0 及以后版本中可用早期版本仅 strict / none 二选一。使用的正则表达式清单官方文档列出了默认隐私模式使用的正则源自 rrweb-snapshot 的utils.tsEmail: [a-zA-Z0-9.!#$%*?^_{|}~-][a-zA-Z0-9-](?:.[a-zA-Z0-9-])* SSN: [0-9]{3}-?[0-9]{2}-?[0-9]{4} Phone number: []?[(]?[0-9]{3}[)]?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4,6} Credit card: [0-9]{4}-?[0-9]{4}-?[0-9]{4}-?[0-9]{4} Unformatted SSN, phone number, credit card: [0-9]{9,16} Address: [0-9]{1,5}.?[0-9]{0,3}\s[a-zA-Z]{2,30}\s[a-zA-Z]{2,15} IP address: (?:[0-9]{1,3}.){3}[0-9]{1,3}当前仓库内置的 rrweb 构建中同样可以找到这份正则清单定义在 __generated/rr/rrweb/rr.js#L584-L605EMAIL_REGEX、LONG_NUMBER_REGEX对应[0-9]{9,16}、SSN_REGEX、PHONE_NUMBER_REGEX、CREDIT_CARD_REGEX、ADDRESS_REGEX、IP_REGEX由DEFAULT_OBFUSCATE_REGEXES数组聚合命中判定函数为function shouldObfuscateTextByDefault(text) { if (!text) return false; return DEFAULT_OBFUSCATE_REGEXES.some((regex) regex.test(text)); }见 rr.js#L606-L609。输入框的脱敏规则从何而来静态文本靠正则动态输入靠整类屏蔽。SDK 通过 sdk/highlight-run/src/client/utils/privacy.ts 中的determineMaskInputOptions把隐私策略翻译成 rrweb 的maskAllInputs/maskInputOptionsexport const determineMaskInputOptions ( privacyPolicy: PrivacySettingOption, ): [maskAllOptions: boolean, maskOptions?: MaskInputOptions] { switch (privacyPolicy) { case strict: return [true, undefined] // 屏蔽所有输入 case default: return [true, undefined] // 同样屏蔽所有输入 case none: { return [false, { password: true }] // 仅屏蔽 password 类型 } }rrweb 侧的兜底逻辑rr.js#L14278-L14295maskAllInputs true时构造包含text、email、tel、number、textarea、select、password等全部类型的屏蔽表否则取调用方传入的maskInputOptions再否则默认{ password: true }。这也解释了为什么none模式下密码框依然会被打码——密码内容属于绝对红线。被判定应屏蔽的输入其value会被替换为与原文等长的*串maskInputValue中text *.repeat(text.length)rr.js#L342-L361保持回放时的宽度稳定。官方博客 Revamping Privacy Mode 还提到默认模式会额外搜索带有常见name/id/autocomplete值的输入框并从输入第一刻就对其进行混淆以解决用户正在输入社保号、但正则要凑够位数才命中的窗口期问题。同时该文也点明了默认模式的两类已知局限一是会过度混淆如用户创建的UserId长数字命中手机号正则因为算法不区分上下文二是跨元素拆分的文本可能漏检如divspencerbhighlight/b.io/div被b切断后整体不再命中邮箱正则。覆盖混淆data-hl-recordtrue默认模式下一些无害但被误混淆的文本例如用户自设的名称、公司地址输入框可以用data-hl-recordtrue属性放行。注意两点约束该属性必须写在被录制的 HTML 标签本身上且其子元素仍可能各自被脱敏。源码印证文本节点混淆前先读取父元素的属性rr.js#L974-L990const enableStrictPrivacy privacySetting strict; const highlightOverwriteRecord n2.parentElement?.getAttribute(data-hl-record); const obfuscateDefaultPrivacy privacySetting default shouldObfuscateTextByDefault(textContent2); if ((enableStrictPrivacy || obfuscateDefaultPrivacy) !highlightOverwriteRecord parentTagName) { // 忽略 HEAD/TITLE/STYLE/SCRIPT 等标签后执行 obfuscateText }输入事件路径同样如此initInputObserver中overwriteRecord target.getAttribute(data-hl-record)而maskedInputType在overwriteRecord true时直接返回falserr.js#L12167-L12188、rr.js#L610-L618即输入值不再打码。因此该属性对 strict 与 default 两种模式都有效且作用于元素自身而非其子孙——这与highlight-mask的整树混淆形成互补。Strict Privacy Mode最严格的全页混淆如果不想逐元素标注可调用H.init()时设置privacySetting: strictH.init(YOUR_PROJECT_ID, { privacySetting: strict })Strict 模式会混淆所有文本和图片。文档给出的效果示例h1Hello World/h1会被记录为h11f0eqo jw02d/h1img srchttps://my-secrets.com/secret.png /会被记录为img src /。两点性质需要强调混淆不可逆随机文本由客户端生成原文从未上传混淆发生在客户端序列化阶段即替换见上节obfuscateText与maskTextFn的调用链。从源码结构看strict 的判定集中在两条链路初始快照中enableStrictPrivacy privacySetting strict时对全部文本执行obfuscateTextrr.js#L974-L990后续 DOM 文本变更则在 MutationObserver 的文本变更分支中做同样的判定与替换rr.js#L11524-L11528保证回放时后续出现的动态内容同样被混淆。此外SDK 在初始化会话时会把策略上报给后端供回放侧渲染使用initializeSession请求携带enable_strict_privacy: this.privacySetting strict与privacy_setting: this.privacySettingindex.tsx#L633-L634。三级策略对照与配置建议维度strictdefault默认none页面文本全部混淆随机化仅命中 PII 正则的文本混淆原样记录图片/媒体全部屏蔽src置空不屏蔽原样记录所有输入框全部打码等长*全部打码等长*仅password类型打码是否需要手动标注不需要可选data-hl-record可放行误伤不需要可用版本所有版本SDK 8.0.0所有版本配置时的决策路径建议合规要求高、不想逐元素标注→strict配合data-hl-recordtrue放行确需查看的少量元素常规生产环境→ 保持default对误混淆的元素用data-hl-recordtrue精确放行对整块敏感区域叠加highlight-block对保留外观但不录值的输入框用highlight-ignore对保留元素但打码文本的区域用highlight-mask调试/内网环境→none此时仍需记住password输入与网络层默认脱敏Authorization/Cookie等依然生效。小结Highlight 的会话录制隐私控制是一套分层设计CSS 类名highlight-block/highlight-mask/highlight-ignore提供元素级、免配置的精确控制privacySettingstrict / default / none提供整页级策略data-hl-recordtrue提供白名单式放行网络层另有请求头/URL/键级脱敏与自定义 sanitizer。所有脱敏均在客户端序列化阶段完成rrweb 的 snapshot 与 MutationObserver 两条链路敏感原文不会离开浏览器。相关实现可追溯至 sdk/highlight-run/src/client/index.tsx、sdk/highlight-run/src/client/utils/privacy.ts 与内置录制器 __generated/rr/rrweb/rr.js官方说明见 Privacy 文档 与 H.init 参考。赞分享可观测性后端【免费下载链接】highlighthighlight.io: The open source, full-stack monitoring platform. Error monitoring, session replay, logging, distributed tracing, and more.项目地址https://gitcode.com/gh_mirrors/hi/highlight点击查看免费下载相关推荐用 Highlight 接入 Next.jshighlight-run/next 的会话回放、错误监控与分布式追踪完整实践用 Highlight 接入 Next.jshighlight run/next 的会话回放、错误监控与分布式追踪完整实践 本文基于 Highlight 仓可观测性后端Highlight iframe 会话录制同源与跨域 iframe 的捕获原理与配置实践Highlight iframe 会话录制同源与跨域 iframe 的捕获原理与配置实践 本文基于 Highlight 官方文档 iframe Recordi可观测性后端Highlight 会话回放中的 Console 消息录制disableConsoleRecording 与 consoleMethodsToRecord 配置详解Highlight 会话回放中的 Console 消息录制disableConsoleRecording 与 consoleMethodsToRecord 配可观测性后端上一篇CocoIndex Postgres 数据源实战把现有 Postgres 表变成可语义检索的 pgvector 向量索引下一篇Open edX Discussions 应用深度解析多供应商论坛配置与课程话题同步机制创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。