Skip to content

[RUM] npm shorthand package specs (github:owner/repo, bare owner/repo) bypass redactErrorText — a customer repo reached Error Tracking unredacted #1673

Description

@dawsontoth

The gap

redactErrorText (src/integrations/datadog/redactErrorText.ts) recognises exactly two
shapes of repository reference:

  • URL_TOKEN — anything matching scheme://…
  • SCP_GIT_REMOTEgit@host:owner/repo

npm package specifiers do not have to be either. github:owner/repo,
gitlab:owner/repo, bitbucket:owner/repo and the bare owner/repo GitHub shorthand
are all valid npm install arguments, they are what Harper passes to git clone /
npm install on a component deploy, and none of them contains :// or a user@host:
prefix. They pass through the redactor untouched, carrying the customer's repository
owner and name into Error Tracking, which is the exact retention-and-search surface the
module's header says it exists to keep them off.

Probing the shipped function directly:

LEAKS   | Failed to clone package github:acme-corp/private-billing: fatal: Too many arguments.
LEAKS   | Failed to download package gitlab:acme-corp/private-billing: npm error
LEAKS   | Failed to download package bitbucket:acme-corp/private-billing: npm error
LEAKS   | Failed to download package acme-corp/private-billing: npm error
redacts | Failed to download package https://github.com/<redacted>: npm error
redacts | Failed to clone package git@github.com:<redacted>: fatal

Production evidence

A SSEOperationError on 2026-08-28 reached RUM with a real third-party GitHub
org and repository name intact, in the github:<owner>/<repo> form, in both
error.message and error.stack. The identifiers are omitted here deliberately — this
repo is public — and are in the Datadog event.

This is after the redactor shipped (a8576681, 2026-07-30) and after the #1609
deploy gap closed, and <redacted> is present in the currently-served entry chunk, so
it is not a deploy-lag artifact: the redactor ran on this message and had no rule that
matched. Sibling events in the same window were redacted
(Failed to clone package https://github.com/<redacted>).html: …), which is what makes
the shorthand form the specific hole rather than the redactor being off.

Volume is low — 23 SSEOperationError events across 3 days in the 30 days to
2026-09-02, of which one carried an unredacted shorthand reference. The severity is not
the volume; it is that the leak is silent and the data is retained.

Why it isn't a one-line regex

github:/gitlab:/bitbucket: are tractable — they are a closed set of npm-recognised
aliases with a <segment>/<segment> payload. The bare owner/repo form is not: no
regex can distinguish it from ordinary prose or a file path without context, and a
greedy rule would shred stack frames and Harper's own paths.

The tractable framing is to redact by position, not by shape — Harper composes these
messages from a known set of prefixes (Failed to clone package <spec>:,
Failed to download package <spec>:, Failed to install dependencies for <spec> using…),
so the token immediately following a recognised prefix can be replaced wholesale
regardless of its form. That also closes the bare-shorthand case, which no shape-based
rule reaches.

That is a design call rather than a mechanical fix, which is why this is an issue and
not a PR.

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    rumFrom real user monitoring where we aim to keep users happy

    Type

    Fields

    Priority

    P2

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions