@contrast/config 1.15.0 → 1.16.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/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright: 2022 Contrast Security, Inc
1
+ Copyright: 2023 Contrast Security, Inc
2
2
  Contact: support@contrastsecurity.com
3
3
  License: Commercial
4
4
 
package/lib/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright: 2022 Contrast Security, Inc
2
+ * Copyright: 2023 Contrast Security, Inc
3
3
  * Contact: support@contrastsecurity.com
4
4
  * License: Commercial
5
5
 
@@ -32,33 +32,67 @@ export type SyslogLevel =
32
32
  | 'info'
33
33
  | 'debug';
34
34
 
35
+ export interface ConfigOption<T> {
36
+ name: string;
37
+ abbrev?: string;
38
+ env?: string;
39
+ arg: string;
40
+ enum?: T[];
41
+ default?: T;
42
+ fn?: (arg: any) => T;
43
+ desc: string;
44
+ }
45
+
35
46
  export interface Config {
36
47
  configFile: string;
37
-
38
48
  _default: Record<string, any>;
39
49
  _flat: Record<string, any>;
40
50
  _sources: Record<string, 'DEFAULT_VALUE' | 'ENVIRONMENT_VARIABLE' | 'USER_CONFIGURATION_FILE' | 'CONTRAST_UI'>;
51
+
41
52
  api: {
53
+ /** Default: `true` */
42
54
  enable: boolean;
43
- api_key: string;
44
- service_key: string;
45
-
46
55
  /** Default: `'https://app.contrastsecurity.com/Contrast'` */
47
56
  url: string;
48
-
57
+ /** No default value but required when `api.enable` is `true` */
58
+ api_key: string;
59
+ /** No default value but required when `api.enable` is `true` */
60
+ service_key: string;
61
+ /** No default value but required when `api.enable` is `true` */
49
62
  user_name: string;
63
+
50
64
  proxy: {
65
+ /** Default: `false` */
51
66
  enable: boolean;
67
+ /** No default value but required when `api.proxy.enable` is `true` */
52
68
  url: string;
53
69
  };
54
70
  };
55
71
 
56
72
  agent: {
57
- polling: {
58
- app_activity_ms: number;
59
- app_settings_ms: number;
60
- app_update_ms: number;
61
- server_settings_ms: number;
73
+ /**
74
+ * Limit for stack trace size (larger limits will improve accuracy but
75
+ * increase memory usage). Default: `10`
76
+ */
77
+ stack_trace_limit: number;
78
+
79
+ /**
80
+ * List of patterns to ignore within stack traces.
81
+ * Default: `['agent-', '@contrast', 'node-agent']
82
+ */
83
+ stack_trace_filters: string[];
84
+
85
+ diagnostics: {
86
+ /** Default: `true` */
87
+ enable: boolean;
88
+ /** Default: `false` */
89
+ quiet: boolean
90
+ report_path?: string;
91
+ };
92
+
93
+ route_coverage: {
94
+ /** Default: `true` */
95
+ enable: boolean;
62
96
  };
63
97
 
64
98
  reporters: {
@@ -66,43 +100,56 @@ export interface Config {
66
100
  file?: string | number;
67
101
  };
68
102
 
103
+ effective_config: {
104
+ reporting: {
105
+ /** Default: `true` */
106
+ enable: boolean;
107
+ };
108
+ };
109
+
110
+ polling: {
111
+ /** Default: `30000` */
112
+ app_activity_ms: number;
113
+ /** Default: `30000` */
114
+ app_settings_ms: number;
115
+ /** Default: `30000` */
116
+ app_update_ms: number;
117
+ /** Default: `30000` */
118
+ server_settings_ms: number;
119
+ };
120
+
69
121
  logger: {
70
- /**
71
- * When false, create a new log file on startup instead of appending and
72
- * rolling daily. Default: `true`
73
- */
74
- append: boolean;
122
+ /** Default: `'./contrast.log'` */
123
+ path: string;
75
124
 
76
125
  /**
77
126
  * Minimum log level. 'silent' disables logging entirely.
78
- * Default: `'error'`
127
+ * Default: `'info'`
79
128
  */
80
129
  level: LevelWithSilent;
81
130
 
82
- /** Default: `'node-contrast'` */
83
- path: string;
131
+ /**
132
+ * When false, create a new log file on startup instead of appending and
133
+ * rolling daily. Default: `true`
134
+ */
135
+ append: boolean;
84
136
 
85
137
  /** Suppress output when `false`. Default: `true` */
86
138
  stdout: boolean;
87
139
  };
88
140
 
89
141
  security_logger: {
142
+ /** Default: `'./security.log'` */
143
+ path: string;
90
144
  /** Default: `'error'` */
91
145
  level: Level;
92
-
93
- /** Default: `'security'` */
94
- path: string;
95
-
96
146
  /** Default: `false` */
97
147
  stdout: boolean;
98
-
99
148
  syslog: {
100
149
  /** Default: `false` */
101
150
  enable: boolean;
102
-
103
151
  /** Default: `'127.0.0.1'` */
104
152
  ip: string;
105
-
106
153
  /** Default: `514` */
107
154
  port: number;
108
155
 
@@ -113,90 +160,107 @@ export interface Config {
113
160
  */
114
161
  facility: number;
115
162
 
116
- /** Log level of 'Blocked' attacks. Default: `'notice'` */
117
- severity_blocked: SyslogLevel;
118
-
119
163
  /** Log level of 'Exploited' attacks. Default: `'alert'` */
120
164
  severity_exploited: SyslogLevel;
121
-
122
- /** Log level of 'Probed' attacks. Default: `'warning'` */
123
- severity_probed: SyslogLevel;
124
-
165
+ /** Log level of 'Blocked' attacks. Default: `'notice'` */
166
+ severity_blocked: SyslogLevel;
125
167
  /** Log level of 'Blocked at Perimeter' attacks. Default: `'notice'` */
126
168
  severity_blocked_perimeter: SyslogLevel;
127
-
169
+ /** Log level of 'Probed' attacks. Default: `'warning'` */
170
+ severity_probed: SyslogLevel;
128
171
  /** Log level of suspcious but not blocked attacks. Default: `'warning'` */
129
172
  severity_suspicious: SyslogLevel;
130
173
  };
131
-
132
174
  };
133
175
 
134
176
  node: {
177
+ /** Location to look for the app's package.json. Default: `process.cwd()` */
178
+ app_root: string;
135
179
  /** Default: `true` */
136
180
  enable_rewrite: boolean;
137
-
138
181
  /** Default: `true` */
139
182
  enable_source_maps: boolean;
183
+ library_usage: {
184
+ reporting: {
185
+ /** Default: `true` */
186
+ enable: boolean;
187
+ /** Default: `1` */
188
+ interval_ms: number;
189
+ };
190
+ };
191
+ };
192
+ };
140
193
 
141
- /** Location to look for the app's package.json. Default: `process.cwd()` */
142
- app_root: string;
194
+ inventory: {
195
+ /** Default: `true` */
196
+ analyze_libraries: boolean;
197
+ };
198
+
199
+ assess: {
200
+ /** Default: `false` */
201
+ enable: boolean;
202
+ tags?: string;
203
+ /** Default: `'ALL'` */
204
+ stacktraces: string;
205
+ /** Default: `150` */
206
+ max_context_source_events: number;
207
+ /** Default: `500` */
208
+ max_propagation_events: number;
209
+
210
+ safe_positives: {
211
+ /** Default: `false` */
212
+ enable: boolean;
143
213
  };
144
214
 
145
- /**
146
- * Limit for stack trace size (larger limits will improve accuracy but
147
- * increase memory usage). Default: `10`
148
- */
149
- stack_trace_limit: number;
215
+ /** Defualt: `false` */
216
+ trust_custom_validators: boolean;
217
+ };
150
218
 
151
- /**
152
- * List of patterns to ignore within stack traces.
153
- * Default: `['agent', '@contrast', 'node-agent']
154
- */
155
- stack_trace_filters: string[];
219
+ protect: {
220
+ /** Default: `false` */
221
+ enable: boolean;
222
+
223
+ probe_analysis: {
224
+ /** Default: `true` */
225
+ enable: boolean;
226
+ }
227
+
228
+ rules: {
229
+ /**
230
+ * List of rule ids to disable.
231
+ * Default: `[]`
232
+ */
233
+ disabled_rules: string[];
234
+ } & Record<Omit<Rule, Rule.BOT_BLOCKER | Rule.IP_DENYLIST | Rule.VIRTUAL_PATCH>, { mode: ProtectRuleMode }>;
156
235
  };
157
236
 
158
237
  application: {
159
238
  /** override the reported application name. */
160
239
  name?: string;
161
-
162
240
  /** override the reported application path. Default: `'/'` */
163
241
  path: string;
242
+ /** override the reported application version */
243
+ version?: string;
164
244
 
165
245
  /**
166
- * Override the reported application version (if different from 'version'
167
- * field in the application's package.json).
246
+ * Provide the ID of a session existing within Contrast UI.
247
+ * Default: `null`
168
248
  */
169
- version?: string;
170
-
171
- /** Provide the ID of a session existing within Contrast UI. */
172
249
  session_id: string | null;
173
250
 
174
- /** Provide metadata used to create a new session within Contrast UI/ */
175
- session_metadata: string | null;
176
- };
177
-
178
- assess: {
179
- tags: string;
180
- };
181
-
182
- protect: {
183
- enable: boolean;
184
-
185
251
  /**
186
- * List of rule ids to disable.
187
- * Default: `[]`
252
+ * Provide metadata used to create a new session within Contrast UI.
253
+ * Default: `null`
188
254
  */
189
- disabled_rules: string[];
190
-
191
- rules: Record<Rule, { mode: ProtectRuleMode }>;
255
+ session_metadata: string | null;
192
256
  };
193
257
 
194
258
  /** Reported server information overrides */
195
259
  server: {
196
- environment?: string;
197
- tags?: string;
198
260
  /** Default: `os.hostname()` */
199
261
  name: string;
262
+ environment?: string;
263
+ tags?: string;
200
264
  version?: string;
201
265
  };
202
266
  }
package/lib/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright: 2022 Contrast Security, Inc
2
+ * Copyright: 2023 Contrast Security, Inc
3
3
  * Contact: support@contrastsecurity.com
4
4
  * License: Commercial
5
5
 
package/lib/options.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright: 2022 Contrast Security, Inc
2
+ * Copyright: 2023 Contrast Security, Inc
3
3
  * Contact: support@contrastsecurity.com
4
4
  * License: Commercial
5
5
 
@@ -13,24 +13,7 @@
13
13
  * way not consistent with the End User License Agreement.
14
14
  */
15
15
 
16
- /**
17
- * Sets up the agent config. All options include a name and a description.
18
- * Where the setting is not a boolean, they include args as well.
19
- *
20
- * The module currently houses all new common config settings.
21
- *
22
- * Other settings include:
23
- * feature: a property in the TS feature set to tie the config option to
24
- * env: environment variable to check for value in
25
- * fn: a function to run on the original value (eg type coercion or sanitizing).
26
- * returns undefined if it can't do anything with the value it is given.
27
- * enum: validation of whether type matches enumerated value
28
- *
29
- * NOTE: I'm not sure if validation should also be specified and handled here.
30
- *
31
- * TODO: add defaults to all new options
32
- * TODO: add mapping for TeamServer FeatureSet analogues where they differ
33
- */
16
+ // @ts-check
34
17
 
35
18
  'use strict';
36
19
 
@@ -41,10 +24,8 @@ const { Rule } = require('@contrast/common');
41
24
 
42
25
  /**
43
26
  * Takes strings "true"|"t" or "false"|"f" (case insensitive) and return the appropriate boolean.
44
- * If we can't match one of the two words, return true;
45
- *
46
- * @param {boolean|string} value passed arg; never undefined or the function isn't called
47
- * @return {boolean}
27
+ * @param {boolean | string} value passed arg; never undefined or the function isn't called
28
+ * @return {boolean | undefined}
48
29
  */
49
30
  function castBoolean(value) {
50
31
  const type = typeof value;
@@ -63,7 +44,7 @@ function castBoolean(value) {
63
44
  * Takes string path and resolves absolute path based on current working dir
64
45
  *
65
46
  * @param {string} value passed arg; never undefined or the function isn't called
66
- * @return {string} absolute path resolve from process.cwd()
47
+ * @return {string | undefined} absolute path resolve from process.cwd()
67
48
  */
68
49
  function toAbsolutePath(value) {
69
50
  return value ? path.resolve(process.cwd(), String(value)) : undefined;
@@ -89,7 +70,27 @@ const parseNum = (val) => {
89
70
  return clearBaseCase(Math.ceil(float));
90
71
  };
91
72
 
92
- const config = [
73
+ /**
74
+ * Sets up the agent config. All options include a name and a description.
75
+ * Where the setting is not a boolean, they include args as well.
76
+ *
77
+ * The module currently houses all new common config settings.
78
+ *
79
+ * Other settings include:
80
+ * - env: environment variable to check for value in
81
+ * - fn: a function to run on the original value (eg type coercion or sanitizing). returns undefined if it can't do anything with the value it is given.
82
+ * - enum: validation of whether type matches enumerated value
83
+ *
84
+ * NOTE: I'm not sure if validation should also be specified and handled here.
85
+ *
86
+ * TODO: add defaults to all new options
87
+ *
88
+ * TODO: add mapping for TeamServer FeatureSet analogues where they differ
89
+ *
90
+ * @type {import('.').ConfigOption[]}
91
+ */
92
+ const options = [
93
+ // config
93
94
  {
94
95
  name: 'configFile',
95
96
  abbrev: 'c',
@@ -98,27 +99,13 @@ const config = [
98
99
  arg: '<path>',
99
100
  desc: 'set config file location. defaults to <app_root>/contrast_security.yaml',
100
101
  },
101
- ];
102
-
103
- const api = [
102
+ // api
104
103
  {
105
104
  name: 'api.enable',
106
105
  arg: '[false]',
107
- fn: castBoolean,
108
106
  default: true,
109
- desc: 'set false to disable reporting',
110
- },
111
- {
112
- name: 'api.api_key',
113
- env: 'CONTRASTSECURITY_API_KEY',
114
- arg: '<key>',
115
- desc: 'the organization API key',
116
- },
117
- {
118
- name: 'api.service_key',
119
- env: 'CONTRASTSECURITY_SECRET_KEY',
120
- arg: '<key>',
121
- desc: 'account service key',
107
+ fn: castBoolean,
108
+ desc: 'Set to `false` to disable Contrast UI communication.',
122
109
  },
123
110
  {
124
111
  name: 'api.url',
@@ -155,295 +142,361 @@ const api = [
155
142
  }
156
143
  return value;
157
144
  },
158
- desc: 'url to report on',
145
+ desc: 'Set the URL for the Contrast UI.',
146
+ },
147
+ {
148
+ name: 'api.api_key',
149
+ env: 'CONTRASTSECURITY_API_KEY',
150
+ arg: '<key>',
151
+ desc: 'Set the API key needed to communicate with the Contrast UI.',
152
+ },
153
+ {
154
+ name: 'api.service_key',
155
+ env: 'CONTRASTSECURITY_SECRET_KEY',
156
+ arg: '<key>',
157
+ desc: 'Set the service key needed to communicate with the Contrast UI. It is used to calculate the Authorization header.',
159
158
  },
160
159
  {
161
160
  name: 'api.user_name',
162
161
  env: 'CONTRASTSECURITY_UID',
163
162
  arg: '<name>',
164
- desc: 'account user name',
163
+ desc: 'Set the user name used to communicate with the Contrast UI. It is used to calculate the Authorization header.',
165
164
  },
165
+ // api.proxy
166
166
  {
167
167
  name: 'api.proxy.enable',
168
168
  arg: '[true]',
169
169
  default: false,
170
- desc: 'if false, no proxy is being used for communication of data',
170
+ desc: "Set value to `true` for the agent to communicate with the Contrast web interface over a proxy. Set value to `false` if you don't want to use the proxy.",
171
171
  },
172
172
  {
173
173
  name: 'api.proxy.url',
174
174
  arg: '<url>',
175
- desc: 'url of proxy for communicating agent data',
176
- }
177
- ];
178
-
179
- const agent = [
175
+ desc: 'Set the URL for your Proxy Server. The URL form is `scheme://host:port`.',
176
+ },
177
+ // agent
178
+ {
179
+ name: 'agent.stack_trace_limit',
180
+ arg: '<limit>',
181
+ default: 10,
182
+ fn: parseNum,
183
+ desc: 'Set to limit the length of Error stack traces to a specified number. Larger limits will improve accuracy but increase memory usage.',
184
+ },
185
+ {
186
+ // NOTE: not in common config.
187
+ name: 'agent.stack_trace_filters',
188
+ arg: '<list,of,filters>',
189
+ default: 'agent-,@contrast,node-agent',
190
+ fn: split,
191
+ desc: 'comma-separated list of patterns to ignore within stack traces',
192
+ },
193
+ // agent.diagnostics
180
194
  {
181
195
  name: 'agent.diagnostics.enable',
182
196
  arg: '[false]',
183
197
  default: true,
184
198
  fn: castBoolean,
185
- desc: 'If true the agent will try to create both diagnostic files at startup',
186
- },
187
- {
188
- name: 'agent.diagnostics.quiet',
189
- arg: '[true]',
190
- default: false,
191
- fn: castBoolean,
192
- desc: 'If true the agent will print all diagnostic results to stdout as well',
199
+ desc: 'Set to `false` to disable agent diagnostics.',
193
200
  },
194
201
  {
195
202
  name: 'agent.diagnostics.report_path',
196
203
  arg: '<path>',
197
- desc: 'path indicating where to report all diagnostics results',
204
+ default: '.',
205
+ fn: toAbsolutePath,
206
+ desc: "Set the directory in which to write diagnostic files. Defaults to the application's current working directory.",
207
+ },
208
+ // agent.route_coverage
209
+ {
210
+ name: 'agent.route_coverage.enable',
211
+ arg: '[false]',
212
+ default: true,
213
+ fn: castBoolean,
214
+ desc: 'Set to `false` for the agent to not send route-based coverage data to the Contrast UI.',
198
215
  },
216
+ // agent.reporters
217
+ // NOTE: Java has a `reporting` node--use that?
199
218
  {
200
219
  name: 'agent.reporters.file',
201
220
  arg: '<path>',
202
221
  desc: 'path indicating where to report all agent findings',
203
222
  },
223
+ // agent.effective_config
204
224
  {
205
- name: 'agent.logger.append',
225
+ name: 'agent.effective_config.reporting.enable',
206
226
  arg: '[false]',
207
- fn: castBoolean,
208
227
  default: true,
209
- desc: 'if false, create a new log file on startup instead of appending and rolling daily',
228
+ fn: castBoolean,
229
+ desc: 'Defaults to `true`. Controls whether configuration setting reports are sent to the Contrast web interface.',
210
230
  },
231
+ // agent.polling
211
232
  {
212
- name: 'agent.logger.level',
213
- arg: '<level>',
214
- fn: lowercase,
215
- enum: ['error', 'warn', 'info', 'debug', 'trace'],
216
- desc: 'logging level (error, warn, info, debug, trace). overrides FeatureSet:logLevel',
233
+ name: 'agent.polling.app_activity_ms',
234
+ arg: '<ms>',
235
+ default: 30000,
236
+ fn: parseNum,
237
+ desc: 'Set the frequency with which the agent sends application activity to the Contrast UI.',
217
238
  },
239
+ {
240
+ name: 'agent.polling.app_settings_ms',
241
+ arg: '<ms>',
242
+ default: 30000,
243
+ fn: parseNum,
244
+ desc: 'Set the frequency with which the agent sends application settings polls to the Contrast UI.',
245
+ },
246
+ {
247
+ name: 'agent.polling.app_update_ms',
248
+ arg: '<ms>',
249
+ default: 30000,
250
+ fn: parseNum,
251
+ desc: 'Set the the frequency with which the agent sends application updates to the Contrast UI.',
252
+ },
253
+ {
254
+ name: 'agent.polling.server_settings_ms',
255
+ arg: '<ms>',
256
+ default: 30000,
257
+ fn: parseNum,
258
+ desc: 'Set the frequency with which the agent sends server settings polls to the Contrast UI.',
259
+ },
260
+ // agent.logger
218
261
  {
219
262
  name: 'agent.logger.path',
263
+ arg: '<path>',
220
264
  default: 'contrast.log',
221
265
  fn: toAbsolutePath,
222
- arg: '<path>',
223
- desc: 'where contrast will put its debug log',
266
+ desc: `Enable diagnostic logging by setting a path to a log file. While diagnostic logging hurts performance, it generates useful information for debugging Contrast. The value set here is the location to which the agent saves log output. If no log file exists at this location, the agent creates a file.
267
+ Example - \`/opt/Contrast/contrast.log\` creates a log in the \`/opt/Contrast\` directory, and rotates it automatically as needed.`,
224
268
  },
225
269
  {
226
- name: 'agent.logger.stdout',
270
+ name: 'agent.logger.level',
271
+ arg: '<level>',
272
+ enum: ['error', 'warn', 'info', 'debug', 'trace'],
273
+ // default: 'info', this has no default at the config level but is instead handled by `logger-factory`.
274
+ fn: lowercase,
275
+ desc: 'Set the the log output level. Valid options are `ERROR`, `WARN`, `INFO`, `DEBUG`, and `TRACE`.',
276
+ },
277
+ {
278
+ name: 'agent.logger.append',
227
279
  arg: '[false]',
228
- fn: castBoolean,
229
280
  default: true,
230
- desc: 'if false, suppress output to STDOUT',
281
+ fn: castBoolean,
282
+ desc: 'Set to `false` for the agent to always create a new log file instead of appending and rolling.',
231
283
  },
232
284
  {
233
- name: 'agent.security_logger.level',
234
- default: 'error',
235
- arg: '<level>',
236
- fn: lowercase,
237
- enum: ['error', 'warn', 'info', 'debug', 'trace'],
238
- desc: 'security logging level (error, warn, info, debug, trace)',
285
+ name: 'agent.logger.stdout',
286
+ arg: '[false]',
287
+ default: true,
288
+ fn: castBoolean,
289
+ desc: 'Set to `false` to suppress log output to `stdout`.',
239
290
  },
291
+ // agent.security_logger
240
292
  {
241
293
  name: 'agent.security_logger.path',
294
+ arg: '<path>',
242
295
  default: 'security.log',
243
296
  fn: toAbsolutePath,
244
- arg: '<path>',
245
- desc: 'where to log security events',
297
+ desc: 'Set the file to which the agent logs security events.',
298
+ },
299
+ {
300
+ name: 'agent.security_logger.level',
301
+ arg: '<level>',
302
+ enum: ['error', 'warn', 'info', 'debug', 'trace'],
303
+ default: 'error',
304
+ fn: lowercase,
305
+ desc: 'Set the log level for security logging. Valid options are `ERROR`, `WARN`, `INFO`, `DEBUG`, and `TRACE`.',
246
306
  },
247
307
  {
248
308
  name: 'agent.security_logger.stdout',
249
309
  arg: '[false]',
250
310
  default: false,
251
311
  fn: castBoolean,
252
- desc: 'if true will output the security_logger loggs to stdout too',
312
+ desc: 'Set to `true` to log output to `stdout` as well as the configured file.',
253
313
  },
314
+ // agent.security_logger.syslog
254
315
  {
255
316
  name: 'agent.security_logger.syslog.enable',
317
+ arg: '[true]',
256
318
  default: false,
257
319
  fn: castBoolean,
258
- desc: 'Set to true to enable Syslog logging',
320
+ desc: 'Set to `true` to enable Syslog logging.',
259
321
  },
260
322
  {
261
323
  name: 'agent.security_logger.syslog.ip',
262
- default: '127.0.0.1',
263
- desc: 'Set the IP address of the Syslog server to which the agent should send messages',
264
324
  arg: '<ip>',
325
+ default: '127.0.0.1',
326
+ desc: 'Set the IP address of the Syslog server to which the agent should send messages.',
265
327
  },
266
328
  {
267
329
  name: 'agent.security_logger.syslog.port',
268
- default: '514',
269
- desc: 'Set the port of the Syslog server to which the agent should send messages',
270
330
  arg: '<port>',
331
+ default: 514,
271
332
  fn: parseNum,
333
+ desc: 'Set the port of the Syslog server to which the agent should send messages.',
272
334
  },
273
335
  {
274
336
  name: 'agent.security_logger.syslog.facility',
275
- default: '19',
276
- desc: 'Set the facility code of the messages the agent sends to Syslog',
277
- enum: [
278
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
279
- 21, 22, 23,
280
- ],
281
337
  arg: '<facility>',
338
+ enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23],
339
+ default: 19,
282
340
  fn: parseNum,
341
+ desc: 'Set the facility code of the messages the agent sends to Syslog.',
283
342
  },
284
343
  {
285
- name: 'agent.security_logger.syslog.severity_blocked',
286
- default: 'notice',
287
- desc: 'Set the log level of Blocked attacks. Value options are ALERT/CRITICAL/ERROR/WARNING/NOTICE/INFO/DEBUG',
288
- enum: ['alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug'],
344
+ name: 'agent.security_logger.syslog.severity_exploited',
289
345
  arg: '<level>',
346
+ enum: ['alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug'],
347
+ default: 'alert',
290
348
  fn: lowercase,
349
+ desc: 'Set the log level of Exploited attacks. Value options are `ALERT`, `CRITICAL`, `ERROR`, `WARNING`, `NOTICE`, `INFO`, and `DEBUG`.',
291
350
  },
292
351
  {
293
- name: 'agent.security_logger.syslog.severity_exploited',
294
- default: 'alert',
295
- desc: 'Set the log level of Exploited attacks. Value options are ALERT/CRITICAL/ERROR/WARNING/NOTICE/INFO/DEBUG',
352
+ name: 'agent.security_logger.syslog.severity_blocked',
353
+ arg: '<level>',
296
354
  enum: ['alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug'],
355
+ default: 'notice',
356
+ fn: lowercase,
357
+ desc: 'Set the log level of Blocked attacks. Value options are `ALERT`, `CRITICAL`, `ERROR`, `WARNING`, `NOTICE`, `INFO`, and `DEBUG`.',
358
+ },
359
+ {
360
+ name: 'agent.security_logger.syslog.severity_blocked_perimiter',
297
361
  arg: '<level>',
362
+ enum: ['alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug'],
363
+ default: 'notice',
298
364
  fn: lowercase,
365
+ desc: 'Set the log level of Blocked At Perimeter attacks. Value options are `ALERT`, `CRITICAL`, `ERROR`, `WARNING`, `NOTICE`, `INFO`, and `DEBUG`.',
299
366
  },
300
367
  {
301
368
  name: 'agent.security_logger.syslog.severity_probed',
302
- default: 'warning',
303
- desc: 'Set the log level of Probed attacks. Value options are ALERT/CRITICAL/ERROR/WARNING/NOTICE/INFO/DEBUG',
304
- enum: ['alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug'],
305
369
  arg: '<level>',
370
+ enum: ['alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug'],
371
+ default: 'warning',
306
372
  fn: lowercase,
373
+ desc: 'Set the log level of Probed attacks. Value options are `ALERT`, `CRITICAL`, `ERROR`, `WARNING`, `NOTICE`, `INFO`, and `DEBUG`.',
307
374
  },
308
375
  {
309
376
  name: 'agent.security_logger.syslog.severity_suspicious',
310
- default: 'warning',
311
- desc: 'Set the log level of suspicious but not blocked attacks. Value options are ALERT/CRITICAL/ERROR/WARNING/NOTICE/INFO/DEBUG',
312
- enum: ['alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug'],
313
377
  arg: '<level>',
378
+ enum: ['alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug'],
379
+ default: 'warning',
314
380
  fn: lowercase,
381
+ desc: 'Set the log level of Suspicious attacks. Value options are `ALERT`, `CRITICAL`, `ERROR`, `WARNING`, `NOTICE`, `INFO`, and `DEBUG`.',
315
382
  },
383
+ // agent.node
316
384
  {
385
+ name: 'agent.node.app_root',
386
+ arg: '<path>',
387
+ default: process.cwd(),
388
+ desc: "Set the directory containing the application's `package.json` file.",
389
+ },
390
+ {
391
+ // NOTE: not in common config.
317
392
  name: 'agent.node.enable_rewrite',
318
393
  arg: '[false]',
319
- fn: castBoolean,
320
394
  default: true,
321
- desc: 'if false, disable source rewriting (not recommended)',
395
+ fn: castBoolean,
396
+ desc: 'Set to `false` to disable source code rewriting. Not recommended.',
322
397
  },
323
398
  {
399
+ // NOTE: not in common config.
324
400
  name: 'agent.node.enable_source_maps',
325
401
  arg: '[false]',
326
- fn: castBoolean,
327
402
  default: true,
328
- desc: 'enable source map support in reporting',
403
+ fn: castBoolean,
404
+ desc: 'Set to `true` to enable source map support in reporting.',
329
405
  },
406
+ // agent.node.library_usage.reporting
330
407
  {
331
- name: 'agent.node.app_root',
332
- arg: '<path>',
333
- desc: "set location to look for the app's package.json",
334
- default: process.cwd(),
408
+ name: 'agent.node.library_usage.reporting.enable',
409
+ arg: '[false]',
410
+ default: true,
411
+ fn: castBoolean,
412
+ desc: 'Set to `false` to disable enhanced library usage features, i.e. scanning for composition of dependencies, reporting library usage.',
335
413
  },
336
414
  {
337
- name: 'agent.node.library_usage.reporting.interval',
415
+ name: 'agent.node.library_usage.reporting.interval_ms',
338
416
  arg: '<num>',
339
- fn: parseNum,
340
417
  default: 1,
341
- desc: 'frequency of collecting code events for library usage in milliseconds, defaults to 1 ms',
418
+ desc: 'Set the interval (in milliseconds) for collecting code events for library usage.',
342
419
  },
420
+ // inventory
343
421
  {
344
- name: 'agent.node.library_usage.reporting.enable',
422
+ name: 'inventory.analyze_libraries',
345
423
  arg: '[false]',
346
- // setting this falsee for now, until feature is complete
347
424
  default: true,
348
425
  fn: castBoolean,
349
- desc: 'add enhanced library usage features (i.e. scanning for composition of dependencies, reporting usage)',
426
+ desc: 'Set to `false` to disable library analysis.',
350
427
  },
428
+ // assess
351
429
  {
352
- name: 'agent.stack_trace_limit',
353
- arg: '<limit>',
354
- default: 10,
355
- fn: parseNum,
356
- desc: 'set limit for stack trace size (larger limits will improve accuracy but increase memory usage)',
357
- },
358
- {
359
- name: 'agent.stack_trace_filters',
360
- arg: '<list,of,filters>',
361
- default: 'agent-,@contrast,node-agent',
362
- fn: split,
363
- desc: 'comma-separated list of patterns to ignore within stack traces',
430
+ name: 'assess.enable',
431
+ arg: '[true]',
432
+ default: false,
433
+ fn: castBoolean,
434
+ desc: 'Include this property to determine if the Assess feature should be enabled. If this property is not present, the decision is delegated to the Contrast UI.',
364
435
  },
365
436
  {
366
- name: 'agent.polling.app_activity_ms',
367
- arg: '<ms>',
368
- default: 30000,
369
- fn: parseNum,
370
- desc: 'how often (in ms) application activity messages are sent to the UI',
437
+ name: 'assess.tags',
438
+ arg: '<tags>',
439
+ desc: `Apply a list of labels to vulnerabilities and preflight messages. Labels must be formatted as a comma-delimited list.
440
+ Example - \`label1, label2, label3\``,
371
441
  },
372
442
  {
373
- name: 'agent.polling.app_update_ms',
374
- arg: '<ms>',
375
- default: 30000,
376
- fn: parseNum,
377
- desc: 'how often (in ms) application updates are sent to the UI'
443
+ name: 'assess.stacktraces',
444
+ arg: '<level>',
445
+ enum: ['ALL', 'SOME', 'NONE'],
446
+ default: 'ALL',
447
+ fn: uppercase,
448
+ desc: 'Select the level of collected stacktraces. ALL - for all assess events, SOME - for Source and Sink events, NONE - no stacktraces collected',
378
449
  },
379
450
  {
380
- name: 'agent.polling.app_settings_ms',
381
- arg: '<ms>',
382
- default: 30000,
451
+ name: 'assess.max_context_source_events',
452
+ arg: '<limit>',
453
+ default: 150,
383
454
  fn: parseNum,
384
- desc: 'how often (in ms) application settings polls are sent to the UI',
455
+ desc: 'Set the maximum number of untrusted data flows to observe per request.',
385
456
  },
386
457
  {
387
- name: 'agent.polling.server_settings_ms',
388
- arg: '<ms>',
389
- default: 30000,
458
+ name: 'assess.max_propagation_events',
459
+ arg: '<limit>',
460
+ default: 500,
390
461
  fn: parseNum,
391
- desc: 'how often (in ms) server settings polls are sent to the UI',
392
- }
393
- ];
394
-
395
- const application = [
396
- {
397
- name: 'application.name',
398
- arg: '<name>',
399
- env: 'CONTRASTSECURITY_APP_NAME',
400
- desc: 'override the reported application name. (default: package.json:name)',
401
- },
402
- {
403
- name: 'application.path',
404
- arg: '<path>',
405
- default: '/',
406
- desc: 'override the reported application path',
407
- },
408
- {
409
- name: 'application.version',
410
- arg: '<version>',
411
- desc: "override the reported application version (if different from 'version' field in the application's package.json)",
462
+ desc: 'Set the maximum number of untrusted data flow propagations to observe per request.',
412
463
  },
413
464
  {
414
- name: 'application.session_id',
415
- arg: '<session_id>',
416
- default: null,
417
- desc: 'provide the ID of a session existing within Contrast UI',
465
+ name: 'assess.safe_positives.enable',
466
+ arg: '[false]',
467
+ default: false,
468
+ fn: castBoolean,
469
+ desc: 'enable detection and reporting of findings regarding safe security practices, aka safe positives. ' +
470
+ 'these results will be written to the location described by the `agent.reporters.file` option.',
418
471
  },
419
472
  {
420
- name: 'application.session_metadata',
421
- arg: '<session_metadata>',
422
- default: null,
423
- desc: 'provide metadata used to create a new session within Contrast UI',
473
+ name: 'assess.trust_custom_validators',
474
+ arg: '<trust-custom-validators>',
475
+ default: false,
476
+ fn: castBoolean,
477
+ desc: 'Set to `true` to trust incoming strings when they pass custom validators (Mongoose, Joi, validator, fastify-static).',
424
478
  },
425
- ];
426
-
427
- const protect = [
479
+ // protect
428
480
  {
429
481
  name: 'protect.enable',
430
- arg: '[false]',
482
+ arg: '[true]',
483
+ default: false,
431
484
  fn: castBoolean,
432
- desc: 'if false, disable protect for this agent',
433
- },
434
- {
435
- name: 'protect.disabled_rules',
436
- arg: '<list,of,rules>',
437
- fn: split,
438
- default: '',
439
- desc: 'comma-separated list of rule ids to disable',
485
+ desc: 'Include this property to determine if the Protect feature should be enabled. If this property is not present, the decision is delegated to the Contrast UI.',
440
486
  },
441
487
  {
442
488
  name: 'protect.probe_analysis.enable',
443
489
  arg: '[false]',
444
490
  default: true,
445
491
  fn: castBoolean,
446
- desc: 'turns on probe analysis and report them to Contrast UI'
492
+ desc: 'Set to `false` to disable probe analysis.',
493
+ },
494
+ {
495
+ name: 'protect.rules.disabled_rules',
496
+ arg: '<list,of,rules>',
497
+ default: '',
498
+ fn: split,
499
+ desc: 'Define a list of Protect rules to disable in the agent. The rules must be formatted as a comma-delimited list.',
447
500
  },
448
501
  ...Object.values(Rule)
449
502
  .filter((ruleId) => ![Rule.BOT_BLOCKER, Rule.IP_DENYLIST, Rule.VIRTUAL_PATCH].includes(ruleId))
@@ -451,93 +504,67 @@ const protect = [
451
504
  name: `protect.rules.${ruleId}.mode`,
452
505
  arg: '<mode>',
453
506
  enum: ['monitor', 'block', 'block_at_perimeter', 'off'],
454
- desc: `the mode in which to run the ${ruleId} rule`,
507
+ desc: 'Set the mode of the rule. Value options are `monitor`, `block`, `block_at_perimeter`, or `off`.',
455
508
  })),
456
- ];
457
-
458
- const assess = [
509
+ // application
459
510
  {
460
- name: 'assess.enable',
461
- arg: '[false]',
462
- fn: castBoolean,
463
- desc: 'if false, disable assess for this agent'
511
+ name: 'application.name',
512
+ env: 'CONTRASTSECURITY_APP_NAME',
513
+ arg: '<name>',
514
+ desc: "Override the reported application name. Defaults to the `name` field from an application's `package.json`",
464
515
  },
465
516
  {
466
- name: 'assess.trust_custom_validators',
467
- arg: '<trust-custom-validators>',
468
- fn: castBoolean,
469
- default: false,
470
- desc: 'trust incoming strings when they pass custom validators (Mongoose, Joi)',
517
+ name: 'application.path',
518
+ arg: '<path>',
519
+ default: '/',
520
+ desc: 'Override the reported application path.',
471
521
  },
472
522
  {
473
- name: 'assess.stacktraces',
474
- arg: '<level>',
475
- default: 'ALL',
476
- fn: uppercase,
477
- enum: ['ALL', 'SOME', 'NONE'],
478
- desc: 'Select the level of collected stacktraces. ALL - for all asses events, SOME - for Source and Sink events, NONE - no stacktraces collected'
523
+ name: 'application.version',
524
+ arg: '<version>',
525
+ desc: "Override the reported application version. Defaults to the `version` field from an application's `package.json`",
479
526
  },
480
527
  {
481
- name: 'assess.max_propagation_events',
482
- arg: '<limit>',
483
- default: 500,
484
- fn: parseNum,
485
- desc: 'set limit for maximum number of propagation events created per request',
528
+ name: 'application.session_id',
529
+ arg: '<session_id>',
530
+ default: null,
531
+ desc: 'Provide the ID of a session which already exists in the Contrast UI. Vulnerabilities discovered by the agent are associated with this session. If an invalid ID is supplied, the agent will be disabled. This option and `application.session_metadata` are mutually exclusive; if both are set, the agent will be disabled.',
486
532
  },
487
533
  {
488
- name: 'assess.max_context_source_events',
489
- arg: '<limit>',
490
- default: 150,
491
- fn: parseNum,
492
- desc: 'set limit for maximum number of source events (tracked strings) created per request',
534
+ name: 'application.session_metadata',
535
+ arg: '<session_metadata>',
536
+ default: null,
537
+ desc: 'Provide metadata which is used to create a new session ID in the Contrast UI. Vulnerabilities discovered by the agent are associated with this new session. This value should be formatted as `key=value` pairs (conforming to RFC 2253). Available key names for this configuration are branchName, buildNumber, commitHash, committer, gitTag, repository, testRun, and version. This option and `application.session_id` are mutually exclusive; if both are set the agent will be disabled.',
493
538
  },
539
+ // server
494
540
  {
495
- name: 'assess.safe_positives.enable',
496
- arg: '[false]',
497
- default: false,
498
- fn: castBoolean,
499
- desc: 'enable detection and reporting of findings regarding safe security practices, aka safe positives. ' +
500
- 'these results will be written to the location described by the `agent.reporters.file` option.',
541
+ name: 'server.name',
542
+ arg: '<name>',
543
+ default: os.hostname(),
544
+ desc: 'Override the reported server name. Defauls to the operating system hostname.',
501
545
  },
502
- ];
503
-
504
- const server = [
505
546
  {
506
547
  name: 'server.environment',
507
548
  arg: '<environment>',
508
- fn: uppercase,
509
549
  // enum: ['QA', 'PRODUCTION', 'DEVELOPMENT'], none of the other agents validate this
510
- desc: 'environment the server is running in (QA, PRODUCTION, or DEVELOPMENT)',
550
+ fn: uppercase,
551
+ desc: `Set the environment directly to override the default set by the Contrast UI. This allows the user to configure the environment dynamically at startup rather than manually updating the Server in the Contrast UI themselves afterwards.
552
+ Valid values include \`QA\`, \`PRODUCTION\` and \`DEVELOPMENT\`. For example, \`PRODUCTION\` registers this Server as running in a \`PRODUCTION\` environment, regardless of the organization's default environment in the Contrast UI.`,
511
553
  },
512
554
  {
513
555
  name: 'server.tags',
514
556
  arg: '<tags>',
515
- desc:
516
- 'server tags provided by the user to the agent that instrumented this server.',
517
- },
518
- {
519
- name: 'server.name',
520
- arg: '<name>',
521
- default: os.hostname(),
522
- desc: 'override the reported server name',
557
+ desc: `Apply a list of labels to the server. Labels must be formatted as a comma-delimited list.
558
+ Example - \`label1, label2, label3\``,
523
559
  },
524
560
  {
561
+ // NOTE: not in common config, and the desc here doesn't really make sense.
525
562
  name: 'server.version',
526
563
  arg: '<version>',
527
564
  desc: "override the reported server version (if different from 'version' field in the application's package.json)",
528
565
  },
529
566
  ];
530
567
 
531
- const options = [].concat(
532
- config,
533
- api,
534
- agent,
535
- application,
536
- protect,
537
- assess,
538
- server
539
- );
540
-
541
568
  module.exports.configOptions = options;
542
569
  module.exports.clearBaseCase = clearBaseCase;
543
570
  module.exports.castBoolean = castBoolean;
package/lib/util.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright: 2022 Contrast Security, Inc
2
+ * Copyright: 2023 Contrast Security, Inc
3
3
  * Contact: support@contrastsecurity.com
4
4
  * License: Commercial
5
5
 
@@ -52,18 +52,21 @@ class Config {
52
52
  _default: {},
53
53
  _flat: {},
54
54
  _sources: {},
55
+ api: {},
55
56
  agent: {
57
+ diagnostics: {},
56
58
  reporters: {},
59
+ security_logger: {},
57
60
  logger: {},
58
61
  node: {},
59
62
  },
60
- application: {},
63
+ inventory: {},
64
+ assess: {},
61
65
  protect: {
62
66
  rules: {},
63
67
  },
64
- assess: {},
68
+ application: {},
65
69
  server: {},
66
- api: {},
67
70
  });
68
71
  }
69
72
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/config",
3
- "version": "1.15.0",
3
+ "version": "1.16.0",
4
4
  "description": "An API for discovering Contrast agent configuration data",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",
@@ -17,7 +17,7 @@
17
17
  "test": "../scripts/test.sh"
18
18
  },
19
19
  "dependencies": {
20
- "@contrast/common": "1.13.0",
20
+ "@contrast/common": "1.14.0",
21
21
  "yaml": "^2.2.2"
22
22
  }
23
23
  }