Skip to content

fix(mcp): mask URL passwords and Authorization credentials - #297

Merged
erkamyaman merged 1 commit into
mainfrom
mcp/redact-url-credentials
Oct 11, 2026
Merged

erkamyaman merged 1 commit into
mainfrom
mcp/redact-url-credentials

Conversation

@erkamyaman

@erkamyaman erkamyaman commented Oct 11, 2026 •

Copy link
Copy Markdown
Member

What and why

URLs with a password (https://user:pass@host) and Authorization values other than Bearer (Basic, Digest, Token, and any known scheme after an Authorization: header name) reached the panel and agents in clear text. A new credential-redact.ts masks them, and every shared redaction helper calls it (forms-privacy redactMessage, router redactText, the Analog server log). So serialize, HTTP calls, router URLs, NgRx, forms and Analog get the same masking. The URL user stays visible. Basic only matches base64 of user:password, Token needs an opaque value with letters and digits, and Digest needs its parameter list, so "Basic plan" or "Token expired" stay readable.

Secret key names also cover bearer (whole name), authHeader, authKey, authCode and basicAuth. auth alone stays visible so auth state slices are readable, and author/authorName are not masked.

How it was verified

  • New credential-redaction.test.ts (9 tests; 5 fail with the masking switched off)
  • pnpm test:devtools (1517 passed)
  • pnpm test:panel (242 passed)
  • pnpm typecheck
  • pnpm format:check
  • pnpm docs:build
  • pnpm commit:check

Screenshots

None attached.

Notes for reviewers

  • bearer is matched as a whole key only. Making it a secret word would also mask values under keys that are bearer tokens themselves, which redaction-leaks.test.ts keeps visible.
  • Not covered: a token used as the URL user with no password (https://ghp_x@github.com), and a password inside a percent-encoded return URL.
  • The security docs page has a new "Credentials inside values" section.

Generated by Claude Code

Summary by CodeRabbit

  • Privacy
    • Sensitive values are now masked in messages and logs, including URL passwords, Basic and Digest credentials, Token values, bearer tokens, and JWTs. URL usernames, authorization schemes, and ordinary phrases remain visible.
    • Additional credential-related names, including authHeader, authKey, authCode, and basicAuth, are now recognized for masking. A key named only auth is not treated as secret.
    • Security and redaction documentation now describes these masking rules.

URLs with userinfo (https://user:pass@host) and Authorization values
other than Bearer (Basic, Digest, Token, and any known scheme after an
Authorization or Proxy-Authorization header name) reached the panel and
agents in clear text. A new credential-redact module masks them, and the
shared helpers (forms-privacy redactMessage, router redactText and the
Analog server log) call it, so serialize, HTTP calls, router URLs, NgRx,
forms and Analog all get the same masking. The URL user stays visible.

Basic only matches base64 that decodes to user:password, Token needs an
opaque value with letters and digits, and Digest needs its parameter
list, so words like "Basic plan" or "Token expired" stay readable.

Secret key names also cover bearer (as a whole name), authHeader,
authKey, authCode and basicAuth. "auth" alone is left out so an auth
state slice stays readable, and author or authorName are not masked.
@github-actions github-actions Bot added area: package The ng-devtools package (packages/ng-devtools) area: docs The documentation site labels Oct 11, 2026
@coderabbitai

coderabbitai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f867e1a9-30e2-462e-9261-963df8a6be30

📥 Commits

Reviewing files that changed from the base of the PR and between 58273c6 and 859fc97.


📒 Files selected for processing (7)
  • apps/docs/src/content/security.md
  • docs/CONTEXT.md
  • packages/devtools/src/__tests__/credential-redaction.test.ts
  • packages/devtools/src/analog-server-log.ts
  • packages/devtools/src/credential-redact.ts
  • packages/devtools/src/forms-privacy.ts
  • packages/devtools/src/router.ts

Limit details: You’ve used all 10 included reviews currently available.



📝 Walkthrough

Walkthrough

The change adds a credential-redaction helper for URL passwords and selected authorization credentials. Router text, form messages, and server logs apply it before their existing redaction steps. The secret-name list, tests, and documentation are also updated.

Changes

Credential redaction

Layer / File(s) Summary
Match and mask credential values
packages/devtools/src/credential-redact.ts
A new helper matches URL passwords and selected authorization credentials. It checks Basic credentials for a decoded colon and Token values for both a digit and a letter before masking.
Apply credential redaction
packages/devtools/src/forms-privacy.ts, packages/devtools/src/router.ts, packages/devtools/src/analog-server-log.ts
Form-message, router-text, and server-log redaction call the helper before existing redaction steps. The secret-name set adds authheader, authkey, authcode, basicauth, and bearer.
Test and document credential redaction
packages/devtools/src/__tests__/credential-redaction.test.ts, apps/docs/src/content/security.md, docs/CONTEXT.md
Tests cover URL passwords, authorization credentials, and secret key names across redaction helpers. Documentation describes the added credential coverage and secret names.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix


Merge Risk | ⚪ Minimal · up to 859fc

Merge Risk: ⚪ Minimal · up to 859fc

This change masks URL passwords and Authorization credentials in router text, form messages and server logs. It only adds redaction and leaves the existing rules in place. No merge-blocking risk is identified.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to 859fc

Credential masking adds protection, but its ordering can leave portions of explicitly sensitive values visible in diagnostic messages. The change does not introduce a new privileged interface.

Retained concerns

  • Medium · security · inferred: Partial credential masking can defeat authoritative whole-secret masking. If a collected sensitive value is https://private-id:pw@host, the new first pass produces https://private-id:[redacted]`@host`. The subsequent exact replacement no longer matches the collected value, leaving previously hidden portions visible in form messages. Router supplied-secret replacement has the same ordering.
Security review details

Security Blast Radius

  • inferred — The demonstrated regression affects diagnostic text containing credential-shaped values already classified as sensitive. Exposure requires access to those diagnostic outputs; the inspected changes do not add authentication authority, package-public entrypoints, or a new cross-tenant route.

Security Findings and Attack Paths

  • inferred — A sensitive form value containing URL credentials can be echoed into an error-summary message or other form text. Password-only transformation changes the string before SecretSet matches it, allowing sensitive URL portions to reach diagnostic consumers. The base masked the complete collected value in this case. This does not establish disclosure of the masked password itself.

Trust Boundaries and Controls

  • observed — Sensitive field values are still directly replaced with the redaction marker. Explicit unmask controls operate during classification, whereas message redaction receives collected secrets separately. Direct field masking therefore does not protect every message that echoes a field value.

Resilience and Maintainability Implications

  • inferred — Repeated redaction does not recover the lost whole-secret match: the original collected value remains unchanged, while the diagnostic text already contains a password mask. Per-form set cleanup limits retention but does not remove portions already emitted.

Hardening Proposals

  • proposed — Preserve authoritative whole-secret replacement before partial credential transformations. Verify this invariant with credential-containing collected values across form summaries, later form text, supplied router secrets, and repeated sanitization.

Pre-merge checks | Passed 4 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 5 files. (2 skipped: 2… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: masking URL passwords and Authorization credentials.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

Full details: Docstring Coverage

Explanation

Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 5 files. (2 skipped: 2 unsupported.)


  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR


🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Usage-based review receipt

  • Mode: Continue automatically
  • Reviewed files: 7
  • Waived: $1.75 (charged $0.00)
  • View usage details

Note

This review exceeded your plan’s limits and used usage-based reviews—free during trial, billed after paid activation unless disabled. Manage usage-based reviews.


Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

🚀 Deploying Preview to Cloudflare 🚀

Preview Deployments by commit

Status Deployment URL Commit Updated (UTC) See this deployment's details
  • Build: Failed ❌

View logs ↗
859fc97 2026-10-11T03:57:59.869Z View logs ↗

Copy link
Copy Markdown
Member Author

The "Workers Builds: angular-devtools" check fails on every PR in this repo, including ones that only touch docs, so it is a Cloudflare project setup issue and not caused by this change. The repository's own CI jobs (check, build, axe) are the ones that gate this PR.


Generated by Claude Code

@erkamyaman
erkamyaman merged commit 7196766 into main Oct 11, 2026
7 of 8 checks passed
@erkamyaman
erkamyaman deleted the mcp/redact-url-credentials branch October 11, 2026 04:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: docs The documentation site area: package The ng-devtools package (packages/ng-devtools)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant