清理敏感数据
了解如何在 SDK 中过滤或清理敏感数据,以防止数据随事件发送。你还可以配置服务器端清理,确保数据不会被存储。
与任何第三方服务一样,了解发送到 Sentry 的数据非常重要,并确保敏感数据要么从未到达 Sentry 服务器,或者至少不会被存储。
以下是一些每个公司都应该考虑的数据清理示例:
- PII(个人可识别信息),例如用户的姓名或电子邮件地址,在 GDPR 生效后应成为每个公司的关注重点。
- 身份验证凭据,如你的 AWS 密码或密钥。
- 机密的知识产权(IP),例如你最喜欢的颜色,或者你即将进行的世界霸权计划。
根据你的法律和运营需求,我们提供以下选项:
- 在 SDK 内部过滤或清理敏感数据,以确保数据 不发送到 Sentry。不同的 SDK 具有不同的功能,配置更改需要重新部署应用程序。
- 配置服务器端清理,以确保 Sentry 不存储 数据。配置更改在 Sentry UI 中进行,并立即应用于新事件。
- 在自己的服务器上运行本地 Relay,位于 SDK 和 Sentry 之间,以确保数据 不发送到 Sentry,同时可以在不部署的情况下应用配置。
确保你的团队了解公司关于可以和不可以发送到 Sentry 的数据政策。我们建议在实施早期确定此政策,并通过代码审查进行沟通和执行。
如果你在移动应用中使用 Sentry,请阅读我们关于 移动数据隐私的常见问题,以帮助处理 Apple App Store 和 Google Play 应用隐私详情。
如果你 不 想使用默认的 PII 行为,你还可以选择以更可控的方式识别用户,使用我们的 用户身份上下文。
SDK 提供了一个 beforeSend
钩子,在错误或消息事件发送之前调用,可用于修改事件数据以移除敏感信息。某些 SDK 还提供了一个 beforeSendTransaction
钩子,用于在事务发送之前执行相同的操作。我们建议使用 beforeSend
和 beforeSendTransaction
来 在数据发送前清理任何敏感数据,以确保敏感数据从未离开本地环境。
在 JavaScript 中,您可以使用一个函数来修改事件或返回一个全新的事件。 您可以返回 null
或事件有效负载——不允许返回其他任何值(包括 void
)。 如果您返回 null
,该事件将被丢弃。
Sentry.init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
// Called for message and error events
beforeSend(event) {
// Modify or drop the event here
if (event.user) {
// Don't send user's email address
delete event.user.email;
}
return event;
},
});
敏感数据可能出现在以下区域:
- 堆栈局部变量(Stack-locals) → 某些 SDK(如 Python、PHP 和 Node)会在堆栈跟踪中捕获变量值。这些值可以被清理,或者如果必要的话,可以完全禁用此行为。
- Breadcrumb → 某些 SDK(如 JavaScript 和 Java 日志集成)会捕获之前执行的日志语句。如果使用此功能并在事件中包含日志语句作为 breadcrumb,请勿记录 PII。一些后端 SDK 还会记录数据库查询,这些查询可能需要清理。大多数 SDK 会将 HTTP 查询字符串和片段作为数据属性添加到 breadcrumb 中,这些内容可能需要清理。
- 用户上下文(User context) → 自动行为由
sendDefaultPii
控制。 - HTTP 上下文(HTTP context) → 查询字符串可能会在某些框架中作为 HTTP 请求上下文的一部分被捕获。
- 事务名称(Transaction Names) → 在某些情况下,事务名称可能包含敏感数据。例如,浏览器的页面加载事务可能有一个原始 URL
/users/1234/details
(其中1234
是用户 ID,可能被视为 PII)。在大多数情况下,我们的 SDK 可以成功参数化 URL 和路由,即把/users/1234/details
转换为/users/:userid/details
。然而,根据框架、路由配置、竞争条件和其他因素,SDK 可能无法完全参数化所有 URL。 - HTTP Span → 大多数 SDK 会将 HTTP 查询字符串和片段作为数据属性包含在内,这意味着 HTTP span 可能需要清理。
有关更多详细信息和数据过滤说明,请参阅 过滤事件。
上下文信息
与其发送明文的机密信息,考虑对其进行哈希处理:
Sentry.setTag("birthday", checksumOrHash("08/12/1990"));
这将允许你在内部系统中根据需要关联这些信息,但保持其对 Sentry 的保密性。
用户详情
如果你的组织认为电子邮件不是机密信息,但如果它们是机密信息,则可以考虑发送内部标识符:
Sentry.setUser({ id: user.id });
// or
Sentry.setUser({ username: user.username });
这样做可以确保你仍然能够从与用户影响相关的功能中受益。
日志集成
作为最佳实践,你应该始终避免记录机密信息。如果你有需要解决的历史系统问题,请考虑以下方法:
- 在日志语句中匿名化机密信息(例如,将电子邮件地址替换为内部标识符)
- 使用
beforeBreadcrumb
在将其附加到 breadcrumb 之前过滤掉这些信息 - 禁用日志 breadcrumb 集成(例如,如 这里 所述)
通过这些措施,你可以更好地保护敏感数据,同时仍能利用 Sentry 提供的功能。