Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions packages/instrumentation/src/navigation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

export { NavigationInstrumentation } from './instrumentation.ts';
export type {
NavigationInstrumentationConfig,
NavigationType,
} from './types.ts';
export { defaultSanitizeUrl } from './utils.ts';
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import {
it,
vi,
} from 'vitest';
import { defaultSanitizeUrl } from '#utils';
import { setupTestLogExporter } from '#utils/test';

import { NavigationInstrumentation } from './instrumentation.ts';
import {
ATTR_BROWSER_NAVIGATION_HASH_CHANGE,
Expand All @@ -22,7 +24,6 @@ import {
ATTR_URL_FULL,
BROWSER_NAVIGATION_EVENT_NAME,
} from './semconv.ts';
import { defaultSanitizeUrl } from './utils.ts';

describe('NavigationInstrumentation', () => {
let inMemoryExporter: InMemoryLogRecordExporter;
Expand Down
3 changes: 2 additions & 1 deletion packages/instrumentation/src/navigation/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
*/

import { describe, expect, it } from 'vitest';
import { defaultSanitizeUrl, isHashChange } from './utils.ts';
import { defaultSanitizeUrl } from '#utils';
import { isHashChange } from './utils.ts';

describe('isHashChange', () => {
it('should return true when adding a hash to the same URL', () => {
Expand Down
61 changes: 0 additions & 61 deletions packages/instrumentation/src/navigation/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,67 +3,6 @@
* SPDX-License-Identifier: Apache-2.0
*/

const SENSITIVE_PARAMS = [
'password',
'passwd',
'secret',
'api_key',
'apikey',
'auth',
'authorization',
'token',
'access_token',
'refresh_token',
'jwt',
'session',
'sessionid',
'key',
'private_key',
'client_secret',
'client_id',
'signature',
'hash',
];

/**
* Default URL sanitization function that redacts credentials and sensitive query parameters.
* This is the default implementation used when no custom sanitizeUrl callback is provided.
*
* @param url - The URL to sanitize
* @returns The sanitized URL with credentials and sensitive parameters redacted
*/
export function defaultSanitizeUrl(url: string): string {
try {
const urlObj = new URL(url);

if (urlObj.username || urlObj.password) {
urlObj.username = 'REDACTED';
urlObj.password = 'REDACTED';
}

for (const param of SENSITIVE_PARAMS) {
if (urlObj.searchParams.has(param)) {
urlObj.searchParams.set(param, 'REDACTED');
}
}

return urlObj.toString();
} catch {
// If URL parsing fails, redact credentials and sensitive query parameters
// using regexes. The credential regex uses a restricted character class to
// avoid polynomial time complexity.
let sanitized = url.replace(/\/\/[^:/@]+:[^/@]+@/, '//REDACTED:REDACTED@');

for (const param of SENSITIVE_PARAMS) {
// Match param=value or param%3Dvalue (URL encoded)
const regex = new RegExp(`([?&]${param}(?:%3D|=))[^&]*`, 'gi');
sanitized = sanitized.replace(regex, '$1REDACTED');
}

return sanitized;
}
}

/**
* Determines if navigation between two URLs represents a hash change.
* A hash change is true if the URLs are the same except for the hash part,
Expand Down
1 change: 1 addition & 0 deletions packages/instrumentation/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@

export { getElementCSSSelector } from './getElementCSSSelector.ts';
export { getElementXPath } from './getElementXPath.ts';
export { defaultSanitizeUrl } from './url.ts';
56 changes: 56 additions & 0 deletions packages/instrumentation/src/utils/url.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

const SENSITIVE_PARAMS = [
'password',
'passwd',
'secret',
'api_key',
'apikey',
'auth',
'authorization',
'token',
'access_token',
'refresh_token',
'jwt',
'session',
'sessionid',
'key',
'private_key',
'client_secret',
'client_id',
'signature',
'hash',
];

/**
* Default URL sanitization function that redacts credentials and sensitive query parameters.
* This is the default implementation used when no custom sanitizeUrl callback is provided.
*
* @param url - The URL to sanitize
* @returns The sanitized URL with credentials and sensitive parameters redacted
*/
export function defaultSanitizeUrl(url: string): string {
try {
const urlObj = new URL(url);
if (urlObj.username || urlObj.password) {
urlObj.username = 'REDACTED';
urlObj.password = 'REDACTED';
}
for (const param of SENSITIVE_PARAMS) {
if (urlObj.searchParams.has(param)) {
urlObj.searchParams.set(param, 'REDACTED');
}
}
return urlObj.toString();
} catch {
let sanitized = url.replace(/\/\/[^:/@]+:[^/@]+@/, '//REDACTED:REDACTED@');
for (const param of SENSITIVE_PARAMS) {
const regex = new RegExp(`([?&]${param}(?:%3D|=))[^&]*`, 'gi');
sanitized = sanitized.replace(regex, '$1REDACTED');
}
return sanitized;
}
}
Loading