@contrast/protect 1.74.1 → 1.75.1

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.
@@ -29,7 +29,7 @@ const {
29
29
  ArrayPrototypeJoin,
30
30
  ArrayPrototypeSlice,
31
31
  StringPrototypeToLowerCase,
32
- StringPrototypeSplit,
32
+ StringPrototypeMatch,
33
33
  }
34
34
  } = require('@contrast/common');
35
35
  const { Core } = require('@contrast/core/lib/ioc/core');
@@ -53,16 +53,13 @@ const { Core } = require('@contrast/core/lib/ioc/core');
53
53
  // input and make a decision immediately (i.e., there is no sink). so these two
54
54
  // rules will need to be implemented by the agent and called from these handlers.
55
55
 
56
-
57
56
  // agent-lib treats each type of nosql database as a separate
58
57
  // rule. they are all mapped to 'nosql-injection' in the agent.
59
58
  // maybe this will need to change.
60
59
  const agentLibRuleTypeToName = {
61
60
  'nosql-injection-mongo': 'nosql-injection'
62
61
  };
63
-
64
62
  const preferWW = { preferWorthWatching: true };
65
-
66
63
  const acceptedMethods = new Set([
67
64
  'acl',
68
65
  'baseline-control',
@@ -96,9 +93,11 @@ const acceptedMethods = new Set([
96
93
  'update',
97
94
  'version-control',
98
95
  ]);
96
+ const componentName = 'protect.inputAnalysis.handlers';
97
+ const noInstrumentationStore = { lock: true, name: componentName };
99
98
 
100
99
  module.exports = Core.makeComponent({
101
- name: 'protect.inputAnalysis.handlers',
100
+ name: componentName,
102
101
  factory(core) {
103
102
  const {
104
103
  logger,
@@ -107,6 +106,7 @@ module.exports = Core.makeComponent({
107
106
  agentLib,
108
107
  inputAnalysis,
109
108
  },
109
+ scopes,
110
110
  config,
111
111
  } = core;
112
112
 
@@ -946,12 +946,21 @@ module.exports = Core.makeComponent({
946
946
  function ipListAnalysis(reqIp, reqHeaders, list) {
947
947
  const forwardedIps = [];
948
948
 
949
- for (let i = 0; i < reqHeaders.length; i++) {
950
- if (reqHeaders[i] === 'x-forwarded-for') {
951
- const ipsFromHeaders = StringPrototypeSplit.call(reqHeaders[i + 1], /[,;]+/);
952
- forwardedIps.push(...ipsFromHeaders);
949
+ // RegExp.exec will still get called under the hood even with using primordials
950
+ scopes.instrumentation.run(noInstrumentationStore, () => {
951
+ for (let i = 0; i < reqHeaders.length; i++) {
952
+ if (reqHeaders[i] === 'x-forwarded-for') {
953
+ // This matches one or more valid IPv4/IPv6 characters, automatically
954
+ // skipping delimiters, whitespace, and invalid characters
955
+ const matches = StringPrototypeMatch.call(reqHeaders[i + 1], /[0-9a-fA-F.:]+/g);
956
+ if (matches) {
957
+ for (const ip of matches) {
958
+ forwardedIps.push(ip);
959
+ }
960
+ }
961
+ }
953
962
  }
954
- }
963
+ });
955
964
 
956
965
  const ipsToCheck = [reqIp, ...forwardedIps];
957
966
  const now = new Date().getTime();
@@ -968,7 +977,7 @@ module.exports = Core.makeComponent({
968
977
 
969
978
  // Ignore bad IP values.
970
979
  if (!address.isValid(currentIp)) {
971
- logger.warn('Unable to parse %s.', currentIp);
980
+ logger.debug({ value: currentIp, length: currentIp.length }, 'Unable to parse IP address %s.', currentIp);
972
981
  continue;
973
982
  }
974
983
  const expired = doesExpire ? expiresAt - now <= 0 : false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/protect",
3
- "version": "1.74.1",
3
+ "version": "1.75.1",
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)",
@@ -20,21 +20,21 @@
20
20
  "test": "bash ../scripts/test.sh"
21
21
  },
22
22
  "dependencies": {
23
- "@contrast/agent-lib": "^9.1.0",
23
+ "@contrast/agent-lib": "9.2.0",
24
24
  "@contrast/common": "1.41.1",
25
- "@contrast/config": "1.57.1",
26
- "@contrast/core": "1.62.1",
27
- "@contrast/dep-hooks": "1.31.1",
28
- "@contrast/esm-hooks": "2.37.1",
29
- "@contrast/instrumentation": "1.41.1",
30
- "@contrast/logger": "1.35.1",
31
- "@contrast/patcher": "1.34.1",
32
- "@contrast/rewriter": "1.39.1",
33
- "@contrast/scopes": "1.32.1",
34
- "@contrast/stack-trace-factory": "1.2.1",
35
- "async-hook-domain": "^4.0.1",
36
- "ipaddr.js": "^2.0.1",
37
- "on-finished": "^2.4.1",
38
- "semver": "^7.6.0"
25
+ "@contrast/config": "1.58.1",
26
+ "@contrast/core": "1.63.1",
27
+ "@contrast/dep-hooks": "1.32.1",
28
+ "@contrast/esm-hooks": "2.38.1",
29
+ "@contrast/instrumentation": "1.42.1",
30
+ "@contrast/logger": "1.36.1",
31
+ "@contrast/patcher": "1.35.1",
32
+ "@contrast/rewriter": "1.40.1",
33
+ "@contrast/scopes": "1.33.1",
34
+ "@contrast/stack-trace-factory": "1.3.1",
35
+ "async-hook-domain": "4.0.1",
36
+ "ipaddr.js": "2.0.1",
37
+ "on-finished": "2.4.1",
38
+ "semver": "7.6.0"
39
39
  }
40
40
  }