Skip to content

Commit

Permalink
Merge pull request #990 from postmanlabs/feature/sanitize-timers
Browse files Browse the repository at this point in the history
Sanitized the global scope by deleting the timers properties
  • Loading branch information
codenirvana authored Apr 1, 2024
2 parents 53b4ac3 + 6677305 commit 6919e1f
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
unreleased:
fixed bugs:
- GH-986 Fixed the types for `pm.execution.setNextRequest`
- GH-990 Sanitized the global scope by deleting the timers properties

4.6.0:
date: 2024-03-13
Expand Down
2 changes: 1 addition & 1 deletion lib/sandbox/cookie-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ STORE_METHODS.forEach(function (method) {
// This timeout ensures that the event is processed asynchronously
// without blocking the rest of the script execution.
// Refer: https://github.com/postmanlabs/postman-app-support/issues/11064
setTimeout(() => {
this.timers.wrapped.setTimeout(() => {
// finally, dispatch event over the bridge
this.emitter.dispatch(eventName, eventId, EVENT_STORE_ACTION, method, args);
});
Expand Down
9 changes: 5 additions & 4 deletions lib/sandbox/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
*/
/* global bridge */

// Setup Timerz before we delete the global timers
require('./timers');

// Although we execute the user code in a well-defined scope using the uniscope
// module but still to cutoff the reference to the globally available properties
// we sanitize the global scope by deleting the forbidden properties in this UVM
Expand All @@ -35,9 +38,7 @@
'require', 'eval', 'console',
// 3. allow uvm internals because these will be cleared by uvm itself at the end.
// make sure any new property added in uvm firmware is allowed here as well.
'bridge', '__uvm_emit', '__uvm_dispatch', '__uvm_addEventListener',
// 4.allow all the timer methods
'setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'setImmediate', 'clearImmediate'
'bridge', '__uvm_emit', '__uvm_dispatch', '__uvm_addEventListener'
]),
deleteProperty = function (key) {
// directly delete the property without setting it to `null` or `undefined`
Expand Down Expand Up @@ -78,7 +79,7 @@ require('./purse');
// setup the ping-pong and execute routines
bridge.on('ping', require('./ping').listener('pong'));

// initialise execution
// initialize execution
require('./execute')(bridge, {
console: (typeof console !== 'undefined' ? console : null),
window: (typeof window !== 'undefined' ? window : null)
Expand Down
20 changes: 12 additions & 8 deletions lib/sandbox/timers.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* @fileoverview This file contains the module that is required to enable specialised timers that have better control
* @fileOverview This file contains the module that is required to enable specialized timers that have better control
* on a global level.
*
* @todo - the architecture of this sucks even if this "works".
Expand All @@ -13,15 +13,15 @@ const /**
FUNCTION = 'function',

/**
* The set of timer function names. We use this array to define common behaviour of all setters and clearer timer
* The set of timer function names. We use this array to define common behavior of all setters and clearer timer
* functions
*
* @constant {Array.<String>}
*/
timerFunctionNames = ['Timeout', 'Interval', 'Immediate', 'Event'],

/**
* This object defines a set of timer function names that are trigerred a number of times instead of a single time.
* This object defines a set of timer function names that are triggered a number of times instead of a single time.
* Such timers, when placed in generic rules, needs special attention.
*
* @constant {Array.<Boolean>}
Expand Down Expand Up @@ -54,7 +54,7 @@ const /**
*
* @note This is a very important piece of code from compatibility standpoint.
* The global timers need to be returned as a function that does not hold reference to the scope
* and does not retain references to scope. Aditionally, the invocation of the timer function is
* and does not retain references to scope. Additionally, the invocation of the timer function is
* done without changing the scope to avoid Illegal Invocation errors.
*
* `timerFunctionNames` returns the suffixes of all timer operations that needs a
Expand Down Expand Up @@ -82,13 +82,17 @@ const /**
isGlobalClearAvailable = (new Function(`return typeof clear${name} === 'function'`))();

if (isGlobalSetterAvailable) {
// eslint-disable-next-line no-new-func
timers[('set' + name)] = (new Function(`return function (fn, ms) { return set${name}(fn, ms); }`))();
timers[`set${name}`] = (
// eslint-disable-next-line no-new-func
new Function('_setFn', `return function set${name} (fn, ms) { return _setFn(fn, ms); }`)
)(this[`set${name}`]);
}

if (isGlobalClearAvailable) {
// eslint-disable-next-line no-new-func
timers[('clear' + name)] = (new Function(`return function (id) { return clear${name}(id); }`))();
timers[`clear${name}`] = (
// eslint-disable-next-line no-new-func
new Function('_clearFn', `return function clear${name} (id) { return _clearFn(id); }`)
)(this[`clear${name}`]);
}

return timers;
Expand Down
1 change: 0 additions & 1 deletion test/unit/sandbox-sanity.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ describe('sandbox', function () {
var ignoredProps = [
'TEMPORARY', 'PERSISTENT', // DedicatedWorkerGlobalScope constants (in Browser)
'require', 'eval', 'console', // uniscope ignored
'setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'setImmediate', 'clearImmediate'
]
var propNames = [];
Expand Down

0 comments on commit 6919e1f

Please sign in to comment.