Skip to content

fix: stop writing the Klaviyo bearer token to function logs [] - #11295

Merged
Michael Pineiro (michaelpineirocontentful) merged 9 commits into
fix/klaviyo-oauth-message-handler-origin-checkfrom
fix/klaviyo-scrub-token-from-logs
Sep 14, 2026
Merged

Michael Pineiro (michaelpineirocontentful) merged 9 commits into
fix/klaviyo-oauth-message-handler-origin-checkfrom
fix/klaviyo-scrub-token-from-logs

Conversation

@michaelpineirocontentful

Copy link
Copy Markdown
Contributor

Summary

The Klaviyo request helper logged the full outgoing request headers — including the Authorization bearer token it had just set — whenever the Klaviyo API returned a non-OK response. It also logged the raw token object on the invalid-token-format error path.

Solution

  • Strip the Authorization header before logging request headers on API errors.
  • Log only the token's type (not its value) on the invalid-token-format path.

Context

Last in a small stack of hardening fixes to the Klaviyo app found during a routine security review.

Test plan

  • tsc --noEmit passes
  • Functions build (build-functions) succeeds

The OAuth callback popup broadcast its completion message with a
wildcard target origin, so any window that ended up as window.opener
could receive the authorization code and state.

Scope the postMessage call to the app's own origin instead of '*'.
…w messages

The window message listener that completes the OAuth flow accepted
any message posted to the window, regardless of where it came from
or which window sent it.

Reject messages that don't come from the app's own origin, or that
don't come from the popup window this instance actually opened.
The proxy's endpoint allowlist only checked the segment before the
first slash, so a value like "template-universal-content/../lists"
passed the check while the traversal segment let the request reach a
Klaviyo endpoint that was never allowlisted.

Replace the prefix check with a pattern anchored to the exact shape
the app actually sends (an allowed endpoint, optionally followed by a
single id segment), rejecting anything else outright.
Covers exact allowlist matches, an allowlisted endpoint plus a single
id segment, and traversal attempts that previously bypassed the
prefix-only check (verified these fail against the pre-fix code and
pass against the anchored-pattern fix).

Widen the vitest include glob to pick up functions/ tests — the
functions/ directory previously had no test coverage at all.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@michaelpineirocontentful Michael Pineiro (michaelpineirocontentful) changed the title fix: stop writing the Klaviyo bearer token to function logs fix: stop writing the Klaviyo bearer token to function logs [] Sep 11, 2026
@michaelpineirocontentful
Michael Pineiro (michaelpineirocontentful) marked this pull request as ready for review September 11, 2026 15:09

@david-shibley-contentful david-shibley-contentful left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh gosh, this one 🤦

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The allowlist check moved to ALLOWED_ENDPOINT_PATTERN; ALLOWED_ENDPOINTS
only survived as an internal building block for that regex. Inline it
directly into the pattern literal instead of keeping a separate binding
nothing else reads.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The Klaviyo request helper logged the full outgoing request headers
(including the Authorization bearer token it had just set) whenever
the API returned a non-OK response, and logged the raw token object
on the invalid-token-format branch as well.

Strip the Authorization header before logging request headers, and
log only the token's type instead of the token value on the
invalid-format error path.
Covers the two paths that previously leaked a secret to console.error:
a non-OK API response (which logged the full request headers including
Authorization) and an unrecognized token shape from the OAuth SDK
(which logged the raw token object). Verified both fail against the
pre-fix code and pass against the fix, and added a third test
confirming the fix still logs enough to debug an API error (status,
body, URL) without the secret.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@michaelpineirocontentful
Michael Pineiro (michaelpineirocontentful) removed this pull request from stack #11296 September 14, 2026 14:09
Base automatically changed from fix/klaviyo-proxy-endpoint-allowlist to fix/klaviyo-oauth-message-handler-origin-check September 14, 2026 14:10
@michaelpineirocontentful
Michael Pineiro (michaelpineirocontentful) merged commit c02abc2 into fix/klaviyo-oauth-message-handler-origin-check Sep 14, 2026
16 checks passed
@michaelpineirocontentful
Michael Pineiro (michaelpineirocontentful) deleted the fix/klaviyo-scrub-token-from-logs branch September 14, 2026 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants