Skip to content

Bug: headerParser truncates header values containing colons (e.g., Authorization: Bearer tokens) #1417

@marlonbarreto-git

Description

@marlonbarreto-git

Bug Description

The headerParser function in config.ts uses arg.split(':') which splits on ALL colons in the string. JavaScript destructuring const [name, value] only captures the first two array elements, silently discarding any content after the second colon.

Affected Code

File: packages/playwright/src/mcp/browser/config.ts (line ~514-520)

export function headerParser(arg: string | undefined, previous?: Record<string, string>): Record<string, string> {
  if (!arg)
    return previous || {};
  const result: Record<string, string> = previous || {};
  const [name, value] = arg.split(':').map(v => v.trim());
  result[name] = value;
  return result;
}

Impact

Any header value containing a colon is silently truncated:

Input Expected Actual
Authorization: Bearer eyJ... Bearer eyJ... Bearer eyJ... (OK — no extra colon)
Cookie: session=abc; path=/ session=abc; path=/ session=abc; path=/ (OK — no colon)
X-Custom: http://example.com http://example.com http (TRUNCATED at ://)
Authorization: Basic dXNlcjpwYXNz Basic dXNlcjpwYXNz Basic dXNlcjpwYXNz (OK)
X-Forwarded-Proto: value:with:colons value:with:colons value (TRUNCATED)

This affects:

  • --cdp-header CLI flag
  • PLAYWRIGHT_MCP_CDP_HEADERS environment variable
  • Any header value containing URLs (http://, https://), port numbers (host:port), or Base64 strings with colons

Users get no warning that their header values are being truncated. Authentication headers that happen to contain colons silently fail to authenticate.

Steps to Reproduce

# Using environment variable
export PLAYWRIGHT_MCP_CDP_HEADERS="X-Custom: http://example.com/api"
npx @playwright/mcp@latest --cdp-endpoint "ws://localhost:9222"
# Result: header sent as "X-Custom: http" — everything after "http:" lost

# Using CLI flag
npx @playwright/mcp@latest --cdp-header "X-Auth: token:secret:data"
# Result: header sent as "X-Auth: token" — ":secret:data" lost

Proposed Solution

Split only on the first colon:

export function headerParser(arg: string | undefined, previous?: Record<string, string>): Record<string, string> {
  if (!arg)
    return previous || {};
  const result: Record<string, string> = previous || {};
  const colonIndex = arg.indexOf(':');
  if (colonIndex === -1)
    return result;  // or throw — header without colon is malformed
  const name = arg.substring(0, colonIndex).trim();
  const value = arg.substring(colonIndex + 1).trim();
  result[name] = value;
  return result;
}

This matches the HTTP header spec (RFC 7230 Section 3.2): header field values can contain colons, only the first colon separates name from value.

Happy to submit a PR for this fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions