@contrast/agent 4.4.1 → 4.6.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.
- package/bin/VERSION +1 -1
- package/bin/linux/contrast-service +0 -0
- package/bin/mac/contrast-service +0 -0
- package/bin/windows/contrast-service.exe +0 -0
- package/lib/assess/hapi/route-coverage.js +3 -3
- package/lib/assess/membrane/index.js +2 -8
- package/lib/assess/membrane/source-membrane.js +3 -4
- package/lib/assess/models/base-event.js +2 -2
- package/lib/assess/models/call-context.js +0 -3
- package/lib/assess/policy/propagators.json +20 -0
- package/lib/assess/policy/signatures.json +103 -0
- package/lib/assess/propagators/path/common.js +165 -36
- package/lib/assess/propagators/path/join.js +5 -1
- package/lib/assess/propagators/path/normalize.js +5 -1
- package/lib/assess/propagators/path/resolve.js +11 -2
- package/lib/assess/response-scanning/autocomplete-missing.js +0 -2
- package/lib/assess/response-scanning/parameter-pollution.js +0 -2
- package/lib/core/arch-components/dynamodb.js +1 -2
- package/lib/core/arch-components/dynamodbv3.js +44 -0
- package/lib/core/arch-components/index.js +1 -0
- package/lib/core/async-storage/hooks/bluebird.js +20 -0
- package/lib/core/config/options.js +3 -2
- package/lib/core/express/utils.js +1 -1
- package/lib/core/logger/debug-logger.js +15 -17
- package/lib/core/stacktrace.js +3 -4
- package/lib/feature-set.js +2 -1
- package/lib/hooks/encoding.js +1 -1
- package/lib/hooks/frameworks/base.js +8 -2
- package/lib/hooks/frameworks/http.js +23 -16
- package/lib/hooks/frameworks/http2.js +73 -0
- package/lib/hooks/frameworks/index.js +8 -3
- package/lib/hooks/http.js +112 -128
- package/lib/hooks/patcher.js +10 -12
- package/lib/hooks/require.js +16 -22
- package/lib/instrumentation.js +0 -3
- package/lib/protect/analysis/aho-corasick.js +13 -30
- package/lib/protect/rules/cmd-injection-command-backdoors/backdoor-detector.js +3 -3
- package/lib/protect/rules/signatures/reflected-xss/helpers/function-call.js +1 -1
- package/lib/protect/rules/xss/helpers/function-call.js +1 -1
- package/lib/util/clean-stack.js +1 -1
- package/lib/util/clean-string/brackets.js +3 -3
- package/lib/util/clean-string/concatenations.js +1 -1
- package/lib/util/clean-string/util.js +1 -2
- package/lib/util/ip-analyzer.js +1 -1
- package/lib/util/some.js +27 -0
- package/lib/util/xml-analyzer/external-entity-finder.js +1 -1
- package/package.json +14 -15
- package/lib/hooks/frameworks/https.js +0 -42
- package/node_modules/bindings/LICENSE.md +0 -22
- package/node_modules/bindings/README.md +0 -98
- package/node_modules/bindings/bindings.js +0 -221
- package/node_modules/bindings/package.json +0 -32
- package/node_modules/file-uri-to-path/.npmignore +0 -1
- package/node_modules/file-uri-to-path/.travis.yml +0 -30
- package/node_modules/file-uri-to-path/History.md +0 -21
- package/node_modules/file-uri-to-path/LICENSE +0 -20
- package/node_modules/file-uri-to-path/README.md +0 -74
- package/node_modules/file-uri-to-path/index.d.ts +0 -2
- package/node_modules/file-uri-to-path/index.js +0 -66
- package/node_modules/file-uri-to-path/package.json +0 -36
- package/node_modules/file-uri-to-path/test/test.js +0 -24
- package/node_modules/file-uri-to-path/test/tests.json +0 -13
- package/node_modules/glossy/LICENSE +0 -19
- package/node_modules/glossy/README.md +0 -129
- package/node_modules/glossy/index.js +0 -12
- package/node_modules/glossy/lib/glossy/parse.js +0 -520
- package/node_modules/glossy/lib/glossy/produce.js +0 -459
- package/node_modules/glossy/package.json +0 -47
- package/node_modules/glossy/test/decide.js +0 -7
- package/node_modules/glossy/test/decode_pri.js +0 -24
- package/node_modules/glossy/test/parse_3164.js +0 -104
- package/node_modules/glossy/test/parse_5424.js +0 -106
- package/node_modules/glossy/test/parse_5848.js +0 -40
- package/node_modules/glossy/test/parse_8601.js +0 -14
- package/node_modules/glossy/test/parse_rfc3339.js +0 -9
- package/node_modules/glossy/test/produce.js +0 -162
- package/node_modules/glossy/test/runner.js +0 -40
- package/node_modules/glossy/test/structure_data.js +0 -24
- package/node_modules/nan/CHANGELOG.md +0 -537
- package/node_modules/nan/LICENSE.md +0 -13
- package/node_modules/nan/README.md +0 -455
- package/node_modules/nan/doc/asyncworker.md +0 -146
- package/node_modules/nan/doc/buffers.md +0 -54
- package/node_modules/nan/doc/callback.md +0 -76
- package/node_modules/nan/doc/converters.md +0 -41
- package/node_modules/nan/doc/errors.md +0 -226
- package/node_modules/nan/doc/json.md +0 -62
- package/node_modules/nan/doc/maybe_types.md +0 -583
- package/node_modules/nan/doc/methods.md +0 -664
- package/node_modules/nan/doc/new.md +0 -147
- package/node_modules/nan/doc/node_misc.md +0 -123
- package/node_modules/nan/doc/object_wrappers.md +0 -263
- package/node_modules/nan/doc/persistent.md +0 -296
- package/node_modules/nan/doc/scopes.md +0 -73
- package/node_modules/nan/doc/script.md +0 -38
- package/node_modules/nan/doc/string_bytes.md +0 -62
- package/node_modules/nan/doc/v8_internals.md +0 -199
- package/node_modules/nan/doc/v8_misc.md +0 -85
- package/node_modules/nan/include_dirs.js +0 -1
- package/node_modules/nan/nan.h +0 -2898
- package/node_modules/nan/nan_callbacks.h +0 -88
- package/node_modules/nan/nan_callbacks_12_inl.h +0 -514
- package/node_modules/nan/nan_callbacks_pre_12_inl.h +0 -520
- package/node_modules/nan/nan_converters.h +0 -72
- package/node_modules/nan/nan_converters_43_inl.h +0 -68
- package/node_modules/nan/nan_converters_pre_43_inl.h +0 -42
- package/node_modules/nan/nan_define_own_property_helper.h +0 -29
- package/node_modules/nan/nan_implementation_12_inl.h +0 -430
- package/node_modules/nan/nan_implementation_pre_12_inl.h +0 -263
- package/node_modules/nan/nan_json.h +0 -166
- package/node_modules/nan/nan_maybe_43_inl.h +0 -356
- package/node_modules/nan/nan_maybe_pre_43_inl.h +0 -268
- package/node_modules/nan/nan_new.h +0 -340
- package/node_modules/nan/nan_object_wrap.h +0 -156
- package/node_modules/nan/nan_persistent_12_inl.h +0 -132
- package/node_modules/nan/nan_persistent_pre_12_inl.h +0 -242
- package/node_modules/nan/nan_private.h +0 -73
- package/node_modules/nan/nan_string_bytes.h +0 -305
- package/node_modules/nan/nan_typedarray_contents.h +0 -96
- package/node_modules/nan/nan_weak.h +0 -437
- package/node_modules/nan/package.json +0 -41
- package/node_modules/nan/tools/1to2.js +0 -412
- package/node_modules/nan/tools/README.md +0 -14
- package/node_modules/nan/tools/package.json +0 -19
- package/node_modules/unix-dgram/LICENSE +0 -13
- package/node_modules/unix-dgram/README.md +0 -107
- package/node_modules/unix-dgram/binding.gyp +0 -20
- package/node_modules/unix-dgram/build/Makefile +0 -324
- package/node_modules/unix-dgram/build/Release/.deps/Release/obj.target/unix_dgram/src/unix_dgram.o.d +0 -58
- package/node_modules/unix-dgram/build/Release/.deps/Release/obj.target/unix_dgram.node.d +0 -1
- package/node_modules/unix-dgram/build/Release/.deps/Release/unix_dgram.node.d +0 -1
- package/node_modules/unix-dgram/build/Release/obj.target/unix_dgram/src/unix_dgram.o +0 -0
- package/node_modules/unix-dgram/build/Release/obj.target/unix_dgram.node +0 -0
- package/node_modules/unix-dgram/build/Release/unix_dgram.node +0 -0
- package/node_modules/unix-dgram/build/binding.Makefile +0 -6
- package/node_modules/unix-dgram/build/config.gypi +0 -213
- package/node_modules/unix-dgram/build/unix_dgram.target.mk +0 -159
- package/node_modules/unix-dgram/lib/unix_dgram.js +0 -168
- package/node_modules/unix-dgram/package.json +0 -36
- package/node_modules/unix-dgram/src/unix_dgram.cc +0 -404
- package/node_modules/unix-dgram/src/win_dummy.cc +0 -7
- package/node_modules/unix-dgram/test/test-connect-callback.js +0 -68
- package/node_modules/unix-dgram/test/test-connect.js +0 -53
- package/node_modules/unix-dgram/test/test-dgram-unix.js +0 -58
- package/node_modules/unix-dgram/test/test-send-error.js +0 -26
- package/node_modules/winston-syslog/.eslintrc +0 -7
- package/node_modules/winston-syslog/.travis.yml +0 -14
- package/node_modules/winston-syslog/CHANGELOG.md +0 -9
- package/node_modules/winston-syslog/LICENSE +0 -20
- package/node_modules/winston-syslog/README.md +0 -135
- package/node_modules/winston-syslog/lib/utils.js +0 -26
- package/node_modules/winston-syslog/lib/winston-syslog.js +0 -385
- package/node_modules/winston-syslog/package.json +0 -56
- package/node_modules/winston-syslog/test/format-test.js +0 -122
- package/node_modules/winston-syslog/test/syslog-test.js +0 -95
- package/node_modules/winston-syslog/test/unix-connect-test.js +0 -133
|
@@ -30,14 +30,21 @@ const path = require('path');
|
|
|
30
30
|
*/
|
|
31
31
|
function splitString(str, win32) {
|
|
32
32
|
// windows treats both (forward and backward) slashes as separators
|
|
33
|
-
|
|
33
|
+
const posixRegEx = /(?=\/)/g;
|
|
34
|
+
const win32RegEx = /(?=[/\\])/g;
|
|
35
|
+
|
|
36
|
+
if (win32) {
|
|
37
|
+
str = str.replace(/\//g, '\\').split(win32RegEx);
|
|
38
|
+
} else {
|
|
39
|
+
str = str.split(posixRegEx);
|
|
40
|
+
}
|
|
34
41
|
if (str.length) {
|
|
35
42
|
// if there is an extension split it out.
|
|
36
43
|
const ix = str[str.length - 1].lastIndexOf('.');
|
|
37
44
|
if (ix > 0) {
|
|
38
45
|
const last = str[str.length - 1];
|
|
39
46
|
str[str.length - 1] = last.substr(0, ix);
|
|
40
|
-
str.push(last.substr(ix));
|
|
47
|
+
str.push(last.substr(ix + 1));
|
|
41
48
|
}
|
|
42
49
|
}
|
|
43
50
|
return str;
|
|
@@ -48,16 +55,25 @@ function splitString(str, win32) {
|
|
|
48
55
|
*
|
|
49
56
|
* @param {Object} meta object of metadata from result/arg
|
|
50
57
|
* @param {(segmentOffset: number) => boolean} meta.evaluator expression to determine the proper position of segment in string
|
|
51
|
-
* @param {number} meta.offset offset of full arg from result of path.resolve
|
|
52
58
|
* @param {string} meta.str result from path.resolve or arg
|
|
59
|
+
* @param {number} offset offset of full arg from result of path.resolve
|
|
53
60
|
* @param {string} segment path segment from one of the args to path.resolve
|
|
54
61
|
*/
|
|
55
|
-
function getSegmentOffset({ str,
|
|
62
|
+
function getSegmentOffset({ str, evaluator }, offset, segment, win32) {
|
|
56
63
|
// as the segments in each arg and in the result get traversed,
|
|
57
64
|
// winnow away the string to ensure we are finding the proper
|
|
58
65
|
// segment within the path
|
|
59
66
|
const substr = str.substring(offset);
|
|
60
|
-
|
|
67
|
+
let segmentOffset = substr.indexOf(segment);
|
|
68
|
+
// If tracking separators, evaluator will fail on extensions
|
|
69
|
+
if (substr === `.${segment}`) {
|
|
70
|
+
return segmentOffset + offset;
|
|
71
|
+
}
|
|
72
|
+
// Adjust offset if the segment does not start with a separator
|
|
73
|
+
const { sep } = path[win32 ? 'win32' : 'posix'];
|
|
74
|
+
if (substr.startsWith(sep) && !segment.startsWith(sep)) {
|
|
75
|
+
segmentOffset--;
|
|
76
|
+
}
|
|
61
77
|
|
|
62
78
|
return evaluator(segmentOffset) ? segmentOffset + offset : -1;
|
|
63
79
|
}
|
|
@@ -71,7 +87,12 @@ function getSegmentOffset({ str, offset, evaluator }, segment) {
|
|
|
71
87
|
*/
|
|
72
88
|
function isWithinTag(str, start, tag) {
|
|
73
89
|
const stop = str.length - 1 + start;
|
|
74
|
-
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
(stop <= tag.stop && stop >= tag.start) ||
|
|
93
|
+
(start >= tag.start && start <= tag.stop) ||
|
|
94
|
+
(tag.start >= start && tag.start <= stop)
|
|
95
|
+
);
|
|
75
96
|
}
|
|
76
97
|
|
|
77
98
|
/**
|
|
@@ -84,6 +105,7 @@ function isWithinTag(str, start, tag) {
|
|
|
84
105
|
*/
|
|
85
106
|
function adjustStart({ tag, argOffset, offset }) {
|
|
86
107
|
const start = tag.start - argOffset;
|
|
108
|
+
|
|
87
109
|
return start > 0 ? start + offset : offset;
|
|
88
110
|
}
|
|
89
111
|
|
|
@@ -135,15 +157,13 @@ function maybeUpdateResultMeta({ index, arg, resultMeta }) {
|
|
|
135
157
|
}
|
|
136
158
|
|
|
137
159
|
/**
|
|
138
|
-
*
|
|
160
|
+
* Calculates a new offset based on a segment
|
|
139
161
|
*
|
|
140
|
-
* @param {Object}
|
|
141
|
-
* @param {Object} argMeta metadata for a given argument
|
|
162
|
+
* @param {Object} offset offset of the object
|
|
142
163
|
* @param {string} segment path segment from one of the args to path.resolve
|
|
143
164
|
*/
|
|
144
|
-
function calculateNewOffset(
|
|
145
|
-
|
|
146
|
-
argMeta.offset = argMeta.offset + segment.length + 1;
|
|
165
|
+
function calculateNewOffset(offset, segment) {
|
|
166
|
+
return offset + segment.length;
|
|
147
167
|
}
|
|
148
168
|
|
|
149
169
|
/**
|
|
@@ -153,10 +173,89 @@ function calculateNewOffset(resultMeta, argMeta, segment) {
|
|
|
153
173
|
* @param {string} segment path segment to check
|
|
154
174
|
* @return {boolean}
|
|
155
175
|
*/
|
|
156
|
-
function
|
|
176
|
+
function isApplicableSegment(segment) {
|
|
157
177
|
return segment !== '.' && segment !== '..' && segment !== '';
|
|
158
178
|
}
|
|
159
179
|
|
|
180
|
+
/**
|
|
181
|
+
* Filters invalid segments like those that are not part of the end result.
|
|
182
|
+
* It also calculates additional offset.
|
|
183
|
+
*
|
|
184
|
+
* @param {*} segments splitted path into segments
|
|
185
|
+
* @param {Object} resultMeta metadata from result of path.resolve
|
|
186
|
+
* @param {Object} data the data object of the propagate function
|
|
187
|
+
* @param {number} index the iteration index
|
|
188
|
+
* @param {boolean} win32 indicating win32 to replace `/` with `\'
|
|
189
|
+
*/
|
|
190
|
+
function filterSegmentsAndCalculateOffset(
|
|
191
|
+
segments,
|
|
192
|
+
resultMeta,
|
|
193
|
+
data,
|
|
194
|
+
index,
|
|
195
|
+
win32
|
|
196
|
+
) {
|
|
197
|
+
const { sep } = path[win32 ? 'win32' : 'posix'];
|
|
198
|
+
const isFirstIteration = index === 0;
|
|
199
|
+
const validSegments = [];
|
|
200
|
+
let additionalOffset = 0;
|
|
201
|
+
|
|
202
|
+
segments.reduce(
|
|
203
|
+
// eslint-disable-next-line complexity
|
|
204
|
+
(accumulator, segment) => {
|
|
205
|
+
let hasChange = false;
|
|
206
|
+
if (!isApplicableSegment(segment)) return accumulator;
|
|
207
|
+
|
|
208
|
+
if (!accumulator.isModified && !isFirstIteration) {
|
|
209
|
+
const previousArg = data.args[index - 1];
|
|
210
|
+
|
|
211
|
+
const sepAdded = !segment.startsWith(sep) && !previousArg.endsWith(sep);
|
|
212
|
+
const sepTaken = segment.startsWith(sep) && previousArg.endsWith(sep);
|
|
213
|
+
accumulator.isModified = sepAdded || sepTaken;
|
|
214
|
+
hasChange = sepAdded || sepTaken;
|
|
215
|
+
additionalOffset = hasChange ? (sepAdded ? 1 : -1) : 0;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const offset = getSegmentOffset(
|
|
219
|
+
resultMeta,
|
|
220
|
+
accumulator.offset + additionalOffset + accumulator.fileDotSeparator,
|
|
221
|
+
segment,
|
|
222
|
+
win32
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
// no reason to proceed if segment is not in final result
|
|
226
|
+
if (offset === -1) {
|
|
227
|
+
if (hasChange) {
|
|
228
|
+
additionalOffset = 0;
|
|
229
|
+
accumulator.isModified = false;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return accumulator;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// in case we have a file we need to increment the offset
|
|
236
|
+
if (resultMeta.str[offset + segment.length] === '.') {
|
|
237
|
+
accumulator.fileDotSeparator = 1;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
validSegments.push(segment);
|
|
241
|
+
accumulator.offset = calculateNewOffset(accumulator.offset, segment);
|
|
242
|
+
accumulator.isModified = true;
|
|
243
|
+
|
|
244
|
+
return accumulator;
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
offset: resultMeta.offset,
|
|
248
|
+
fileDotSeparator: 0,
|
|
249
|
+
isModified: false
|
|
250
|
+
}
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
return {
|
|
254
|
+
additionalOffset,
|
|
255
|
+
segments: validSegments
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
160
259
|
/**
|
|
161
260
|
* Moves the tag ranges properly based on if a path segment exists in the
|
|
162
261
|
* result
|
|
@@ -164,42 +263,66 @@ function applicableSegment(segment) {
|
|
|
164
263
|
* @param {Object} resultMeta metadata for the result
|
|
165
264
|
* @param {Object} argMeta meta for a given argument
|
|
166
265
|
* @param {boolean} win32 indicating win32 to replace `/` with `\'
|
|
266
|
+
* @param {Object} data the data object of the propagate function
|
|
267
|
+
* @param {number} index the iteration index
|
|
167
268
|
*/
|
|
168
|
-
function adjustTagsToPart(resultMeta, argMeta, win32) {
|
|
269
|
+
function adjustTagsToPart(resultMeta, argMeta, win32, data, index) {
|
|
169
270
|
const { str, tagRanges } = argMeta;
|
|
170
|
-
const segments =
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
271
|
+
const { segments, additionalOffset } = filterSegmentsAndCalculateOffset(
|
|
272
|
+
splitString(str, win32),
|
|
273
|
+
resultMeta,
|
|
274
|
+
data,
|
|
275
|
+
index,
|
|
276
|
+
win32
|
|
277
|
+
);
|
|
176
278
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (offset === -1) {
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
279
|
+
// updating the offset
|
|
280
|
+
resultMeta.offset += additionalOffset;
|
|
182
281
|
|
|
183
|
-
|
|
282
|
+
return segments.reduce((newTags, segment) => {
|
|
283
|
+
const offset = getSegmentOffset(
|
|
284
|
+
resultMeta,
|
|
285
|
+
resultMeta.offset,
|
|
286
|
+
segment,
|
|
287
|
+
win32
|
|
288
|
+
);
|
|
184
289
|
|
|
185
|
-
|
|
290
|
+
const argOffset = getSegmentOffset(argMeta, argMeta.offset, segment, win32);
|
|
291
|
+
|
|
292
|
+
// updating the offset
|
|
293
|
+
resultMeta.offset = calculateNewOffset(resultMeta.offset, segment);
|
|
294
|
+
argMeta.offset = calculateNewOffset(argMeta.offset, segment);
|
|
295
|
+
|
|
296
|
+
// in case we have a file we need to increment the offset
|
|
297
|
+
if (resultMeta.str[offset + segment.length] === '.') {
|
|
298
|
+
resultMeta.offset += 1;
|
|
299
|
+
}
|
|
186
300
|
|
|
187
301
|
tagRanges.forEach((tag) => {
|
|
188
|
-
if (isWithinTag(segment, argOffset, tag))
|
|
189
|
-
const start = adjustStart({ tag, argOffset, offset });
|
|
190
|
-
const stop = adjustStop({ tag, argOffset, offset, segment });
|
|
302
|
+
if (!isWithinTag(segment, argOffset, tag)) return;
|
|
191
303
|
|
|
192
|
-
|
|
193
|
-
|
|
304
|
+
const start = adjustStart({
|
|
305
|
+
tag,
|
|
306
|
+
argOffset,
|
|
307
|
+
offset
|
|
308
|
+
});
|
|
309
|
+
const stop = adjustStop({
|
|
310
|
+
tag,
|
|
311
|
+
argOffset,
|
|
312
|
+
offset,
|
|
313
|
+
segment
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
newTags.push(new TagRange(start, stop, tag.tag));
|
|
194
317
|
});
|
|
195
|
-
});
|
|
196
318
|
|
|
197
|
-
|
|
319
|
+
return newTags;
|
|
320
|
+
}, []);
|
|
198
321
|
}
|
|
199
322
|
|
|
200
323
|
function propagate({ resultMeta, data, win32 }) {
|
|
201
324
|
if (!resultMeta.evaluator) {
|
|
202
|
-
resultMeta.evaluator = (segmentOffset) => segmentOffset ===
|
|
325
|
+
resultMeta.evaluator = (segmentOffset) => segmentOffset === 0;
|
|
203
326
|
}
|
|
204
327
|
|
|
205
328
|
data.args.forEach((arg, index) => {
|
|
@@ -213,7 +336,13 @@ function propagate({ resultMeta, data, win32 }) {
|
|
|
213
336
|
tagRanges: argData.tracked ? argData.tagRanges : []
|
|
214
337
|
};
|
|
215
338
|
|
|
216
|
-
const targetTagRanges = adjustTagsToPart(
|
|
339
|
+
const targetTagRanges = adjustTagsToPart(
|
|
340
|
+
resultMeta,
|
|
341
|
+
argMeta,
|
|
342
|
+
win32,
|
|
343
|
+
data,
|
|
344
|
+
index
|
|
345
|
+
);
|
|
217
346
|
|
|
218
347
|
if (targetTagRanges.length > 0) {
|
|
219
348
|
resultMeta.parents.push(argData.event);
|
|
@@ -31,7 +31,11 @@ function hookPath(path) {
|
|
|
31
31
|
resultMeta.offset = 0;
|
|
32
32
|
resultMeta.evaluator = (segmentOffset) => segmentOffset === 0;
|
|
33
33
|
}
|
|
34
|
-
propagate({
|
|
34
|
+
propagate({
|
|
35
|
+
data,
|
|
36
|
+
resultMeta,
|
|
37
|
+
win32: os === 'win32'
|
|
38
|
+
});
|
|
35
39
|
}
|
|
36
40
|
});
|
|
37
41
|
}
|
|
@@ -43,7 +43,11 @@ module.exports.handle = function handle() {
|
|
|
43
43
|
resultMeta.evaluator = (segmentOffset) => segmentOffset > -1;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
propagate({
|
|
46
|
+
propagate({
|
|
47
|
+
resultMeta,
|
|
48
|
+
data,
|
|
49
|
+
win32: os === 'win32'
|
|
50
|
+
});
|
|
47
51
|
}
|
|
48
52
|
});
|
|
49
53
|
}
|
|
@@ -34,7 +34,12 @@ module.exports.handle = function handle() {
|
|
|
34
34
|
if (!data.args[0]) return;
|
|
35
35
|
const resultMeta = getResultMeta(data, 'resolve');
|
|
36
36
|
const isAbsolute = absolutePath(data.args[0]);
|
|
37
|
-
|
|
37
|
+
|
|
38
|
+
/*
|
|
39
|
+
plus one in case isAbsolute is false since our working deretory ends without slash
|
|
40
|
+
example: /Users/John/Documents/Projects/node-agent
|
|
41
|
+
*/
|
|
42
|
+
resultMeta.offset = isAbsolute ? 0 : process.cwd().length + 1;
|
|
38
43
|
|
|
39
44
|
// a work-around for paths like C:\Windows
|
|
40
45
|
if (
|
|
@@ -45,7 +50,11 @@ module.exports.handle = function handle() {
|
|
|
45
50
|
resultMeta.evaluator = (segmentOffset) => segmentOffset > -1;
|
|
46
51
|
}
|
|
47
52
|
|
|
48
|
-
propagate({
|
|
53
|
+
propagate({
|
|
54
|
+
data,
|
|
55
|
+
resultMeta,
|
|
56
|
+
win32: os === 'win32'
|
|
57
|
+
});
|
|
49
58
|
}
|
|
50
59
|
});
|
|
51
60
|
}
|
|
@@ -18,7 +18,6 @@ const agentEmitter = require('../../agent-emitter');
|
|
|
18
18
|
const { PATCH_TYPES } = require('../../constants');
|
|
19
19
|
const ModuleHook = require('../../hooks/require');
|
|
20
20
|
const patcher = require('../../hooks/patcher');
|
|
21
|
-
const _ = require('lodash');
|
|
22
21
|
|
|
23
22
|
ModuleHook.resolve({ name: 'aws-sdk' }, (AWS) => {
|
|
24
23
|
patcher.patch(AWS.DynamoDB.prototype, 'makeRequest', {
|
|
@@ -27,7 +26,7 @@ ModuleHook.resolve({ name: 'aws-sdk' }, (AWS) => {
|
|
|
27
26
|
alwaysRun: true,
|
|
28
27
|
post(ctx) {
|
|
29
28
|
try {
|
|
30
|
-
const endpoint =
|
|
29
|
+
const { endpoint } = this;
|
|
31
30
|
agentEmitter.emit('architectureComponent', {
|
|
32
31
|
vendor: 'DynamoDB',
|
|
33
32
|
url: new URL(`${endpoint.protocol}//${endpoint.hostname}`).toString(),
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Copyright: 2021 Contrast Security, Inc
|
|
3
|
+
Contact: support@contrastsecurity.com
|
|
4
|
+
License: Commercial
|
|
5
|
+
|
|
6
|
+
NOTICE: This Software and the patented inventions embodied within may only be
|
|
7
|
+
used as part of Contrast Security’s commercial offerings. Even though it is
|
|
8
|
+
made available through public repositories, use of this Software is subject to
|
|
9
|
+
the applicable End User Licensing Agreement found at
|
|
10
|
+
https://www.contrastsecurity.com/enduser-terms-0317a or as otherwise agreed
|
|
11
|
+
between Contrast Security and the End User. The Software may not be reverse
|
|
12
|
+
engineered, modified, repackaged, sold, redistributed or otherwise used in a
|
|
13
|
+
way not consistent with the End User License Agreement.
|
|
14
|
+
*/
|
|
15
|
+
'use strict';
|
|
16
|
+
const logger = require('../logger')('contrast:arch-component');
|
|
17
|
+
const agentEmitter = require('../../agent-emitter');
|
|
18
|
+
const { PATCH_TYPES } = require('../../constants');
|
|
19
|
+
const ModuleHook = require('../../hooks/require');
|
|
20
|
+
const patcher = require('../../hooks/patcher');
|
|
21
|
+
|
|
22
|
+
function emitArchitectureComponent(endpoint) {
|
|
23
|
+
agentEmitter.emit('architectureComponent', {
|
|
24
|
+
vendor: 'DynamoDB',
|
|
25
|
+
url: new URL(`${endpoint.protocol}//${endpoint.hostname}`).toString(),
|
|
26
|
+
remoteHost: '',
|
|
27
|
+
remotePort: endpoint.port
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
ModuleHook.resolve({ name: '@aws-sdk/client-dynamodb' }, (AWS) => {
|
|
32
|
+
patcher.patch(AWS.DynamoDBClient.prototype, 'send', {
|
|
33
|
+
name: 'DynamoDBv3.arch_component',
|
|
34
|
+
patchType: PATCH_TYPES.ARCH_COMPONENT,
|
|
35
|
+
alwaysRun: true,
|
|
36
|
+
post(ctx) {
|
|
37
|
+
try {
|
|
38
|
+
this.config.endpoint().then(emitArchitectureComponent);
|
|
39
|
+
} catch (err) {
|
|
40
|
+
logger.warn('unable to report DynamoDB architecture component\n', err);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -23,6 +23,26 @@ module.exports = function() {
|
|
|
23
23
|
moduleHook.resolve({ name: 'bluebird' }, (bluebird) => {
|
|
24
24
|
module.exports.patchConfig(bluebird);
|
|
25
25
|
module.exports.patchAddCallbacks(bluebird);
|
|
26
|
+
module.exports.patchGetNewLibraryCopy(bluebird);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Ensures that new library copies are also instrumented.
|
|
32
|
+
* @param {function} bluebird the library export
|
|
33
|
+
*/
|
|
34
|
+
module.exports.patchGetNewLibraryCopy = function(bluebird) {
|
|
35
|
+
if (typeof bluebird.getNewLibraryCopy !== 'function') {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
patcher.patch(bluebird, 'getNewLibraryCopy', {
|
|
40
|
+
alwaysRun: true,
|
|
41
|
+
name: 'bluebird.getNewLibraryCopy',
|
|
42
|
+
patchType: PATCH_TYPES.ASYNC_CONTEXT,
|
|
43
|
+
post(data) {
|
|
44
|
+
module.exports.patchAddCallbacks(data.result);
|
|
45
|
+
}
|
|
26
46
|
});
|
|
27
47
|
};
|
|
28
48
|
|
|
@@ -481,9 +481,10 @@ const agent = [
|
|
|
481
481
|
{
|
|
482
482
|
name: 'agent.stack_trace_limit',
|
|
483
483
|
arg: '<limit>',
|
|
484
|
-
default:
|
|
484
|
+
default: 25,
|
|
485
485
|
fn: parseNum,
|
|
486
|
-
desc:
|
|
486
|
+
desc:
|
|
487
|
+
'set limit for stack trace size (larger limits will improve accuracy but increase memory usage)'
|
|
487
488
|
},
|
|
488
489
|
{
|
|
489
490
|
name: 'agent.polling.app_activity_ms',
|
|
@@ -273,7 +273,7 @@ const normalizeSegment = (segment) => {
|
|
|
273
273
|
}
|
|
274
274
|
}
|
|
275
275
|
} else if (segment instanceof RegExp) {
|
|
276
|
-
segment = segment.toString().replace(
|
|
276
|
+
segment = segment.toString().replace(/(^\/?)|(\/?$)/g, '');
|
|
277
277
|
segment = `/{${segment}}`;
|
|
278
278
|
} else if (Array.isArray(segment)) {
|
|
279
279
|
segment = segment.map((s) => `${normalizeSignatureArg(`${s}`)}`);
|
|
@@ -314,23 +314,21 @@ class DebugLogFactory {
|
|
|
314
314
|
};
|
|
315
315
|
|
|
316
316
|
[...levelNames, 'console'].forEach((level) => {
|
|
317
|
-
if (level
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
};
|
|
333
|
-
}
|
|
317
|
+
if (level === 'console') {
|
|
318
|
+
const orig = logger[level].bind(logger);
|
|
319
|
+
logger[level] = function(...args) {
|
|
320
|
+
return Scopes.runInNoInstrumentationScope(
|
|
321
|
+
() => orig(...args),
|
|
322
|
+
DEADZONE_NAME
|
|
323
|
+
);
|
|
324
|
+
};
|
|
325
|
+
} else {
|
|
326
|
+
logger[level] = function(message, ...splat) {
|
|
327
|
+
return Scopes.runInNoInstrumentationScope(
|
|
328
|
+
() => logger.log({ level, message, splat }),
|
|
329
|
+
DEADZONE_NAME
|
|
330
|
+
);
|
|
331
|
+
};
|
|
334
332
|
}
|
|
335
333
|
});
|
|
336
334
|
|
package/lib/core/stacktrace.js
CHANGED
|
@@ -15,13 +15,13 @@ Copyright: 2021 Contrast Security, Inc
|
|
|
15
15
|
'use strict';
|
|
16
16
|
|
|
17
17
|
const semver = require('semver');
|
|
18
|
+
const agent = require('../agent');
|
|
18
19
|
const process = require('process');
|
|
19
20
|
const sourceMap = require('../util/source-map');
|
|
20
21
|
const _isAgentPath = require('../util/is-agent-path');
|
|
21
22
|
|
|
22
|
-
const STACK_TRACE_LIMIT =
|
|
23
|
+
const STACK_TRACE_LIMIT = agent.config.agent.stack_trace_limit;
|
|
23
24
|
const EVAL_ORIGIN_REGEX = /\((.*?):(\d+):\d+\)/;
|
|
24
|
-
const EJS_EVAL_ORIGIN_REGEX = /(.*\.ejs$)/;
|
|
25
25
|
const EVENTS_FILE = semver.gte(process.version, '16.0.0')
|
|
26
26
|
? 'node:events'
|
|
27
27
|
: 'events.js';
|
|
@@ -146,8 +146,7 @@ class Factory {
|
|
|
146
146
|
if (callsite.isEval()) {
|
|
147
147
|
evalOrigin = Factory.formatFileName(callsite.getEvalOrigin());
|
|
148
148
|
[, file, lineNumber, columnNumber] =
|
|
149
|
-
evalOrigin.match(EVAL_ORIGIN_REGEX) ||
|
|
150
|
-
evalOrigin.match(EJS_EVAL_ORIGIN_REGEX);
|
|
149
|
+
evalOrigin.match(EVAL_ORIGIN_REGEX) || evalOrigin.endsWith('.ejs');
|
|
151
150
|
}
|
|
152
151
|
|
|
153
152
|
file = file || callsite.getFileName();
|
package/lib/feature-set.js
CHANGED
package/lib/hooks/encoding.js
CHANGED
|
@@ -31,7 +31,7 @@ module.exports = function() {
|
|
|
31
31
|
hardPatchEncoding(Buffer.prototype, 'Buffer', 'lastIndexOf', 0);
|
|
32
32
|
hardPatchEncoding(Buffer.prototype, 'Buffer', 'includes', 0);
|
|
33
33
|
|
|
34
|
-
hardPatchEncoding(Buffer, 'Buffer', 'alloc', 0
|
|
34
|
+
hardPatchEncoding(Buffer, 'Buffer', 'alloc', 0);
|
|
35
35
|
hardPatchEncoding(Buffer.prototype, 'Buffer', 'fill', 0);
|
|
36
36
|
};
|
|
37
37
|
|
|
@@ -22,8 +22,14 @@ const RequestFactory = require('../../reporter/models/utils/request-factory');
|
|
|
22
22
|
const CleanStack = require('../../util/clean-stack');
|
|
23
23
|
const agentEmitter = require('../../agent-emitter');
|
|
24
24
|
|
|
25
|
+
/** @typedef {import('../../agent').ContrastAgent} Agent */
|
|
26
|
+
|
|
25
27
|
class BaseFramework {
|
|
26
|
-
|
|
28
|
+
/**
|
|
29
|
+
* @param {Object} opts
|
|
30
|
+
* @param {string} opts.id
|
|
31
|
+
* @param {Agent} opts.agent
|
|
32
|
+
*/
|
|
27
33
|
constructor({ id, agent } = {}) {
|
|
28
34
|
this.id = id;
|
|
29
35
|
this.agent = agent;
|
|
@@ -46,7 +52,7 @@ class BaseFramework {
|
|
|
46
52
|
* -- Note --
|
|
47
53
|
* The current imlementation uses a CleanStack instance in order to generate
|
|
48
54
|
* a stackframe from which to obtain the information. This can be expensive.
|
|
49
|
-
* @returns {
|
|
55
|
+
* @returns {string}
|
|
50
56
|
*/
|
|
51
57
|
getAppCodeLocation() {
|
|
52
58
|
const limit = Error.stackTraceLimit;
|
|
@@ -19,39 +19,41 @@ const moduleHook = require('../require');
|
|
|
19
19
|
const patcher = require('../patcher');
|
|
20
20
|
const { HTTP_EVENTS, PATCH_TYPES } = require('../../constants');
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
super({ id, agent });
|
|
25
|
-
|
|
26
|
-
this.init();
|
|
27
|
-
}
|
|
22
|
+
/** @typedef {import('../../agent').ContrastAgent} Agent */
|
|
23
|
+
/** @typedef {import('net').Server} Server */
|
|
28
24
|
|
|
25
|
+
class HttpFramework extends BaseFramework {
|
|
29
26
|
/**
|
|
30
|
-
*
|
|
27
|
+
* @param {Agent} agent
|
|
28
|
+
* @param {string} id
|
|
31
29
|
*/
|
|
32
|
-
|
|
30
|
+
constructor(agent, id = 'http') {
|
|
31
|
+
super({ agent, id });
|
|
33
32
|
moduleHook.resolve({ name: this.id }, this.onRequire.bind(this));
|
|
34
33
|
}
|
|
35
34
|
|
|
35
|
+
/**
|
|
36
|
+
* @template {import('http') | import('https')} T
|
|
37
|
+
* @param {T} xport
|
|
38
|
+
* @returns {T}
|
|
39
|
+
*/
|
|
36
40
|
onRequire(xport) {
|
|
37
|
-
const { id } = this;
|
|
38
|
-
|
|
39
41
|
patcher.patch(xport, 'Server', {
|
|
40
|
-
name: `${id}.Server`,
|
|
42
|
+
name: `${this.id}.Server`,
|
|
41
43
|
patchType: PATCH_TYPES.FRAMEWORK,
|
|
42
44
|
alwaysRun: true,
|
|
43
45
|
post: (fnData) => this.handleServerCreate(fnData.args, fnData.result)
|
|
44
46
|
});
|
|
45
47
|
|
|
46
48
|
patcher.patch(xport, 'createServer', {
|
|
47
|
-
name: `${id}.createServer`,
|
|
49
|
+
name: `${this.id}.createServer`,
|
|
48
50
|
patchType: PATCH_TYPES.FRAMEWORK,
|
|
49
51
|
alwaysRun: true,
|
|
50
52
|
post: (fnData) => this.handleServerCreate(fnData.args, fnData.result)
|
|
51
53
|
});
|
|
52
54
|
|
|
53
55
|
patcher.patch(xport.Server.prototype, 'listen', {
|
|
54
|
-
name: `${id}.Server.prototype`,
|
|
56
|
+
name: `${this.id}.Server.prototype`,
|
|
55
57
|
patchType: PATCH_TYPES.FRAMEWORK,
|
|
56
58
|
alwaysRun: true,
|
|
57
59
|
pre: (fnData) => this.handleServerListen(fnData.args, fnData.obj)
|
|
@@ -62,6 +64,7 @@ class HttpFramework extends BaseFramework {
|
|
|
62
64
|
|
|
63
65
|
/**
|
|
64
66
|
* Emits a listen event if one has not been pubished for the server instance.
|
|
67
|
+
* @param {any[]}
|
|
65
68
|
* @param {Server} server Server on which `listen` was called
|
|
66
69
|
*/
|
|
67
70
|
handleServerListen(args, server) {
|
|
@@ -70,12 +73,16 @@ class HttpFramework extends BaseFramework {
|
|
|
70
73
|
|
|
71
74
|
/**
|
|
72
75
|
* Emits a create event for the new Server instance.
|
|
73
|
-
* @param {
|
|
76
|
+
* @param {any[]} args The arguments passed to the Server constructor
|
|
74
77
|
* @param {Server} server The http Server instance
|
|
75
78
|
*/
|
|
76
79
|
handleServerCreate(args, server) {
|
|
77
|
-
const [
|
|
78
|
-
|
|
80
|
+
const [options] = args;
|
|
81
|
+
let [, handler] = args;
|
|
82
|
+
if (typeof options === 'function') {
|
|
83
|
+
handler = options;
|
|
84
|
+
}
|
|
85
|
+
this.emitter.emit(HTTP_EVENTS.SERVER_CREATE, handler, server);
|
|
79
86
|
}
|
|
80
87
|
}
|
|
81
88
|
|