清理敏感数据

了解如何在 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,该事件将被丢弃。

Copied
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 跨度可能需要清理。

更多详细信息和数据过滤说明,请参阅 事件过滤

与其发送明文的机密信息,考虑对其进行哈希处理:

Copied
Sentry.setTag("birthday", checksumOrHash("08/12/1990"));

这将允许您在需要时在内部系统中关联这些信息,但保持其对 Sentry 的保密性。

如果您的组织认为电子邮件不是机密信息,但如果它们是机密信息,则可以考虑发送内部标识符:

Copied
Sentry.setUser({ id: user.id });

// or

Sentry.setUser({ username: user.username });

这样做可以确保您仍然能够从用户影响相关的功能中受益。

作为最佳实践,您应始终避免记录机密信息。如果您有需要绕过的遗留系统,请考虑以下方法:

  • 在日志语句中匿名化机密信息(例如,将电子邮件地址替换为内部标识符)
  • 使用 beforeBreadcrumb 在将其附加到面包屑之前进行过滤
  • 禁用日志面包屑集成(例如,如 此处 所述)