HarperFast / HarperFast/studio

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

Open
#1,673 0 comments 0 reactions 0 assignees View on GitHub
rum
Dominant language
TypeScript
Stars
5
Forks
4
Avg merge
1d 8h
Merged PRs (30d)
40

Description

## The gap

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

- `URL_TOKEN` — anything matching `scheme://…`
- `SCP_GIT_REMOTE` — `git@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/: npm error
redacts | Failed to clone package git@github.com:: 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:/` 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 `` 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/).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 `/` 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 :`,
`Failed to download package :`, `Failed to install dependencies for 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

- #1664 — Harper's composed error text reaching Error Tracking (secrets); same class,
different message family.
- #1665 — `error.causes[]` bypasses every redaction layer; independent gap in the same
module's coverage.
- `a8576681` — the commit that introduced `redactErrorText` and the private-repo drop rule.

Contributor guide

Open the contributing guide

Research direction

Start with src/integrations/datadog/redactErrorText.ts and trace the callers that compose “Failed to clone package”, “Failed to download package”, and “Failed to install dependencies for” messages. Review the existing URL_TOKEN and SCP_GIT_REMOTE handling, then define coverage for npm aliases and bare owner/repo values without redacting ordinary prose, paths, or stack frames.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.