@contrast/assess 1.24.0 → 1.24.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.
@@ -62,7 +62,7 @@ module.exports = function(core) {
62
62
  args: data.origArgs.map((_arg, idx) => ({
63
63
  value: idx === 0 ? trackingData.value : restOfArgsValues[idx - 1],
64
64
  tracked: !!idx === 0
65
- })),
65
+ })).filter(el => el),
66
66
  result: {
67
67
  value: result,
68
68
  tracked: !!resultInfo
@@ -46,6 +46,7 @@ module.exports = function(core) {
46
46
  const namedGroups = hasNamedGroup ? lastEl : null;
47
47
  return { match, captureGroups, matchIdx, str, namedGroups };
48
48
  }
49
+
49
50
  function replaceSpecialCharacters(replacement, { captureGroups, match, str, namedGroups }, replacementType) {
50
51
  const origReplace = patcher.unwrap(String.prototype.replace);
51
52
  let ret = replacement;
@@ -82,7 +83,7 @@ module.exports = function(core) {
82
83
  if (numberedGroupMatches) {
83
84
  numberedGroupMatches.forEach((numberedGroup) => {
84
85
  const group = Number(substring(numberedGroup, 1));
85
- ret = origReplace.call(ret, numberedGroup, captureGroups[group - 1]);
86
+ ret = origReplace.call(ret, numberedGroup, captureGroups[group - 1] || '');
86
87
  });
87
88
  }
88
89
 
@@ -94,6 +95,7 @@ module.exports = function(core) {
94
95
 
95
96
  return ret;
96
97
  }
98
+
97
99
  function getReplacementInfo(data, replacerArgs, parsedArgs) {
98
100
  let replacement = data._replacementType === 'function' ?
99
101
  data._replacement.call(global, ...replacerArgs) :
@@ -51,6 +51,31 @@ module.exports = function(core) {
51
51
  ]
52
52
  ];
53
53
 
54
+ function getPropagationEvent(argInfo, partInfo, { name, result, hooked, orig }, parseQueryString = false) {
55
+ return createPropagationEvent({
56
+ name,
57
+ moduleName: 'url',
58
+ methodName: 'parse',
59
+ context: `url.parse('${argInfo.value += parseQueryString ? "', true" : ''})`,
60
+ object: {
61
+ value: 'url',
62
+ tracked: false
63
+ },
64
+ result: {
65
+ value: inspect(result),
66
+ tracked: true
67
+ },
68
+ args: [{ value: partInfo.value, tracked: true }],
69
+ tags: partInfo.tags,
70
+ history: [{ ...partInfo }],
71
+ source: 'P',
72
+ target: 'R',
73
+ stacktraceOpts: {
74
+ constructorOpt: hooked,
75
+ prependFrames: [orig]
76
+ },
77
+ });
78
+ }
54
79
 
55
80
  return core.assess.dataflow.propagation.urlInstrumentation.parse = {
56
81
  install() {
@@ -65,47 +90,41 @@ module.exports = function(core) {
65
90
  const { args, result, hooked, orig } = data;
66
91
  if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return;
67
92
 
68
- const url = args[0];
93
+ const [url, parseQueryString] = args;
69
94
  const argInfo = tracker.getData(url);
70
95
 
71
96
  if (!argInfo) return;
72
97
 
98
+ const metadata = { name, result, hooked, orig };
73
99
  const traverse = function(href, url, keys, idx = 0) {
74
100
  let substr = href;
75
101
  keys.forEach((key) => {
76
102
  if (typeof key === 'string') {
77
103
  const part = result[key];
78
104
  if (part) {
79
- const index = href.indexOf(part, idx - 1);
80
- substr = href.substring(index, index + part.length);
81
- idx += part.length;
105
+
106
+ if (key === 'query' && parseQueryString) {
107
+ Object.keys(part).forEach((key) => {
108
+ const partInfo = tracker.getData(part[key]);
109
+
110
+ if (!partInfo) return;
111
+
112
+ const event = getPropagationEvent(argInfo, partInfo, metadata, parseQueryString);
113
+ if (!event) return;
114
+
115
+ Object.assign(partInfo, event);
116
+ });
117
+ return;
118
+ } else {
119
+ const index = href.indexOf(part, idx - 1);
120
+ substr = href.substring(index, index + part.length);
121
+ idx += part.length;
122
+ }
82
123
 
83
124
  const partInfo = tracker.getData(substr);
84
125
  if (!partInfo) return;
85
126
 
86
- const event = createPropagationEvent({
87
- name,
88
- moduleName: 'url',
89
- methodName: 'parse',
90
- context: `url.parse('${argInfo.value}')`,
91
- object: {
92
- value: 'url',
93
- tracked: false
94
- },
95
- result: {
96
- value: inspect(result),
97
- tracked: true
98
- },
99
- args: [{ value: partInfo.value, tracked: true }],
100
- tags: partInfo.tags,
101
- history: [partInfo],
102
- source: 'P',
103
- target: 'R',
104
- stacktraceOpts: {
105
- constructorOpt: hooked,
106
- prependFrames: [orig]
107
- },
108
- });
127
+ const event = getPropagationEvent(argInfo, partInfo, metadata);
109
128
 
110
129
  if (!event) return;
111
130
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/assess",
3
- "version": "1.24.0",
3
+ "version": "1.24.1",
4
4
  "description": "Contrast service providing framework-agnostic Assess support",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",