@@ -149,6 +149,49 @@ const SENSITIVE_HEADER_SNIPPETS = [
149149 'cookie' ,
150150] ;
151151
152+ /**
153+ * Extra substrings matched only against individual Cookie / Set-Cookie **names** (not header names),
154+ * so we can cover common session secrets that do not match {@link SENSITIVE_HEADER_SNIPPETS}
155+ * (e.g. `connect.sid` does not contain `session`) without false positives on arbitrary HTTP headers.
156+ */
157+ const SENSITIVE_COOKIE_NAME_SNIPPETS = [
158+ // Express / Connect default session cookie
159+ '.sid' ,
160+ // PHP session cookie
161+ 'phpsess' ,
162+ // Common opaque session id suffix / cookie names (e.g. ASPSESSIONID*, BIGipServer*)
163+ 'sessid' ,
164+ // Laravel etc. "remember me" tokens
165+ 'remember' ,
166+ // OAuth / OIDC auxiliary cookies
167+ 'oauth' ,
168+ 'oidc' ,
169+ 'pkce' ,
170+ 'nonce' ,
171+ // Explicit token-style cookie names
172+ 'id_token' ,
173+ 'access_token' ,
174+ 'refresh_token' ,
175+ // RFC 6265bis cookie name prefixes for high-security cookies
176+ '__secure-' ,
177+ '__host-' ,
178+ // Load balancer / CDN sticky-session cookies (opaque routing tokens)
179+ 'awsalb' ,
180+ 'awselb' ,
181+ 'akamai' ,
182+ // BaaS / IdP session cookies (names often omit "session")
183+ '__stripe' ,
184+ 'cognito' ,
185+ 'firebase' ,
186+ 'supabase' ,
187+ 'sb-' ,
188+ // Auth.js / NextAuth.js
189+ 'next-auth' ,
190+ // Step-up / MFA cookies
191+ 'mfa' ,
192+ '2fa' ,
193+ ] ;
194+
152195const PII_HEADER_SNIPPETS = [ 'x-forwarded-' , '-user' ] ;
153196
154197/**
@@ -196,17 +239,23 @@ export function httpHeadersToSpanAttributes(
196239
197240 const lowerCasedCookieKey = cookieKey . toLowerCase ( ) ;
198241
199- addSpanAttribute (
242+ addSpanAttribute ( {
200243 spanAttributes,
201- lowerCasedHeaderKey ,
202- lowerCasedCookieKey ,
203- cookieValue ,
244+ headerKey : lowerCasedHeaderKey ,
245+ cookieKey : lowerCasedCookieKey ,
246+ value : cookieValue ,
204247 sendDefaultPii,
205248 lifecycle,
206- ) ;
249+ } ) ;
207250 }
208251 } else {
209- addSpanAttribute ( spanAttributes , lowerCasedHeaderKey , '' , value , sendDefaultPii , lifecycle ) ;
252+ addSpanAttribute ( {
253+ spanAttributes,
254+ headerKey : lowerCasedHeaderKey ,
255+ value,
256+ sendDefaultPii,
257+ lifecycle,
258+ } ) ;
210259 }
211260 } ) ;
212261 } catch {
@@ -220,15 +269,31 @@ function normalizeAttributeKey(key: string): string {
220269 return key . replace ( / - / g, '_' ) ;
221270}
222271
223- function addSpanAttribute (
224- spanAttributes : Record < string , string > ,
225- headerKey : string ,
226- cookieKey : string ,
227- value : string | string [ ] | undefined ,
228- sendPii : boolean ,
229- lifecycle : 'request' | 'response' ,
230- ) : void {
231- const headerValue = handleHttpHeader ( cookieKey || headerKey , value , sendPii ) ;
272+ type AddSpanAttributeOptions = {
273+ spanAttributes : Record < string , string > ;
274+ /** Lowercased HTTP header name (e.g. `cookie`, `set-cookie`, `accept`). */
275+ headerKey : string ;
276+ /**
277+ * Lowercased cookie name when this attribute comes from a parsed `Cookie` / `Set-Cookie` value.
278+ * Omit for non-cookie headers; when present and non-empty, cookie-specific sensitivity rules apply.
279+ */
280+ cookieKey ?: string ;
281+ value : string | string [ ] | undefined ;
282+ sendDefaultPii : boolean ;
283+ lifecycle : 'request' | 'response' ;
284+ } ;
285+
286+ function addSpanAttribute ( {
287+ spanAttributes,
288+ headerKey,
289+ cookieKey,
290+ value,
291+ sendDefaultPii,
292+ lifecycle,
293+ } : AddSpanAttributeOptions ) : void {
294+ const isCookieSubKey = Boolean ( cookieKey ) ;
295+ const nameForSensitivity = cookieKey || headerKey ;
296+ const headerValue = handleHttpHeader ( nameForSensitivity , value , sendDefaultPii , isCookieSubKey ) ;
232297 if ( headerValue == null ) {
233298 return ;
234299 }
@@ -241,10 +306,15 @@ function handleHttpHeader(
241306 lowerCasedKey : string ,
242307 value : string | string [ ] | undefined ,
243308 sendPii : boolean ,
309+ isCookieSubKey : boolean = false ,
244310) : string | undefined {
311+ const snippetsForSensitivity = isCookieSubKey
312+ ? [ ...SENSITIVE_HEADER_SNIPPETS , ...SENSITIVE_COOKIE_NAME_SNIPPETS ]
313+ : SENSITIVE_HEADER_SNIPPETS ;
314+
245315 const isSensitive = sendPii
246- ? SENSITIVE_HEADER_SNIPPETS . some ( snippet => lowerCasedKey . includes ( snippet ) )
247- : [ ...PII_HEADER_SNIPPETS , ...SENSITIVE_HEADER_SNIPPETS ] . some ( snippet => lowerCasedKey . includes ( snippet ) ) ;
316+ ? snippetsForSensitivity . some ( snippet => lowerCasedKey . includes ( snippet ) )
317+ : [ ...PII_HEADER_SNIPPETS , ...snippetsForSensitivity ] . some ( snippet => lowerCasedKey . includes ( snippet ) ) ;
248318
249319 if ( isSensitive ) {
250320 return '[Filtered]' ;
0 commit comments