add: remote logger request uri sanitisation (JS) (#51046)

* add: remote logger request uri sanitisation

* md lint

* Update packages/js/remote-logging/README.md

Co-authored-by: Paul Sealock <psealock@gmail.com>

* pr feedback

---------

Co-authored-by: Paul Sealock <psealock@gmail.com>
This commit is contained in:
RJ 2024-09-03 13:42:03 +08:00 committed by GitHub
parent c1f9a73af1
commit 258ae0b03b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 109 additions and 3 deletions

View File

@ -172,3 +172,27 @@ addFilter(
(endpoint) => 'https://my-custom-endpoint.com/js-error-log'
);
```
### `woocommerce_remote_logging_request_uri_whitelist`
Modifies the list of whitelisted query parameters that won't be masked in the logged request URI
**Parameters:**
- `whitelist` (string[]): The default whitelist.
**Return value:** (string[]) The modified whitelist.
**Usage example:**
```js
import { addFilter } from '@wordpress/hooks';
addFilter(
'woocommerce_remote_logging_request_uri_whitelist',
'my-plugin',
( whitelist ) => {
return [ ...whitelist, 'exampleParam' ]
}
);
```

View File

@ -0,0 +1,4 @@
Significance: minor
Type: update
Add query params sanitisation

View File

@ -33,6 +33,44 @@ export const REMOTE_LOGGING_LOG_ENDPOINT_FILTER =
export const REMOTE_LOGGING_JS_ERROR_ENDPOINT_FILTER =
'woocommerce_remote_logging_js_error_endpoint';
export const REMOTE_LOGGING_REQUEST_URI_PARAMS_WHITELIST_FILTER =
'woocommerce_remote_logging_request_uri_whitelist';
export const REMPOTE_LOGGING_REQUEST_URI_PARAMS_DEFAULT_WHITELIST = [
'path',
'page',
'step',
'task',
'tab',
'section',
'status',
'post_type',
'taxonomy',
'action',
];
export const sanitiseRequestUriParams = ( search: string ) => {
const params = new URLSearchParams( search );
/**
* This filter modifies the list of whitelisted query parameters that won't be masked
* in the logged request URI
*
* @filter woocommerce_remote_logging_request_uri_whitelist
* @param {string[]} whitelist The default whitelist
*/
const whitelist = applyFilters(
REMOTE_LOGGING_REQUEST_URI_PARAMS_WHITELIST_FILTER,
REMPOTE_LOGGING_REQUEST_URI_PARAMS_DEFAULT_WHITELIST
) as typeof REMPOTE_LOGGING_REQUEST_URI_PARAMS_DEFAULT_WHITELIST;
for ( const [ key ] of params ) {
if ( ! whitelist.includes( key ) ) {
params.set( key, 'xxxxxx' );
}
}
return params.toString();
};
const REMOTE_LOGGING_LAST_ERROR_SENT_KEY =
'wc_remote_logging_last_error_sent_time';
@ -106,7 +144,8 @@ export class RemoteLogger {
properties: {
...extraData?.properties,
request_uri:
window.location.pathname + window.location.search,
window.location.pathname +
sanitiseRequestUriParams( window.location.search ),
},
} ),
trace: this.getFormattedStackFrame(
@ -213,7 +252,8 @@ export class RemoteLogger {
tags: [ 'js-unhandled-error' ],
properties: {
request_uri:
window.location.pathname + window.location.search,
window.location.pathname +
sanitiseRequestUriParams( window.location.search ),
},
} ),
trace: this.getFormattedStackFrame( trace ),

View File

@ -13,6 +13,8 @@ import {
REMOTE_LOGGING_ERROR_DATA_FILTER,
REMOTE_LOGGING_LOG_ENDPOINT_FILTER,
REMOTE_LOGGING_JS_ERROR_ENDPOINT_FILTER,
sanitiseRequestUriParams,
REMOTE_LOGGING_REQUEST_URI_PARAMS_WHITELIST_FILTER,
} from '../remote-logger';
import { fetchMock } from './__mocks__/fetch';
@ -380,3 +382,24 @@ describe( 'captureException', () => {
expect( fetchMock ).not.toHaveBeenCalled();
} );
} );
describe( 'sanitiseRequestUriParams', () => {
afterEach(() => {
removeFilter(REMOTE_LOGGING_REQUEST_URI_PARAMS_WHITELIST_FILTER, 'test' );
})
it( 'should replace non-whitelisted params with xxxxxx', () => {
expect(sanitiseRequestUriParams('?path=home&user=admin&token=abc123')).toEqual('path=home&user=xxxxxx&token=xxxxxx')
})
it( 'should not replace whitelisted params with xxxxxx', () => {
expect(sanitiseRequestUriParams('?path=home')).toEqual('path=home')
})
it( 'should not do anything if empty string is passed in', () => {
expect(sanitiseRequestUriParams('')).toEqual('')
})
it( 'should apply filters correctly', () => {
addFilter( REMOTE_LOGGING_REQUEST_URI_PARAMS_WHITELIST_FILTER, 'test', (defaultWhitelist) => {
return [ ... defaultWhitelist, 'foo' ];
})
expect(sanitiseRequestUriParams('?path=home&foo=bar&user=admin&token=abc123')).toEqual('path=home&foo=bar&user=xxxxxx&token=xxxxxx')
})
})

View File

@ -0,0 +1,4 @@
Significance: minor
Type: update
Added more paths to remote logger query param whitelist

View File

@ -438,7 +438,18 @@ class RemoteLogger extends \WC_Log_Handler {
* @return string The sanitized request URI.
*/
private function sanitize_request_uri( $request_uri ) {
$default_whitelist = array( 'path', 'page', 'step', 'task', 'tab' );
$default_whitelist = array(
'path',
'page',
'step',
'task',
'tab',
'section',
'status',
'post_type',
'taxonomy',
'action',
);
/**
* Filter to allow other plugins to whitelist request_uri query parameter values for unmasked remote logging.