清除敏感数据

了解如何在 SDK 中过滤或清除敏感数据,以防止数据随事件发送。您还可以配置服务器端清除以确保数据不会被存储。

与任何第三方服务一样,了解发送到 Sentry 的数据非常重要,并确保敏感数据要么从未到达 Sentry 服务器,要么至少不会被存储。

以下是一些每个公司都应该考虑的数据清除示例:

  • PII(个人身份信息),如用户的姓名或电子邮件地址,在 GDPR 生效后应成为每家公司的关注点。
  • 身份验证凭据,如您的 AWS 密码或密钥。
  • 机密知识产权(IP),例如您最喜欢的颜色,或您即将进行的世界霸权计划。

我们根据您的法律和运营需求提供以下选项:

  • 在 SDK 内过滤或清除敏感数据,以确保数据 不发送到 Sentry。不同的 SDK 具有不同的功能,配置更改需要重新部署应用程序。
  • 配置服务器端清除以确保 Sentry 不存储 数据。配置更改在 Sentry UI 中进行,并立即应用于新事件。
  • 在自己的服务器上运行本地 Relay,位于 SDK 和 Sentry 之间,以确保数据 不发送到 Sentry,同时可以在不部署的情况下应用配置。

确保您的团队了解公司关于可以和不可以发送到 Sentry 的数据的政策。我们建议在实施早期确定此政策,并通过代码审查进行沟通和强制执行。

如果您在移动应用中使用 Sentry,请阅读我们关于移动数据隐私的常见问题,以帮助处理 Apple App Store 和 Google Play 应用隐私详情。

我们的较新 SDK 默认不会故意发送 PII,以确保安全。此行为由一个名为 send-default-pii 的选项控制。

启用此选项是某些 Sentry 功能正常工作的必要条件,但也意味着您需要更加小心发送到 Sentry 的数据(使用以下选项)。

如果您不希望使用默认的 PII 行为,您还可以选择以更可控的方式识别用户,使用我们的 用户身份上下文

SDK 提供了一个 before_send 钩子,在错误或消息事件发送之前调用,可用于修改事件数据以清除敏感信息。一些 SDK 还提供了一个 before_send_transaction 钩子,用于对事务进行相同的操作。我们建议在 SDK 中使用 before_send 和 before_send_transaction 在数据发送前清除任何敏感信息,以确保敏感数据从未离开本地环境。

In the Symfony config, a service can be used to modify the event or return a completely new one. If you return null, the event will be discarded.

config/packages/sentry.yaml
Copied
sentry:
  options:
    before_send: "sentry.callback.before_send"

services:
  sentry.callback.before_send:
    class: 'App\Service\Sentry'
    factory: ['@App\Service\Sentry', "getBeforeSend"]

The service needed for the before_send option can be implemented as follows:

src/Service/Sentry.php
Copied
<?php

namespace App\Service;

class Sentry
{
    public function getBeforeSend(): callable
    {
        return function (\Sentry\Event $event): ?\Sentry\Event {
            return $event;
        };
    }
}

敏感数据可能出现在以下区域:

  • 栈局部变量 → 某些 SDK(Python、PHP 和 Node)会在堆栈跟踪中捕获变量值。这些可以被清除,或者如果需要,可以完全禁用此行为。
  • 面包屑 → 某些 SDK(例如 JavaScript 和 Java 日志集成)会捕获之前执行的日志语句。如果使用此功能并在事件中包含日志语句作为面包屑,请勿记录 PII。一些后端 SDK 还会记录数据库查询,这些可能需要清除。大多数 SDK 会将 HTTP 查询字符串和片段作为数据属性添加到面包屑中,这些可能需要清除。
  • 用户上下文 → 自动行为由 send_default_pii 控制。
  • HTTP 上下文 → 查询字符串可能会在某些框架中作为 HTTP 请求上下文的一部分被捕获。
  • 事务名称 → 在某些情况下,事务名称可能包含敏感数据。例如,浏览器的页面加载事务可能有一个原始 URL /users/1234/details(其中 1234 是用户 ID,可能被视为 PII)。在大多数情况下,我们的 SDK 可以成功参数化 URL 和路由,即将 /users/1234/details 转换为 /users/:userid/details。但是,根据框架、路由配置、竞争条件和其他因素,SDK 可能无法完全参数化所有 URL。
  • HTTP 跨度 → 大多数 SDK 会将 HTTP 查询字符串和片段作为数据属性包含在内,这意味着 HTTP 跨度可能需要清除。

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

上下文信息

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

Copied
\Sentry\configureScope(function (\Sentry\State\Scope $scope) use ($user): void {
    $scope->setTag('birthday', checksum_or_hash($user->birthday));
});

这将允许您在需要时在内部系统中关联它,但对 Sentry 保持机密。

用户详情

如果您的组织确定电子邮件不是机密信息,但如果它们是机密信息,请考虑发送内部标识符:

Copied
\Sentry\configureScope(function (\Sentry\State\Scope $scope) use ($user): void {
    $scope->setUser(['id' => $user->id]);

    // or

    $scope->setUser(['username' => $user->username]);
});

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

日志集成

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

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