@contrast/agent 4.25.6-beta.0 → 4.27.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/bootstrap.js +7 -0
- package/config-diagnostics.js +130 -0
- package/lib/assess/models/call-context.js +26 -2
- package/lib/assess/models/index.js +2 -0
- package/lib/contrast.js +29 -8
- package/lib/core/config/options.js +7 -0
- package/lib/util/config-diagnostics-utils.js +221 -0
- package/package.json +7 -5
package/bootstrap.js
CHANGED
|
@@ -41,6 +41,13 @@ Module.runMain = async function (...args) {
|
|
|
41
41
|
await loader.bootstrap(process.argv);
|
|
42
42
|
}
|
|
43
43
|
await loader.resetArgs(process.argv[0], process.argv[1]);
|
|
44
|
+
|
|
45
|
+
const diagnostics = process.env['CONTRAST__AGENT__DIAGNOSTICS__ENABLE'];
|
|
46
|
+
if (diagnostics === 'true') {
|
|
47
|
+
// eslint-disable-next-line no-process-exit
|
|
48
|
+
process.exit(0);
|
|
49
|
+
}
|
|
50
|
+
|
|
44
51
|
loader.logTime(startTime, 'agent');
|
|
45
52
|
const appStartTime = process.hrtime();
|
|
46
53
|
orig.apply(this, args);
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
Copyright: 2022 Contrast Security, Inc
|
|
4
|
+
Contact: support@contrastsecurity.com
|
|
5
|
+
License: Commercial
|
|
6
|
+
|
|
7
|
+
NOTICE: This Software and the patented inventions embodied within may only be
|
|
8
|
+
used as part of Contrast Security’s commercial offerings. Even though it is
|
|
9
|
+
made available through public repositories, use of this Software is subject to
|
|
10
|
+
the applicable End User Licensing Agreement found at
|
|
11
|
+
https://www.contrastsecurity.com/enduser-terms-0317a or as otherwise agreed
|
|
12
|
+
between Contrast Security and the End User. The Software may not be reverse
|
|
13
|
+
engineered, modified, repackaged, sold, redistributed or otherwise used in a
|
|
14
|
+
way not consistent with the End User License Agreement.
|
|
15
|
+
*/
|
|
16
|
+
'use strict';
|
|
17
|
+
|
|
18
|
+
const { exec } = require('child_process');
|
|
19
|
+
|
|
20
|
+
function handleDependentParameter(args, currParameter, nextParameter) {
|
|
21
|
+
switch (currParameter) {
|
|
22
|
+
case '--output':
|
|
23
|
+
case '-o':
|
|
24
|
+
args.output = nextParameter;
|
|
25
|
+
break;
|
|
26
|
+
default:
|
|
27
|
+
throw new Error(`Invalid parameter ${currParameter}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function handleIndependentParameter(args, parameter) {
|
|
32
|
+
switch (parameter) {
|
|
33
|
+
case '--help':
|
|
34
|
+
args.help = true;
|
|
35
|
+
break;
|
|
36
|
+
case '--quiet':
|
|
37
|
+
case '-q':
|
|
38
|
+
args.quiet = true;
|
|
39
|
+
break;
|
|
40
|
+
default:
|
|
41
|
+
throw new Error(`Invalid parameter ${parameter}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function printHelpMessage() {
|
|
46
|
+
console.log(
|
|
47
|
+
'\nDescription:\n' +
|
|
48
|
+
'The config-diagnostics utility returns the current effective node agent configuration\n' +
|
|
49
|
+
'\nUsage:\n' +
|
|
50
|
+
'npx -p @contrast/agent config-diagnostics <path/to/entry/script> [options]\n' +
|
|
51
|
+
'npx -p @contrast/agent config-diagnostics --help\n' +
|
|
52
|
+
'\nOptions:\n' +
|
|
53
|
+
'--quiet -q Prevents output of the report to the console.\n' +
|
|
54
|
+
'--output -o The directory to write the report in. Defaults to the current directory.\n'
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function parseArgv() {
|
|
59
|
+
const argv = process.argv.slice(2);
|
|
60
|
+
const args = {
|
|
61
|
+
output: 'contrast_effective_config.json',
|
|
62
|
+
quiet: false,
|
|
63
|
+
help: false,
|
|
64
|
+
};
|
|
65
|
+
let currParameter = null;
|
|
66
|
+
|
|
67
|
+
for (let i = 0; i < argv.length; i++) {
|
|
68
|
+
if (!currParameter) {
|
|
69
|
+
currParameter = argv[i];
|
|
70
|
+
}
|
|
71
|
+
if (!(currParameter.startsWith('--') || currParameter.startsWith('-'))) {
|
|
72
|
+
currParameter = null;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (i + 1 == argv.length || argv[i + 1].startsWith('--') || argv[i + 1].startsWith('-')) {
|
|
77
|
+
handleIndependentParameter(args, currParameter);
|
|
78
|
+
currParameter = null;
|
|
79
|
+
} else {
|
|
80
|
+
handleDependentParameter(args, currParameter, argv[i + 1]);
|
|
81
|
+
currParameter = null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return args;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function executeNodeAgent(args) {
|
|
89
|
+
let agentEnvArgs = 'CONTRAST__SHOW__BANNER=false CONTRAST__AGENT__DIAGNOSTICS__ENABLE=true';
|
|
90
|
+
const entry = process.argv.slice(2).shift();
|
|
91
|
+
|
|
92
|
+
if (!args.quiet) {
|
|
93
|
+
agentEnvArgs = agentEnvArgs.concat(' CONTRAST__AGENT__DIAGNOSTICS__QUIET=false');
|
|
94
|
+
}
|
|
95
|
+
if (args.output) {
|
|
96
|
+
agentEnvArgs = agentEnvArgs.concat(` CONTRAST__AGENT__DIAGNOSTICS__REPORT_PATH=${args.output}`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
exec(`${agentEnvArgs} node -r ./node_modules/@contrast/agent/bootstrap.js ${entry}`,
|
|
100
|
+
(error, stdout, stderr) => {
|
|
101
|
+
if (error && !args.quiet) {
|
|
102
|
+
console.log(`error: ${error.message}`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// by default errors still won't be visible since stdout == sterr
|
|
107
|
+
if (stderr) {
|
|
108
|
+
console.log(`stderr: ${stderr}`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (!args.quiet) {
|
|
113
|
+
console.log(stdout);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function fetchAgentConfig(args) {
|
|
120
|
+
if (process.argv.slice(2).length == 1 && args.help) {
|
|
121
|
+
printHelpMessage();
|
|
122
|
+
} else {
|
|
123
|
+
executeNodeAgent(args);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
fetchAgentConfig(parseArgv());
|
|
129
|
+
// exporting this stuff for testing purposes only
|
|
130
|
+
module.exports = { printHelpMessage, parseArgv, executeNodeAgent, fetchAgentConfig };
|
|
@@ -21,6 +21,7 @@ const stackFactory = require('../../core/stacktrace').singleton;
|
|
|
21
21
|
const { PROXY_TARGET } = require('../../../lib/constants');
|
|
22
22
|
const TagRange = require('../models/tag-range');
|
|
23
23
|
const distringuish = require('@contrast/distringuish');
|
|
24
|
+
const agent = require('../../agent');
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* Holds information about the call context of a function
|
|
@@ -153,13 +154,36 @@ function valueString(value) {
|
|
|
153
154
|
return type;
|
|
154
155
|
}
|
|
155
156
|
|
|
156
|
-
|
|
157
|
+
const appendStack = agent.config.assess.enable_lazy_stacktraces ?
|
|
158
|
+
(instance, snapshot) => {
|
|
159
|
+
let stack;
|
|
160
|
+
// This enables the lazy generation of a stacktrace which is a performance
|
|
161
|
+
// improvement, but the snapshot method call is in a closure which creates
|
|
162
|
+
// a memory leak in longer running tests
|
|
163
|
+
Object.defineProperty(instance, 'stack', {
|
|
164
|
+
enumerable: true,
|
|
165
|
+
configurable: true,
|
|
166
|
+
get() {
|
|
167
|
+
if (!stack) {
|
|
168
|
+
stack = snapshot();
|
|
169
|
+
}
|
|
170
|
+
return stack;
|
|
171
|
+
},
|
|
172
|
+
set(value) {
|
|
173
|
+
stack = value;
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
} : (instance, snapshot) => {
|
|
177
|
+
instance.stack = snapshot();
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
function create (params) {
|
|
157
181
|
const instance = new CallContext(params);
|
|
158
182
|
const snapshot = params.stacktrace || stackFactory.createSnapshot({
|
|
159
183
|
constructorOpt: params.hooked
|
|
160
184
|
});
|
|
161
185
|
|
|
162
|
-
instance
|
|
186
|
+
appendStack(instance, snapshot);
|
|
163
187
|
|
|
164
188
|
return instance;
|
|
165
189
|
}
|
|
@@ -12,6 +12,8 @@ Copyright: 2022 Contrast Security, Inc
|
|
|
12
12
|
engineered, modified, repackaged, sold, redistributed or otherwise used in a
|
|
13
13
|
way not consistent with the End User License Agreement.
|
|
14
14
|
*/
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
15
17
|
const CallContext = require('./call-context');
|
|
16
18
|
const Signature = require('./signature');
|
|
17
19
|
const BaseEvent = require('./base-event');
|
package/lib/contrast.js
CHANGED
|
@@ -14,7 +14,7 @@ Copyright: 2022 Contrast Security, Inc
|
|
|
14
14
|
*/
|
|
15
15
|
'use strict';
|
|
16
16
|
|
|
17
|
-
const { program } = require('./core/config/options');
|
|
17
|
+
const { program, options } = require('./core/config/options');
|
|
18
18
|
const path = require('path');
|
|
19
19
|
const os = require('os');
|
|
20
20
|
const semver = require('semver');
|
|
@@ -25,6 +25,7 @@ const Module = require('module');
|
|
|
25
25
|
const sourceMapUtility = require('./util/source-map');
|
|
26
26
|
const loggerFactory = require('./core/logger');
|
|
27
27
|
const logger = loggerFactory('contrast:contrast-init');
|
|
28
|
+
const { outputAgentConfigFile } = require('./util/config-diagnostics-utils');
|
|
28
29
|
|
|
29
30
|
function getAgentSnippet() {
|
|
30
31
|
// getting reference to name every time for testing purposes
|
|
@@ -59,9 +60,12 @@ contrastAgent.showBanner = function showBanner() {
|
|
|
59
60
|
console.log(colors.red(cat));
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
const showAgentBanner = (process.env['CONTRAST__SHOW__BANNER'] === 'false') ? false : true;
|
|
64
|
+
if (showAgentBanner) {
|
|
65
|
+
logger.console();
|
|
66
|
+
logger.console('%s %s', NAME, VERSION);
|
|
67
|
+
logger.console(colors.green('--------------------------------------'));
|
|
68
|
+
}
|
|
65
69
|
};
|
|
66
70
|
|
|
67
71
|
/**
|
|
@@ -284,18 +288,16 @@ contrastAgent.prepare = function(...args) {
|
|
|
284
288
|
|
|
285
289
|
/**
|
|
286
290
|
* Sends startup message to TeamServer then instruments user code
|
|
287
|
-
*
|
|
288
291
|
* @param {Array} args process.argv
|
|
289
292
|
*/
|
|
290
293
|
contrastAgent.bootstrap = function(args) {
|
|
291
294
|
const reporter = new TSReporter(agent);
|
|
295
|
+
|
|
292
296
|
// returning promise for testing purposes only
|
|
293
297
|
return reporter
|
|
294
298
|
.onboard(args)
|
|
295
299
|
.catch((err) => {
|
|
296
|
-
logger.error(
|
|
297
|
-
'Reporter onboarding failed. Continuing without instrumentation.'
|
|
298
|
-
);
|
|
300
|
+
logger.error('Reporter onboarding failed. Continuing without instrumentation.');
|
|
299
301
|
logger.error(err);
|
|
300
302
|
agent.clearIntervals();
|
|
301
303
|
return;
|
|
@@ -314,6 +316,25 @@ contrastAgent.bootstrap = function(args) {
|
|
|
314
316
|
'Unexpected error while trying to start contrast. Continuing without instrumentation. Error: %o',
|
|
315
317
|
err
|
|
316
318
|
);
|
|
319
|
+
})
|
|
320
|
+
.finally(async () => {
|
|
321
|
+
let destination = process.env['CONTRAST__AGENT__DIAGNOSTICS__REPORT_PATH'];
|
|
322
|
+
if (destination == null) {
|
|
323
|
+
destination = agent.config._flat['agent.logger.path'].split('/');
|
|
324
|
+
destination.pop() && destination.push('contrast_effective_config.json');
|
|
325
|
+
destination = destination.join('/');
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const args = {
|
|
329
|
+
quiet: (process.env['CONTRAST__AGENT__DIAGNOSTICS__QUIET'] === 'false') ? false : true,
|
|
330
|
+
output: destination,
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
try {
|
|
334
|
+
outputAgentConfigFile(agent, options, args, null);
|
|
335
|
+
} catch (err) {
|
|
336
|
+
outputAgentConfigFile(agent, options, args, err);
|
|
337
|
+
}
|
|
317
338
|
});
|
|
318
339
|
};
|
|
319
340
|
|
|
@@ -761,6 +761,13 @@ const assess = [
|
|
|
761
761
|
fn: castBoolean,
|
|
762
762
|
desc: 'When set to `false` won\'t track the source events lazily but will track the first up to 250 source events',
|
|
763
763
|
},
|
|
764
|
+
{
|
|
765
|
+
name: 'assess.enable_lazy_stacktraces',
|
|
766
|
+
arg: '[false]',
|
|
767
|
+
default: false,
|
|
768
|
+
fn: castBoolean,
|
|
769
|
+
desc: 'When set to `true` it will evaluate stacktraces lazily, this improves performance, but causes a memory leak if used in a longer running application',
|
|
770
|
+
},
|
|
764
771
|
];
|
|
765
772
|
|
|
766
773
|
const protect = [
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Copyright: 2022 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
|
+
|
|
17
|
+
const path = require('path');
|
|
18
|
+
const fs = require('fs');
|
|
19
|
+
|
|
20
|
+
// eslint-disable-next-line complexity
|
|
21
|
+
function getLoggerValues(option, config, tsData) {
|
|
22
|
+
let tsValue, effectiveValue = config._flat[option.name];
|
|
23
|
+
|
|
24
|
+
switch (option.name) {
|
|
25
|
+
case 'agent.logger.level':
|
|
26
|
+
tsValue = tsData.logLevel;
|
|
27
|
+
break;
|
|
28
|
+
case 'agent.logger.path':
|
|
29
|
+
tsValue = tsData.logFile;
|
|
30
|
+
break;
|
|
31
|
+
case 'agent.security_logger.syslog.enable':
|
|
32
|
+
tsValue = tsData.defend.syslog.enabled;
|
|
33
|
+
break;
|
|
34
|
+
case 'agent.security_logger.syslog.ip':
|
|
35
|
+
tsValue = tsData.defend.syslog.ipAddress;
|
|
36
|
+
break;
|
|
37
|
+
case 'agent.security_logger.syslog.port':
|
|
38
|
+
tsValue = tsData.defend.syslog.port;
|
|
39
|
+
break;
|
|
40
|
+
case 'agent.security_logger.syslog.fascility':
|
|
41
|
+
tsValue = tsData.defend.syslog.fascilityCode;
|
|
42
|
+
break;
|
|
43
|
+
case 'agent.security_logger.syslog.severity_exploited':
|
|
44
|
+
tsValue = tsData.defend.syslog.severityExploited;
|
|
45
|
+
break;
|
|
46
|
+
case 'agent.security_logger.syslog.severity_blocked':
|
|
47
|
+
tsValue = tsData.defend.syslog.severityBlocked;
|
|
48
|
+
break;
|
|
49
|
+
case 'agent.security_logger.syslog.severity_probed':
|
|
50
|
+
tsValue = tsData.defend.syslog.severityProbed;
|
|
51
|
+
break;
|
|
52
|
+
default:
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (config._sources[option.name] == 'DEFAULT' && tsValue != null) {
|
|
57
|
+
effectiveValue = tsValue;
|
|
58
|
+
config._sources[option.name] = 'ContrastUI';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
CanonicalName: option.name,
|
|
63
|
+
Name: option.name,
|
|
64
|
+
Value: effectiveValue,
|
|
65
|
+
Source: config._sources[option.name],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function getAssessValues(option, config, tsData) {
|
|
70
|
+
let tsValue, effectiveValue = config._flat[option.name];
|
|
71
|
+
|
|
72
|
+
switch (option.name) {
|
|
73
|
+
case 'assess.enable':
|
|
74
|
+
tsValue = tsData.assess.enabled;
|
|
75
|
+
break;
|
|
76
|
+
case 'assess.enable_propagators':
|
|
77
|
+
tsValue = tsData.assess.propagators;
|
|
78
|
+
break;
|
|
79
|
+
case 'assess.sampling.enable':
|
|
80
|
+
tsValue = tsData.assess.sampling;
|
|
81
|
+
break;
|
|
82
|
+
default:
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (config._sources[option.name] == 'DEFAULT' && tsValue != null) {
|
|
87
|
+
effectiveValue = tsValue;
|
|
88
|
+
config._sources[option.name] = 'ContrastUI';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
CanonicalName: option.name,
|
|
93
|
+
Name: option.name,
|
|
94
|
+
Value: effectiveValue,
|
|
95
|
+
Source: config._sources[option.name],
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function getProtectValues(option, config, tsData) {
|
|
100
|
+
let value = {};
|
|
101
|
+
|
|
102
|
+
if (option.name.includes('ip-denylist')) {
|
|
103
|
+
value = {
|
|
104
|
+
CanonicalName: option.name.split('.')[2],
|
|
105
|
+
Name: option.name,
|
|
106
|
+
Value: tsData.ipDenylistsList,
|
|
107
|
+
Source: 'ContrastUI',
|
|
108
|
+
};
|
|
109
|
+
} else if (option.name.includes('virtual-patch')) {
|
|
110
|
+
value = {
|
|
111
|
+
CanonicalName: option.name.split('.')[2],
|
|
112
|
+
Name: option.name,
|
|
113
|
+
Value: tsData.virtualPatchesList,
|
|
114
|
+
Source: 'ContrastUI',
|
|
115
|
+
};
|
|
116
|
+
} else if (option.name.includes('protect.rules') && option.name.includes('mode')) {
|
|
117
|
+
const apiRule = tsData.protectionRulesList.find(r => r.id == option.name.split('.')[2]);
|
|
118
|
+
|
|
119
|
+
const apiMode = apiRule ? apiRule.mode : undefined;
|
|
120
|
+
const ymlMode = config._flat[option.name];
|
|
121
|
+
let effectiveMode;
|
|
122
|
+
|
|
123
|
+
if (!ymlMode && apiMode) {
|
|
124
|
+
config._sources[option.name] = 'ContrastUI';
|
|
125
|
+
effectiveMode = apiMode;
|
|
126
|
+
} else if (ymlMode) {
|
|
127
|
+
effectiveMode = ymlMode;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
value = {
|
|
131
|
+
CanonicalName: option.name.split('.')[2],
|
|
132
|
+
Name: option.name,
|
|
133
|
+
Value: effectiveMode,
|
|
134
|
+
Source: config._sources[option.name],
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return value;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function getEffectiveConfigValues(agent, options, err) {
|
|
142
|
+
const tsData = { ...agent.tsFeatureSet.serverFeatures, ...agent.tsFeatureSet.applicationSettings };
|
|
143
|
+
const values = [];
|
|
144
|
+
|
|
145
|
+
for (const option of options) {
|
|
146
|
+
if (!err && option.name.includes('protect.rules') && option.name.includes('mode')) {
|
|
147
|
+
// get all protect rules
|
|
148
|
+
values.push(getProtectValues(option, agent.config, tsData));
|
|
149
|
+
} else if (!err && option.name.includes('logger')) {
|
|
150
|
+
// fetch agent/service/sys logger settings
|
|
151
|
+
values.push(getLoggerValues(option, agent.config, tsData));
|
|
152
|
+
} else if (!err && option.name.includes('assess')) {
|
|
153
|
+
// fetch assess settings
|
|
154
|
+
values.push(getAssessValues(option, agent.config, tsData));
|
|
155
|
+
} else if (agent.config._flat[option.name] != null) {
|
|
156
|
+
// fetch everything else
|
|
157
|
+
values.push({
|
|
158
|
+
CanonicalName: option.name,
|
|
159
|
+
Name: option.name,
|
|
160
|
+
Value: agent.config._flat[option.name],
|
|
161
|
+
Source: agent.config._sources[option.name],
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return values;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function getEffectiveConfig(agent, options, err) {
|
|
169
|
+
const effectiveConfigValues = getEffectiveConfigValues(agent, options, err);
|
|
170
|
+
const envValues = effectiveConfigValues.filter(v => v.Source == 'ENV');
|
|
171
|
+
const cliValues = effectiveConfigValues.filter(v => v.Source == 'CLI');
|
|
172
|
+
const ymlValues = effectiveConfigValues.filter(v => v.Source == 'YAML');
|
|
173
|
+
const apiValues = effectiveConfigValues.filter(v => v.Source == 'ContrastUI');
|
|
174
|
+
|
|
175
|
+
const effectiveConfig = {
|
|
176
|
+
ReportCreate: new Date(Date.now()),
|
|
177
|
+
Config: {
|
|
178
|
+
EffectiveConfig: {
|
|
179
|
+
Status: undefined,
|
|
180
|
+
Values: effectiveConfigValues
|
|
181
|
+
},
|
|
182
|
+
Environment: envValues,
|
|
183
|
+
CommandLine: cliValues,
|
|
184
|
+
ContrastUI: apiValues,
|
|
185
|
+
File: ymlValues,
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
return effectiveConfig;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function outputAgentConfigFile(agent, options, args, err) {
|
|
193
|
+
const effectiveConfig = getEffectiveConfig(agent, options, err);
|
|
194
|
+
|
|
195
|
+
if (err) {
|
|
196
|
+
effectiveConfig.Config.Status = 'Failure! ' +
|
|
197
|
+
`Could not connect to TeamServer, so no TeamServer data will be included. Error: ${err}`;
|
|
198
|
+
} else {
|
|
199
|
+
effectiveConfig.Config.Status = 'Success';
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
fs.accessSync(path.join(args.output, '..'), fs.constants.RDWD_OK);
|
|
204
|
+
fs.writeFileSync(args.output, JSON.stringify(effectiveConfig, null, 2), 'utf-8');
|
|
205
|
+
} catch (err) {
|
|
206
|
+
console.log(`Couldn't create effective config file: ${err}`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (!args.quiet) {
|
|
210
|
+
console.log(JSON.stringify(effectiveConfig, null, 2));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
module.exports = {
|
|
215
|
+
getEffectiveConfigValues,
|
|
216
|
+
getEffectiveConfig,
|
|
217
|
+
outputAgentConfigFile,
|
|
218
|
+
getProtectValues,
|
|
219
|
+
getAssessValues,
|
|
220
|
+
getLoggerValues
|
|
221
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrast/agent",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.27.0",
|
|
4
4
|
"description": "Node.js security instrumentation by Contrast Security",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"security",
|
|
@@ -54,7 +54,8 @@
|
|
|
54
54
|
"bin": {
|
|
55
55
|
"node-contrast": "cli.js",
|
|
56
56
|
"perf-logs": "perf-logs.js",
|
|
57
|
-
"contrast-transpile": "cli-rewriter.js"
|
|
57
|
+
"contrast-transpile": "cli-rewriter.js",
|
|
58
|
+
"read-contrast-config": "config-diagnostics.js"
|
|
58
59
|
},
|
|
59
60
|
"files": [
|
|
60
61
|
"bin/**",
|
|
@@ -64,7 +65,8 @@
|
|
|
64
65
|
"cli.js",
|
|
65
66
|
"esm.mjs",
|
|
66
67
|
"perf-logs.js",
|
|
67
|
-
"cli-rewriter.js"
|
|
68
|
+
"cli-rewriter.js",
|
|
69
|
+
"config-diagnostics.js"
|
|
68
70
|
],
|
|
69
71
|
"repository": {
|
|
70
72
|
"type": "git"
|
|
@@ -138,7 +140,7 @@
|
|
|
138
140
|
"dustjs-linkedin": "^3.0.1",
|
|
139
141
|
"ejs": "^3.1.7",
|
|
140
142
|
"escape-html": "^1.0.3",
|
|
141
|
-
"eslint": "^8.
|
|
143
|
+
"eslint": "^8.26.0",
|
|
142
144
|
"eslint-plugin-mocha": "^10.0.3",
|
|
143
145
|
"eslint-plugin-node": "^11.1.0",
|
|
144
146
|
"express": "file:test/mock/express",
|
|
@@ -158,7 +160,7 @@
|
|
|
158
160
|
"lint-staged": "^12.0.2",
|
|
159
161
|
"madge": "^4.0.1",
|
|
160
162
|
"marsdb": "file:test/mock/marsdb",
|
|
161
|
-
"mocha": "^9.2.
|
|
163
|
+
"mocha": "^9.2.2",
|
|
162
164
|
"mochawesome": "^7.0.1",
|
|
163
165
|
"mock-fs": "^5.1.2",
|
|
164
166
|
"mongodb": "file:test/mock/mongodb",
|