@@ -20,6 +20,15 @@ const {
2020 redactKeysFromPostedFormVariables,
2121} = require ( './filters/sanitize-field-names' ) ;
2222
23+ // When redacting individual cookie field values, this string is used instead
24+ // of `[REDACTED]`. The APM spec says:
25+ // > The replacement string SHOULD be `[REDACTED]`.
26+ // We diverge from spec here because, for better or worse, the `cookie` module
27+ // does `encodeURIComponent/decodeURIComponent` encoding on cookie fields. If we
28+ // used the brackets, then the reconstructed cookie would look like
29+ // `foo=bar; session-id=%5BREDACTED%5D`, which isn't helpful.
30+ const COOKIE_VAL_REDACTED = 'REDACTED' ;
31+
2332/**
2433 * Extract appropriate `{transaction,error}.context.request` from an HTTP
2534 * request object. This handles header and body capture and redaction
@@ -61,14 +70,21 @@ function getContextFromRequest(req, conf, type) {
6170 conf . sanitizeFieldNamesRegExp ,
6271 ) ;
6372
64- if ( context . headers . cookie ) {
65- context . cookies = cookie . parse ( req . headers . cookie ) ;
66- context . cookies = redactKeysFromObject (
67- context . cookies ,
73+ if ( context . headers . cookie && context . headers . cookie !== REDACTED ) {
74+ let cookies = cookie . parse ( req . headers . cookie ) ;
75+ cookies = redactKeysFromObject (
76+ cookies ,
6877 conf . sanitizeFieldNamesRegExp ,
78+ COOKIE_VAL_REDACTED ,
6979 ) ;
70- // Redact the cookie to avoid data duplication
71- context . headers . cookie = REDACTED ;
80+ try {
81+ context . headers . cookie = Object . keys ( cookies )
82+ . map ( ( k ) => cookie . serialize ( k , cookies [ k ] ) )
83+ . join ( '; ' ) ;
84+ } catch ( _err ) {
85+ // Fallback to full redaction if there is an issue re-serializing.
86+ context . headers . cookie = REDACTED ;
87+ }
7288 }
7389 }
7490
0 commit comments