@contrast/protect 1.42.0 → 1.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,9 +24,12 @@ const {
24
24
  traverseKeysAndValues,
25
25
  traverseValues,
26
26
  InputType,
27
- ArrayPrototypeJoin,
28
- StringPrototypeToLowerCase,
29
- StringPrototypeSplit,
27
+ primordials: {
28
+ ArrayPrototypeJoin,
29
+ ArrayPrototypeSlice,
30
+ StringPrototypeToLowerCase,
31
+ StringPrototypeSplit,
32
+ }
30
33
  } = require('@contrast/common');
31
34
 
32
35
  //
@@ -256,7 +259,7 @@ module.exports = function (core) {
256
259
  resultsList.push({
257
260
  ruleId: item.ruleId,
258
261
  inputType: 'UrlParameter',
259
- path: path.slice(),
262
+ path: ArrayPrototypeSlice.call(path),
260
263
  key: path.pop(), // there should always be at least the param name
261
264
  value,
262
265
  score: item.score,
@@ -692,7 +695,7 @@ module.exports = function (core) {
692
695
  const result = {
693
696
  ruleId: item.ruleId,
694
697
  inputType: `${inputTypeStr}${type}`,
695
- path: mongoPath || path.slice(),
698
+ path: mongoPath || ArrayPrototypeSlice.call(path),
696
699
  key: type === 'Key' ? value : path[path.length - 1],
697
700
  value,
698
701
  score: item.score,
@@ -15,6 +15,7 @@
15
15
 
16
16
  'use strict';
17
17
 
18
+ const { primordials: { JSONParse } } = require('@contrast/common');
18
19
  const { isSecurityException } = require('../../security-exception');
19
20
 
20
21
  module.exports = (core) => {
@@ -35,7 +36,7 @@ module.exports = (core) => {
35
36
 
36
37
  if (fnName === 'bodyParser.text' && typeof req.body === 'string') {
37
38
  try {
38
- sourceContext.parsedBody = JSON.parse(req.body);
39
+ sourceContext.parsedBody = JSONParse(req.body);
39
40
  } catch (err) {
40
41
  logger.error({ err }, 'Error parsing with bodyParser.text()');
41
42
  origNext();
@@ -15,7 +15,7 @@
15
15
 
16
16
  'use strict';
17
17
 
18
- const { Event, StringPrototypeToLowerCase } = require('@contrast/common');
18
+ const { Event, primordials: { StringPrototypeToLowerCase, ArrayPrototypeSlice } } = require('@contrast/common');
19
19
  const { patchType } = require('../constants');
20
20
 
21
21
  module.exports = function (core) {
@@ -38,7 +38,7 @@ module.exports = function (core) {
38
38
  function removeCookies(headers) {
39
39
  for (let i = 0; i < headers.length; i += 2) {
40
40
  if (headers[i] === 'cookies') {
41
- headers = headers.slice();
41
+ headers = ArrayPrototypeSlice.call(headers);
42
42
  headers.splice(i, 2);
43
43
  }
44
44
  }
@@ -94,7 +94,7 @@ module.exports = function (core) {
94
94
  const connectInputs = {
95
95
  headers: removeCookies(headers),
96
96
  uriPath,
97
- method:StringPrototypeToLowerCase.call(method),
97
+ method: StringPrototypeToLowerCase.call(method),
98
98
  };
99
99
 
100
100
  if (inputAnalysis.virtualPatchesEvaluators?.length) {
@@ -10,6 +10,10 @@ describe('protect input-analysis http', function () {
10
10
 
11
11
  describe('initialization', function () {
12
12
  let core, httpInstr, mockServer;
13
+ // this captures the sinon stub before it is wrapped by Perf so we can
14
+ // determine if it was called/not called as expected. if we don't do this
15
+ // the core.depHooks.install() will be replaced by the Perf wrapper and
16
+ // sinon will complain that it's not a spy/call-to-spy.
13
17
 
14
18
  beforeEach(function () {
15
19
  ({ core } = initProtectFixture());
@@ -38,7 +42,9 @@ describe('protect input-analysis http', function () {
38
42
 
39
43
  it('should not be initialized after being required', function () {
40
44
  expect(httpInstr.install).a('function');
41
- expect(core.depHooks.install).not.to.have.been.called;
45
+ // the next two lines are effectively: expect(core.depHooks.install).not.to.have.been.called;
46
+ const depHooksInstall = core.Perf.all.get('agentify').get('agentify:@contrast/dep-hooks:install');
47
+ expect(depHooksInstall).equal(undefined);
42
48
  expect(core.depHooks.resolve).not.to.have.been.called;
43
49
  });
44
50
 
@@ -15,7 +15,7 @@
15
15
 
16
16
  'use strict';
17
17
 
18
- const { Event, StringPrototypeSubstr } = require('@contrast/common');
18
+ const { Event, primordials: { StringPrototypeSubstr } } = require('@contrast/common');
19
19
  const address = require('ipaddr.js');
20
20
 
21
21
  module.exports = (core) => {
@@ -15,7 +15,7 @@
15
15
 
16
16
  'use strict';
17
17
 
18
- const { Event, StringPrototypeToLowerCase } = require('@contrast/common');
18
+ const { Event, primordials: { StringPrototypeToLowerCase, RegExpPrototypeTest } } = require('@contrast/common');
19
19
 
20
20
  module.exports = (core) => {
21
21
  const {
@@ -95,13 +95,13 @@ function buildVPEvaluators(virtualPatches, evaluatorsArray) {
95
95
  function buildEvaluationCheck(evaluation) {
96
96
  switch (evaluation) {
97
97
  case 'MATCHES':
98
- return (reqValue, matchedValue) => new RegExp(matchedValue, 'i').test(reqValue);
98
+ return (reqValue, matchedValue) => RegExpPrototypeTest.call(new RegExp(matchedValue, 'i'), reqValue);
99
99
  case 'EQUALS':
100
100
  return (reqValue, matchedValue) => reqValue.toString() === matchedValue.toString();
101
101
  case 'CONTAINS':
102
102
  return (reqValue, matchedValue) => reqValue.includes(matchedValue);
103
103
  case 'DOESNT_MATCH':
104
- return (reqValue, matchedValue) => !new RegExp(matchedValue, 'i').test(reqValue);
104
+ return (reqValue, matchedValue) => !RegExpPrototypeTest.call(new RegExp(matchedValue, 'i'), reqValue);
105
105
  // This is a typo but it is how it's passed from ContrastUI
106
106
  case 'DOESNT_EQUALS':
107
107
  return (reqValue, matchedValue) => reqValue.toString() !== matchedValue.toString();
@@ -20,7 +20,7 @@ const {
20
20
  ProtectRuleMode: { OFF },
21
21
  BLOCKING_MODES,
22
22
  isString,
23
- JSONStringify,
23
+ primordials: { JSONStringify },
24
24
  traverseKeys,
25
25
  traverseKeysAndValues,
26
26
  agentLibIDListTypes,
@@ -16,7 +16,7 @@
16
16
  'use strict';
17
17
 
18
18
  const {
19
- StringPrototypeToUpperCase,
19
+ primordials: { StringPrototypeToUpperCase },
20
20
  symbols: { kMetrics }
21
21
  } = require('@contrast/common');
22
22
 
@@ -15,7 +15,7 @@
15
15
 
16
16
  'use strict';
17
17
 
18
- const { StringPrototypeToLowerCase, StringPrototypeSlice } = require('@contrast/common');
18
+ const { primordials: { StringPrototypeToLowerCase, StringPrototypeSlice } } = require('@contrast/common');
19
19
 
20
20
  module.exports = function(core) {
21
21
  const {
package/lib/policy.js CHANGED
@@ -19,9 +19,12 @@ const {
19
19
  Rule,
20
20
  ProtectRuleMode,
21
21
  Event,
22
- ArrayPrototypeJoin,
23
- StringPrototypeToLowerCase,
24
- StringPrototypeSplit,
22
+ primordials: {
23
+ ArrayPrototypeJoin,
24
+ StringPrototypeToLowerCase,
25
+ StringPrototypeSplit,
26
+ RegExpPrototypeTest
27
+ }
25
28
  } = require('@contrast/common');
26
29
  const { ConfigSource } = require('@contrast/config');
27
30
 
@@ -90,7 +93,7 @@ module.exports = function (core) {
90
93
  if (regExpNeeded) {
91
94
  const rx = new RegExp(`^${ArrayPrototypeJoin.call(urls, '|')}$`);
92
95
 
93
- return (uriPath) => rx ? rx.test(uriPath) : false;
96
+ return (uriPath) => rx ? RegExpPrototypeTest.call(rx, uriPath) : false;
94
97
  }
95
98
 
96
99
  return (uriPath) => urls.some((url) => url === uriPath);
@@ -107,7 +110,7 @@ module.exports = function (core) {
107
110
  function createInputNameMatcher(dtmInputName) {
108
111
  if (regExpCheck(dtmInputName)) {
109
112
  const rx = new RegExp(`^${dtmInputName}$`);
110
- return (inputName) => rx ? rx.test(inputName) : false;
113
+ return (inputName) => rx ? RegExpPrototypeTest.call(rx, inputName) : false;
111
114
  }
112
115
 
113
116
  return (inputName) => inputName === dtmInputName;
@@ -21,7 +21,11 @@ const {
21
21
  ProtectRuleMode: { OFF },
22
22
  InputType,
23
23
  traverseValues,
24
- StringPrototypeReplace,
24
+ primordials: {
25
+ StringPrototypeReplace,
26
+ ArrayPrototypeSlice,
27
+ RegExpPrototypeTest
28
+ }
25
29
  } = require('@contrast/common');
26
30
 
27
31
  const {
@@ -166,7 +170,7 @@ function findBackdoorInjection(sourceContext, command) {
166
170
  found = {
167
171
  key,
168
172
  inputType: path.length > 1 ? InputType.JSON_VALUE : inputType,
169
- path: path.slice(0, -1),
173
+ path: ArrayPrototypeSlice.call(path, 0, -1),
170
174
  value: command
171
175
  };
172
176
 
@@ -195,6 +199,6 @@ function isBackdoorDetected(requestValue, command) {
195
199
  return (
196
200
  normalizedValue === normalizedCommand ||
197
201
  (normalizedCommand.endsWith(normalizedValue) &&
198
- SINK_EXPLOIT_PATTERN_START.test(normalizedCommand))
202
+ RegExpPrototypeTest.call(SINK_EXPLOIT_PATTERN_START, normalizedCommand))
199
203
  );
200
204
  }
@@ -14,7 +14,7 @@
14
14
  */
15
15
  'use strict';
16
16
 
17
- const { StringPrototypeSubstr, StringPrototypeToLowerCase } = require('@contrast/common');
17
+ const { primordials: { StringPrototypeSubstr, StringPrototypeToLowerCase, RegExpPrototypeTest, RegExpPrototypeExec } } = require('@contrast/common');
18
18
 
19
19
  const PROTOCOLS = {
20
20
  FTP: 'FTP',
@@ -67,7 +67,7 @@ function isExternalEntity(str) {
67
67
  if (str.startsWith(val)) return true;
68
68
  }
69
69
 
70
- return FILE_PATTERN_WINDOWS.test(str);
70
+ return RegExpPrototypeTest.call(FILE_PATTERN_WINDOWS, str);
71
71
  }
72
72
 
73
73
  /**
@@ -77,7 +77,7 @@ module.exports.findExternalEntities = function(xml = '') {
77
77
  const entities = [];
78
78
  let match;
79
79
 
80
- while ((match = entityRegex.exec(xml))) {
80
+ while ((match = RegExpPrototypeExec.call(entityRegex, xml))) {
81
81
  const {
82
82
  groups: { type, uri1, uri2 }
83
83
  } = match;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/protect",
3
- "version": "1.42.0",
3
+ "version": "1.44.0",
4
4
  "description": "Contrast service providing framework-agnostic Protect support",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",
@@ -18,16 +18,16 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@contrast/agent-lib": "^7.0.1",
21
- "@contrast/common": "1.25.0",
22
- "@contrast/config": "1.32.0",
23
- "@contrast/core": "1.36.0",
24
- "@contrast/dep-hooks": "1.4.0",
25
- "@contrast/esm-hooks": "2.10.0",
26
- "@contrast/instrumentation": "1.14.0",
27
- "@contrast/logger": "1.9.0",
28
- "@contrast/patcher": "1.8.0",
29
- "@contrast/rewriter": "1.12.0",
30
- "@contrast/scopes": "1.5.0",
21
+ "@contrast/common": "1.26.0",
22
+ "@contrast/config": "1.34.0",
23
+ "@contrast/core": "1.38.0",
24
+ "@contrast/dep-hooks": "1.6.0",
25
+ "@contrast/esm-hooks": "2.12.0",
26
+ "@contrast/instrumentation": "1.16.0",
27
+ "@contrast/logger": "1.11.0",
28
+ "@contrast/patcher": "1.10.0",
29
+ "@contrast/rewriter": "1.14.0",
30
+ "@contrast/scopes": "1.7.0",
31
31
  "ipaddr.js": "^2.0.1",
32
32
  "semver": "^7.6.0"
33
33
  },