@contrast/agentify 1.3.1 → 1.4.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/lib/contrast-methods.js +77 -24
- package/lib/function-hooks.js +1 -1
- package/lib/index.js +19 -14
- package/lib/rewrite-hooks.js +6 -1
- package/package.json +1 -1
package/lib/contrast-methods.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
'use strict';
|
|
17
17
|
|
|
18
|
-
module.exports = function(core) {
|
|
18
|
+
module.exports = function (core) {
|
|
19
19
|
const { logger, patcher } = core;
|
|
20
20
|
|
|
21
21
|
const getOrig = (v) => patcher.unwrap(v);
|
|
@@ -28,70 +28,123 @@ module.exports = function(core) {
|
|
|
28
28
|
* 2) patch those functions on `contrastMethods.api` in order to add instrumentation
|
|
29
29
|
*/
|
|
30
30
|
const contrastMethods = {
|
|
31
|
-
// TODO: Assess will require add'l methods
|
|
32
|
-
// TODO: ESM will require add'l methods
|
|
33
31
|
api: {
|
|
34
32
|
eval(v) {
|
|
35
33
|
return v;
|
|
36
34
|
},
|
|
37
|
-
|
|
35
|
+
|
|
36
|
+
// Binary Operators
|
|
37
|
+
add(left, right) {
|
|
38
38
|
const ret = getOrig(left) + getOrig(right);
|
|
39
39
|
return ret;
|
|
40
40
|
},
|
|
41
|
-
|
|
41
|
+
eqEq(left, right) {
|
|
42
42
|
left = getOrig(left);
|
|
43
43
|
right = getOrig(right);
|
|
44
44
|
|
|
45
45
|
return left == right;
|
|
46
46
|
},
|
|
47
|
-
|
|
47
|
+
eqEqEq(left, right) {
|
|
48
48
|
left = getOrig(left);
|
|
49
49
|
right = getOrig(right);
|
|
50
50
|
|
|
51
|
-
return left
|
|
51
|
+
return left === right;
|
|
52
52
|
},
|
|
53
|
-
|
|
53
|
+
notEqEq(left, right) {
|
|
54
54
|
left = getOrig(left);
|
|
55
55
|
right = getOrig(right);
|
|
56
56
|
|
|
57
|
-
return left
|
|
57
|
+
return left !== right;
|
|
58
58
|
},
|
|
59
|
-
|
|
59
|
+
notEq(left, right) {
|
|
60
60
|
left = getOrig(left);
|
|
61
61
|
right = getOrig(right);
|
|
62
62
|
|
|
63
63
|
return left != right;
|
|
64
64
|
},
|
|
65
|
+
|
|
66
|
+
// Computed Properties
|
|
67
|
+
// Used to force a copy of handle:
|
|
68
|
+
// https://stackoverflow.com/a/31733628
|
|
69
|
+
// This is a workaround for CONTRAST-30333, in which something we
|
|
70
|
+
// suspect is a v8 bug means that handle will otherwise be clobbered
|
|
71
|
+
// and if it was externalized, we will lose the data associated with it
|
|
65
72
|
forceCopy(handle) {
|
|
66
|
-
// Used to force a copy of handle:
|
|
67
|
-
// https://stackoverflow.com/a/31733628
|
|
68
|
-
// This is a workaround for CONTRAST-30333, in which something we
|
|
69
|
-
// suspect is a v8 bug means that handle will otherwise be clobbered
|
|
70
|
-
// and if it was externalized, we will lose the data associated with it
|
|
71
73
|
if (typeof handle === 'string') {
|
|
72
74
|
handle = toUntrackedString(handle);
|
|
73
75
|
}
|
|
74
76
|
return handle;
|
|
75
77
|
},
|
|
76
|
-
|
|
78
|
+
|
|
79
|
+
// Switch Case
|
|
80
|
+
cast(val) {
|
|
77
81
|
return getOrig(val);
|
|
78
82
|
},
|
|
79
|
-
|
|
80
|
-
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Tagged Templates
|
|
86
|
+
* The first argument received by the tag function is an array of strings.
|
|
87
|
+
* For any template literal, its length is equal to the number of
|
|
88
|
+
* substitutions (occurrences of ${...}) plus one, and is therefore always
|
|
89
|
+
* non-empty.
|
|
90
|
+
* see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates
|
|
91
|
+
* @param {string[]} strings length n+1
|
|
92
|
+
* @param {string[]} args length n
|
|
93
|
+
* @returns {string}
|
|
94
|
+
*/
|
|
95
|
+
tag(strings, ...args) {
|
|
96
|
+
const [first, ...rest] = strings;
|
|
97
|
+
|
|
98
|
+
return rest.reduce(
|
|
99
|
+
(result, str, i) => result.concat(args[i], str),
|
|
100
|
+
first,
|
|
101
|
+
);
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
// Import Statements
|
|
105
|
+
importDefault(...args) {
|
|
106
|
+
// noop
|
|
81
107
|
},
|
|
82
108
|
|
|
109
|
+
importStarAs(...args) {
|
|
110
|
+
// noop
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
importNamed(...args) {
|
|
114
|
+
// noop
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
// Injections
|
|
83
118
|
Function: core.patcher.patch(global.Function, {
|
|
84
119
|
name: 'global.Function',
|
|
85
|
-
patchType: 'rewrite-injection'
|
|
120
|
+
patchType: 'rewrite-injection',
|
|
121
|
+
}),
|
|
122
|
+
JSON: core.patcher.patch(global.JSON, {
|
|
123
|
+
name: 'global.JSON',
|
|
124
|
+
patchType: 'rewrite-injection',
|
|
125
|
+
}),
|
|
126
|
+
Number: core.patcher.patch(global.Number, {
|
|
127
|
+
name: 'global.Number',
|
|
128
|
+
patchType: 'rewrite-injection',
|
|
129
|
+
}),
|
|
130
|
+
Object: core.patcher.patch(global.Object, {
|
|
131
|
+
name: 'global.Object',
|
|
132
|
+
patchType: 'rewrite-injection',
|
|
133
|
+
}),
|
|
134
|
+
String: core.patcher.patch(global.String, {
|
|
135
|
+
name: 'global.String',
|
|
136
|
+
patchType: 'rewrite-injection',
|
|
86
137
|
}),
|
|
87
138
|
},
|
|
139
|
+
|
|
88
140
|
installed: false,
|
|
141
|
+
|
|
89
142
|
getGlobal() {
|
|
90
143
|
return global;
|
|
91
|
-
}
|
|
144
|
+
},
|
|
92
145
|
};
|
|
93
146
|
|
|
94
|
-
contrastMethods.install = function() {
|
|
147
|
+
contrastMethods.install = function () {
|
|
95
148
|
if (contrastMethods.installed) {
|
|
96
149
|
return;
|
|
97
150
|
}
|
|
@@ -102,15 +155,15 @@ module.exports = function(core) {
|
|
|
102
155
|
Object.defineProperty(global, 'ContrastMethods', {
|
|
103
156
|
enumerable: true,
|
|
104
157
|
configurable: false,
|
|
105
|
-
value: contrastMethods.api
|
|
158
|
+
value: contrastMethods.api,
|
|
106
159
|
});
|
|
107
160
|
contrastMethods.installed = true;
|
|
108
161
|
} catch (err) {
|
|
109
162
|
// We should never expect this since the installation process is well
|
|
110
163
|
// controlled, but still we should have the defensive code.
|
|
111
|
-
logger.error({ err }, 'Unable to
|
|
164
|
+
logger.error({ err }, 'Unable to inject global.ContrastMethods');
|
|
112
165
|
}
|
|
113
166
|
};
|
|
114
167
|
|
|
115
|
-
return core.contrastMethods = contrastMethods;
|
|
168
|
+
return (core.contrastMethods = contrastMethods);
|
|
116
169
|
};
|
package/lib/function-hooks.js
CHANGED
|
@@ -81,7 +81,7 @@ module.exports = function (deps) {
|
|
|
81
81
|
unwritten = rewriter.unwrite(unwritten);
|
|
82
82
|
unwritten = unwritten.replace(METHOD_CONTEXT, '');
|
|
83
83
|
unwritten = unwritten.replace(FUNCTION_CONTEXT, '');
|
|
84
|
-
unwritten = unwritten.replace(
|
|
84
|
+
unwritten = unwritten.replace(/;\s*$/, ''); // removes trailing semicolon/whitespace
|
|
85
85
|
return unwritten;
|
|
86
86
|
} catch (err) {
|
|
87
87
|
logger.warn({ err, code }, 'Failed to unwrite function code');
|
package/lib/index.js
CHANGED
|
@@ -31,7 +31,8 @@ const defaultOpts = {
|
|
|
31
31
|
'assess',
|
|
32
32
|
'protect',
|
|
33
33
|
'depHooks',
|
|
34
|
-
'
|
|
34
|
+
'routeCoverage',
|
|
35
|
+
'libraryAnalysis',
|
|
35
36
|
'rewriteHooks',
|
|
36
37
|
'functionHooks'
|
|
37
38
|
]
|
|
@@ -106,7 +107,7 @@ class Agent {
|
|
|
106
107
|
await self.handleInstallFailure(err);
|
|
107
108
|
}
|
|
108
109
|
|
|
109
|
-
self.
|
|
110
|
+
self.logDiagnosticFiles();
|
|
110
111
|
return self.runMain.apply(this, args);
|
|
111
112
|
};
|
|
112
113
|
}
|
|
@@ -135,29 +136,33 @@ class Agent {
|
|
|
135
136
|
}
|
|
136
137
|
}
|
|
137
138
|
|
|
138
|
-
|
|
139
|
-
const { config, getEffectiveConfig } = this.core;
|
|
139
|
+
logDiagnosticFiles() {
|
|
140
|
+
const { config, getEffectiveConfig, getSystemInfo } = this.core;
|
|
140
141
|
|
|
141
|
-
if (config.
|
|
142
|
-
const
|
|
142
|
+
if (config.agent.diagnostics.enable !== false) {
|
|
143
|
+
const effectiveConfig = JSON.stringify(getEffectiveConfig(), null, 2).concat('\n\n');
|
|
144
|
+
const systemInfo = JSON.stringify(getSystemInfo(), null, 2).concat('\n\n');
|
|
143
145
|
|
|
144
|
-
if (config.
|
|
145
|
-
fs.writeFileSync(1,
|
|
146
|
+
if (!config.agent.diagnostics.quiet) {
|
|
147
|
+
fs.writeFileSync(1, effectiveConfig, 'utf8');
|
|
148
|
+
fs.writeFileSync(1, systemInfo, 'utf8');
|
|
146
149
|
}
|
|
147
150
|
|
|
148
|
-
let outputDir = config.
|
|
151
|
+
let outputDir = config.agent.diagnostics.report_path;
|
|
149
152
|
if (!outputDir && config.agent.logger.path) {
|
|
150
|
-
outputDir = path.join(config.agent.logger.path, '
|
|
153
|
+
outputDir = path.join(config.agent.logger.path, '..');
|
|
151
154
|
}
|
|
152
155
|
|
|
153
156
|
try {
|
|
154
|
-
fs.writeFileSync(outputDir,
|
|
157
|
+
fs.writeFileSync(path.join(outputDir, 'contrast_effective_config.json'), effectiveConfig, 'utf-8');
|
|
158
|
+
fs.writeFileSync(path.join(outputDir, 'contrast_system_info.json'), systemInfo, 'utf-8');
|
|
155
159
|
} catch (err) {
|
|
156
|
-
outputDir = path.join(process.cwd()
|
|
160
|
+
outputDir = path.join(process.cwd());
|
|
157
161
|
try {
|
|
158
|
-
fs.writeFileSync(outputDir,
|
|
162
|
+
fs.writeFileSync(path.join(outputDir, 'contrast_effective_config.json'), effectiveConfig, 'utf-8');
|
|
163
|
+
fs.writeFileSync(path.join(outputDir, 'contrast_system_info.json'), systemInfo, 'utf-8');
|
|
159
164
|
} catch (err) {
|
|
160
|
-
fs.writeFileSync(1, `Couldn't create
|
|
165
|
+
fs.writeFileSync(1, `Couldn't create the diagnostic files: ${err}`, 'utf-8');
|
|
161
166
|
}
|
|
162
167
|
}
|
|
163
168
|
}
|
package/lib/rewrite-hooks.js
CHANGED
|
@@ -27,7 +27,12 @@ module.exports = function(deps) {
|
|
|
27
27
|
|
|
28
28
|
Module.prototype._compile = function(content, filename) {
|
|
29
29
|
let compiled;
|
|
30
|
-
const { code } = deps.rewriter.rewrite(content, {
|
|
30
|
+
const { code } = deps.rewriter.rewrite(content, {
|
|
31
|
+
filename,
|
|
32
|
+
isModule: false,
|
|
33
|
+
inject: true,
|
|
34
|
+
wrap: true,
|
|
35
|
+
});
|
|
31
36
|
|
|
32
37
|
try {
|
|
33
38
|
compiled = origCompile.call(this, code, filename);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrast/agentify",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Configures Contrast agent services and instrumentation within an application",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",
|