清理敏感数据
了解如何在 SDK 中过滤或清理敏感数据,以防止数据随事件发送到 Sentry。您还可以配置服务器端清理,以确保数据不会被存储。
与任何第三方服务一样,了解发送到 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
钩子,用于处理事务事件。我们建议在 SDK 中使用 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)会在堆栈跟踪中捕获变量值。这些值可以被清理,或者如果必要,可以禁用此行为。
- 面包屑(Breadcrumbs) → 某些 SDK(如 JavaScript 和 Java 日志集成)会捕获之前执行的日志语句。如果使用此功能并包含日志语句作为事件中的面包屑,请勿记录 PII。某些后端 SDK 还会记录数据库查询,这些查询可能需要清理。大多数 SDK 会将 HTTP 查询字符串和片段作为数据属性添加到面包屑中,这些内容可能需要清理。
- 用户上下文(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 跨度(HTTP Spans) → 大多数 SDK 会将 HTTP 查询字符串和片段作为数据属性包含在内,这意味着 HTTP 跨度可能需要清理。
更多详细信息和数据过滤说明,请参阅 事件过滤。
与其发送明文的机密信息,考虑对其进行哈希处理:
Sentry.setTag("birthday", checksumOrHash("08/12/1990"));
这将允许您在需要时在内部系统中关联这些信息,但保持其对 Sentry 的保密性。
如果您的组织认为电子邮件不是机密信息,但如果它们是机密信息,则可以考虑发送内部标识符:
Sentry.setUser({ id: user.id });
// or
Sentry.setUser({ username: user.username });
这样做可以确保您仍然能够从用户影响相关的功能中受益。
作为最佳实践,您应始终避免记录机密信息。如果您有需要绕过的遗留系统,请考虑以下方法:
- 在日志语句中匿名化机密信息(例如,将电子邮件地址替换为内部标识符)
- 使用
beforeBreadcrumb
在将其附加到面包屑之前进行过滤 - 禁用日志面包屑集成(例如,如 此处 所述)