@newrelic/security-agent 0.1.3 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/THIRD_PARTY_NOTICES.md +3 -3
  3. package/lib/instrumentation-security/core/constants.js +0 -1
  4. package/lib/instrumentation-security/hooks/fs/nr-fs.js +6 -5
  5. package/lib/instrumentation-security/hooks/mysql/nr-mysql.js +16 -0
  6. package/lib/instrumentation-security/hooks/require/nr-require.js +12 -5
  7. package/lib/nr-security-agent/lib/core/Auth-headers.js +1 -0
  8. package/lib/nr-security-agent/lib/core/applicationinfo.js +1 -1
  9. package/lib/nr-security-agent/lib/core/commonUtils.js +10 -10
  10. package/lib/nr-security-agent/lib/core/connections/websocket/index.js +0 -6
  11. package/lib/nr-security-agent/lib/core/connections/websocket/response/IASTUtils.js +50 -0
  12. package/lib/nr-security-agent/lib/core/connections/websocket/response/collector-policy-handler.js +4 -1
  13. package/lib/nr-security-agent/lib/core/connections/websocket/response/fuzz-request-handler.js +90 -31
  14. package/lib/nr-security-agent/lib/core/connections/websocket/response/iast-cool-down.js +15 -0
  15. package/lib/nr-security-agent/lib/core/connections/websocket/response/iast-record-deletion.js +19 -0
  16. package/lib/nr-security-agent/lib/core/connections/websocket/response/index.js +17 -5
  17. package/lib/nr-security-agent/lib/core/connections/websocket/websocket.js +9 -58
  18. package/lib/nr-security-agent/lib/core/logging.js +89 -71
  19. package/lib/nr-security-agent/lib/core/sec-agent-constants.js +3 -2
  20. package/lib/nr-security-agent/lib/core/statusUtils.js +1 -1
  21. package/lib/nr-security-agent/lib/core/websocket-client.js +5 -168
  22. package/package.json +4 -4
  23. package/lib/nr-security-agent/lib/core/worker-entities.js +0 -82
  24. package/lib/nr-security-agent/lib/core/worker.js +0 -148
@@ -32,8 +32,9 @@ const INIT_PING_RETRY_DELAY_ON_FAIL = 200; // in ms
32
32
  const RECONNECTION_DELAY = 500; // ms
33
33
  const APPLICATION_INFO_JSON_NAME = 'applicationinfo';
34
34
  let APP_INFO;
35
+ let CSEC_WS_STATE = '';
35
36
 
36
- const queue = new RingBuffer(1000);
37
+ const queue = new RingBuffer(10);
37
38
  let logger = logs.getLogger();
38
39
  const initLogger = logs.getInitLogger();
39
40
  let webSocket;
@@ -119,7 +120,6 @@ SecWebSocket.prototype.init = function init() {
119
120
  logger.debug("Pong received from Validator");
120
121
  })
121
122
  webSocket.on('close', () => {
122
- commonUtils.setWSHealthStatus('Error');
123
123
  logger.warn("WS connection closed");
124
124
  })
125
125
  this.instance = webSocket;
@@ -132,7 +132,7 @@ SecWebSocket.prototype.init = function init() {
132
132
  SecWebSocket.prototype.reconnect = function reconnect() {
133
133
  const { instance } = this;
134
134
  if (instance.readyState === WebSocket.CONNECTING &&
135
- process.env.CSEC_WS_STATE === CONNECTING) {
135
+ CSEC_WS_STATE === CONNECTING) {
136
136
  return;
137
137
  }
138
138
  setWebSocketConn();
@@ -207,19 +207,15 @@ SecWebSocket.prototype.dispatch = async function dispatch(event) {
207
207
  !this.isICReadyForEvents
208
208
  ) {
209
209
  handleDispatchFailure(this, event, eventStr);
210
- commonUtils.setWSHealthStatus('Error')
211
210
  return;
212
211
  }
213
212
  try {
214
- aquireWebSocket();
215
213
  await promisify(this.instance, this.instance.send)(eventStr, { mask: true }, () => {
216
214
  logger.debug(LOG_MESSAGES.EVENT_SENT + eventStr);
217
215
  });
218
- releaseWebSocket();
219
216
  } catch (error) {
220
217
  logger.debug(LOG_MESSAGES.ERROR_WHILE_SEND_EVENT, eventStr, error);
221
218
  statusUtils.addErrortoBuffer(error);
222
- commonUtils.setWSHealthStatus('Error')
223
219
  handleDispatchFailure(this, event, eventStr);
224
220
  }
225
221
  };
@@ -269,7 +265,6 @@ SecWebSocket.prototype.setValidatorNotReadyForEvents = function setValidatorNotR
269
265
  * recover these events.
270
266
  */
271
267
  SecWebSocket.prototype.flushEventQueue = async function flushEventQueue() {
272
- aquireWebSocket();
273
268
  try {
274
269
  const sentEvents = [];
275
270
  for (let counter = 0; counter < queue.size(); counter += 1) {
@@ -280,9 +275,7 @@ SecWebSocket.prototype.flushEventQueue = async function flushEventQueue() {
280
275
  hc.getInstance().registerEventsSent(results.length);
281
276
  } catch (err) {
282
277
  statusUtils.addErrortoBuffer(err);
283
- logger.error('Flush failed, reception of all events on IC couldn\'t be ensured.');
284
- } finally {
285
- releaseWebSocket();
278
+ logger.debug('Flush failed, reception of all events on IC couldn\'t be ensured.');
286
279
  }
287
280
  };
288
281
 
@@ -298,7 +291,6 @@ const handleDispatchFailure = (self, event, eventStr) => {
298
291
  // so feeding an old applicationinfo JSON would be incorrect
299
292
  if (eventStr && event.jsonName !== APPLICATION_INFO_JSON_NAME) {
300
293
  hc.getInstance().registerEventDrop();
301
- queue.enq(eventStr);
302
294
  }
303
295
  };
304
296
 
@@ -332,7 +324,7 @@ const defaultOnOpenCB = () => async function onOpen() {
332
324
  self.reconnect();
333
325
  return;
334
326
  }
335
-
327
+
336
328
  const validatorService = commonUtils.getValidatorServiceEndpointURL();
337
329
  initLogger.info(`[STEP-4] => Web socket connection to SaaS validator established successfully at ${validatorService}`)
338
330
  try {
@@ -343,13 +335,8 @@ const defaultOnOpenCB = () => async function onOpen() {
343
335
  const applicationInfo = APP_INFO || Agent.getAgent().applicationInfo;
344
336
  await self.dispatchApplicationInfo(applicationInfo);
345
337
 
346
- // by now we expect IC to be ready
347
- aquireWebSocket(true);
348
338
  self.setICReadyForEvents();
349
- // we would also want the event queue to be flushed
350
- await self.flushEventQueue();
351
- ResponseHandler.FuzzRequestHandler.setLastFuzzEnventTime();
352
- releaseWebSocket();
339
+ ResponseHandler.FuzzRequestHandler.setLastFuzzEventTime();
353
340
  initLogger.info(LOG_MESSAGES.SENDING_APPINFO_COMPLETE, JSON.stringify(applicationInfo));
354
341
  } catch (err) {
355
342
  logger.error(`Connection broken: ${err.message}`);
@@ -388,14 +375,13 @@ const defaultOnErrCB = () => function onClose(error) {
388
375
  commonUtils.setWSHealthStatus('Error');
389
376
  statusUtils.addErrortoBuffer(error);
390
377
  const self = this;
391
- logger.error("Error while connecting to validator:",error.message)
378
+ logger.error("Error while connecting to validator:", error.message)
392
379
  logger.warn("Security Agent INACTIVE!!!")
393
380
  if (error && error.code && (error.code === 'ECONNREFUSED' || error.code === 'EPIPE' || error.code === 'ECONNRESET')) {
394
381
  logger.debug("WS Client Error callback called:", error);
395
382
  self.obeyReconnect();
396
383
  }
397
384
  else {
398
- aquireWebSocket(true);
399
385
  self.reconnect();
400
386
  }
401
387
  };
@@ -415,52 +401,17 @@ SecWebSocket.PING_MSG = ACK;
415
401
  SecWebSocket.PING_RETRY_INTERVAL = INIT_PING_RETRY_DELAY_ON_FAIL;
416
402
  SecWebSocket.RECONNECTION_DELAY = RECONNECTION_DELAY;
417
403
 
418
- /**
419
- * Checks if the websocket is currently busy
420
- * by checking on CSEC_WS_STATE
421
- *
422
- * @returns {boolean} busy
423
- */
424
- function isWebSocketBusy() {
425
- return process.env.CSEC_WS_STATE !== IDLE;
426
- }
427
404
 
428
405
  /**
429
406
  * Sets the websocket state as connecting
430
407
  */
431
408
  function setWebSocketConn() {
432
- process.env.CSEC_WS_ACQUIRED_COUNT = 0;
433
- process.env.CSEC_WS_STATE = CONNECTING;
409
+ CSEC_WS_STATE = CONNECTING;
434
410
  }
435
411
 
436
- /**
437
- * marks the WS being aquired to be used in an operation
438
- */
439
- function aquireWebSocket(forced = false) {
440
- if (!forced && process.env.CSEC_WS_STATE === CONNECTING) return;
441
-
442
- let count = Number.parseInt(process.env.CSEC_WS_ACQUIRED_COUNT);
443
- count += 1;
444
- process.env.CSEC_WS_ACQUIRED_COUNT = count;
445
- process.env.CSEC_WS_STATE = BUSY;
446
- }
447
-
448
- /**
449
- * marks the WS being released after use in an operation
450
- */
451
- function releaseWebSocket() {
452
- const { CSEC_WS_STATE, CSEC_WS_ACQUIRED_COUNT } = process.env;
453
- let count = Number.parseInt(CSEC_WS_ACQUIRED_COUNT);
454
- count = count > 0 ? count - 1 : 0;
455
- process.env.CSEC_WS_ACQUIRED_COUNT = count;
456
- process.env.CSEC_WS_STATE = count === 0 && CSEC_WS_STATE !== CONNECTING ? CSEC_WS_STATE : IDLE;
457
- }
458
412
 
459
413
  module.exports = {
460
414
  WSCallbacks,
461
415
  SecWebSocket,
462
- isWebSocketBusy,
463
- setWebSocketConn,
464
- aquireWebSocket,
465
- releaseWebSocket
416
+ setWebSocketConn
466
417
  };
@@ -16,18 +16,24 @@ const LOG_PATTERN_OBJ = {
16
16
  type: 'pattern',
17
17
  pattern: '%[%d[%p][%c][%h][%z]%] %m'
18
18
  };
19
- const { LOG_DIR } = require('./sec-agent-constants');
19
+ const { LOG_DIR, CSEC_HOME } = require('./sec-agent-constants');
20
20
  let logger;
21
21
  const API = require('../../../nr-security-api');
22
22
  const NRAgent = API.getNRAgent();
23
23
 
24
24
  const logFileName = `${LOG_DIR}node-security-collector.log`;
25
25
  const initLogFileName = `${LOG_DIR}node-security-collector-init.log`;
26
+ let isLoggerOk = true;
26
27
 
27
- function createLogPathIfNotExist (dir) {
28
+
29
+ function createLogPathIfNotExist(dir) {
28
30
  try {
29
31
  if (!fs.existsSync(dir)) {
30
- fs.mkdirSync(dir, { recursive: true });
32
+ fs.mkdirSync(dir, 777, { recursive: true });
33
+ fs.chmodSync(dir, 0o777);
34
+ }
35
+ else {
36
+ fs.chmodSync(dir, 0o777);
31
37
  }
32
38
  } catch (error) {
33
39
  }
@@ -37,90 +43,103 @@ function createLogPathIfNotExist (dir) {
37
43
  * Initializes the logger appenders.
38
44
  * @param {v4uuid} applicationUUID
39
45
  */
40
- function initialize (applicationUUID) {
41
- const appenders = {};
42
- appenders.NR_CSEC = {
43
- type: 'file',
44
- compress: false,
45
- layout: LOG_PATTERN_OBJ
46
- };
47
- appenders.NR_CSEC_INIT = {
48
- type: 'file',
49
- compress: false,
50
- layout: LOG_PATTERN_OBJ
51
- };
52
-
53
- const logLevel = NRAgent && NRAgent.config && NRAgent.config.logging.enabled ? NRAgent.config.logging.level : 'info';
54
-
46
+ function initialize(applicationUUID) {
55
47
  try {
56
- if (!fs.existsSync(LOG_DIR)) {
57
- createLogPathIfNotExist(LOG_DIR);
48
+ const logLevel = NRAgent && NRAgent.config && NRAgent.config.logging.enabled ? NRAgent.config.logging.level : 'info';
49
+ const apmLogFilePath = NRAgent && NRAgent.config && NRAgent.config.logging.enabled ? NRAgent.config.logging.filepath : '';
50
+ let appenderType = 'file';
51
+
52
+ if (apmLogFilePath === 'stdout') {
53
+ appenderType = 'stdout';
58
54
  }
59
- } catch (error) {
60
- }
61
55
 
62
- Object.assign(appenders.NR_CSEC, {
63
- filename: logFileName,
64
- maxLogSize: LOG_FILE_SIZE,
65
- backups: 0
66
- });
67
-
68
- Object.assign(appenders.NR_CSEC_INIT, {
69
- filename: initLogFileName,
70
- maxLogSize: LOG_FILE_SIZE,
71
- backups: 0
72
- });
73
-
74
- const categories = {
75
- default: {
76
- appenders: [
77
- 'NR_CSEC'
78
- ],
79
- level: logLevel
80
- },
81
- NR_CSEC_INIT: {
82
- appenders: [
83
- 'NR_CSEC_INIT',
84
- 'NR_CSEC'
85
- ],
86
- level: logLevel
87
- },
88
- };
89
-
90
- if (env === 'dev' || env === 'trace') {
91
- appenders.STDOUT = {
92
- type: 'stdout',
56
+ const appenders = {};
57
+ appenders.NR_CSEC = {
58
+ type: appenderType,
59
+ compress: false,
93
60
  layout: LOG_PATTERN_OBJ
94
61
  };
95
- categories.default.appenders.push('STDOUT');
96
- categories.NR_CSEC_INIT.appenders.push('STDOUT');
97
- }
62
+ appenders.NR_CSEC_INIT = {
63
+ type: appenderType,
64
+ compress: false,
65
+ layout: LOG_PATTERN_OBJ
66
+ };
67
+
68
+
69
+ createLogPathIfNotExist(CSEC_HOME);
70
+ createLogPathIfNotExist(LOG_DIR);
71
+
72
+
73
+ Object.assign(appenders.NR_CSEC, {
74
+ filename: logFileName,
75
+ maxLogSize: LOG_FILE_SIZE,
76
+ backups: 0
77
+ });
78
+
79
+ Object.assign(appenders.NR_CSEC_INIT, {
80
+ filename: initLogFileName,
81
+ maxLogSize: LOG_FILE_SIZE,
82
+ backups: 0
83
+ });
84
+
85
+ const categories = {
86
+ default: {
87
+ appenders: [
88
+ 'NR_CSEC'
89
+ ],
90
+ level: logLevel
91
+ },
92
+ NR_CSEC_INIT: {
93
+ appenders: [
94
+ 'NR_CSEC_INIT',
95
+ ],
96
+ level: logLevel
97
+ },
98
+ };
99
+
100
+ if (apmLogFilePath !== 'stdout') {
101
+ categories.NR_CSEC_INIT.appenders.push('NR_CSEC')
102
+ }
103
+
104
+
105
+ if (env === 'dev' || env === 'trace') {
106
+ appenders.STDOUT = {
107
+ type: 'stdout',
108
+ layout: LOG_PATTERN_OBJ
109
+ };
110
+ categories.default.appenders.push('STDOUT');
111
+ categories.NR_CSEC_INIT.appenders.push('STDOUT');
112
+ }
98
113
 
99
- log4js.configure({
100
- appenders: appenders,
101
- categories: categories,
102
- disableClustering: true
103
- });
104
- process.env.loglevel = logLevel;
114
+ log4js.configure({
115
+ appenders: appenders,
116
+ categories: categories,
117
+ disableClustering: true
118
+ });
119
+ } catch (error) {
120
+ console.error("Error while logging into file. Fallback to stdout.", error.message);
121
+ isLoggerOk = false;
122
+ }
105
123
  }
106
124
 
107
125
  /**
108
126
  * sets the logging level of current instance.
109
127
  * @param {String} level
110
128
  */
111
- function setLevel (level = INFO) {
129
+ function setLevel(level = INFO) {
112
130
  level = level.trim();
113
131
  if (logger) {
114
132
  logger.level = level;
115
- } else {
116
- throw new Error('CSEC-Loggers Not yet Initialized!');
133
+ }
134
+ if (!isLoggerOk) {
135
+ logger.level = INFO;
117
136
  }
118
137
  }
119
138
 
120
139
  /**
121
140
  * get the logging level of current instance.
122
141
  */
123
- function getLevel () {
142
+ function getLevel() {
124
143
  if (logger) {
125
144
  return logger.level;
126
145
  } else {
@@ -134,7 +153,7 @@ function getLevel () {
134
153
  * already made.
135
154
  * @param {v4uuid} applicationUUID
136
155
  */
137
- function getLogger (applicationUUID = process.env.applicationUUID) {
156
+ function getLogger(applicationUUID = process.env.applicationUUID) {
138
157
  if (logger) {
139
158
  return logger;
140
159
  }
@@ -146,9 +165,8 @@ function getLogger (applicationUUID = process.env.applicationUUID) {
146
165
  fs.chmodSync(`${logFileName}`, 0o777);
147
166
  fs.chmodSync(`${initLogFileName}`, 0o777);
148
167
  } catch (error) {
149
- logger.error("Error while setting up permissions on log files", error);
150
168
  }
151
- initLogger.info("[STEP-2] => Generating unique identifier:",applicationUUID )
169
+ initLogger.info("[STEP-2] => Generating unique identifier:", applicationUUID)
152
170
  if (NRAgent) {
153
171
  setLevel(NRAgent.config.logging.level);
154
172
  }
@@ -159,14 +177,14 @@ function getLogger (applicationUUID = process.env.applicationUUID) {
159
177
  }
160
178
  }
161
179
 
162
- function reCreateLogger (applicationUUID) {
180
+ function reCreateLogger(applicationUUID) {
163
181
  initialize(applicationUUID);
164
182
  logger = log4js.getLogger('NR_CSEC');
165
183
  setLevel(logger.level);
166
184
  updateModuleLoggers(logger);
167
185
  }
168
186
 
169
- function getInitLogger () {
187
+ function getInitLogger() {
170
188
  const initLogger = log4js.getLogger('NR_CSEC_INIT');
171
189
  return initLogger;
172
190
  }
@@ -49,7 +49,9 @@ module.exports = {
49
49
  COLLECTOR_CONFIG: 100,
50
50
  BLOCKING: 101,
51
51
  POLICY_ERROR: 102,
52
- OBEY_WS_RECONNECT:12
52
+ OBEY_WS_RECONNECT:12,
53
+ ENTER_IAST_COOLDOWN:13,
54
+ IAST_RECORD_DELETE_CONFIRMATION:14
53
55
 
54
56
  },
55
57
  JSON_NAME: {
@@ -74,7 +76,6 @@ module.exports = {
74
76
  (process.env[AWS_EXECUTION_ENV_VAR] || '').match(AWS_LAMBDA_NODE_EXEC_ENV_IDENTIFIER)
75
77
  ),
76
78
  LAMBDA_RUNTIME_DIR_VAR: 'LAMBDA_RUNTIME_DIR',
77
- CSEC_LAST_FUZZ_REQUEST_TIME: 'CSEC_LAST_FUZZ_REQUEST_TIME',
78
79
  NR_CSEC_FUZZ_REQUEST_ID: 'nr-csec-fuzz-request-id',
79
80
  EMPTY_APPLICATION_UUID: '--0--',
80
81
  QUESTIONMARK: '?',
@@ -95,7 +95,7 @@ function writeSnapshot() {
95
95
  commonUtils.removeOlderSnapshots();
96
96
  fs.writeFile(statusFile, snapshot, { mode: 0o777 }, function (err) {
97
97
  if (err) {
98
- logger.error(err);
98
+ logger.debug(err.message);
99
99
  } else {
100
100
  logger.info('Snapshot updated to file: %s', statusFile);
101
101
  fs.chmod(statusFile, 0o777, (err) => {
@@ -4,8 +4,6 @@
4
4
  */
5
5
 
6
6
  'use strict';
7
- const path = require('path');
8
- const RingBuffer = require('ringbufferjs');
9
7
  const LOG_MESSAGES = require('./sec-agent-constants').LOG_MESSAGES;
10
8
 
11
9
  const { Agent } = require('./agent');
@@ -14,31 +12,21 @@ const hc = require('./health-check');
14
12
  const applicationInfo = require('./applicationinfo').getInstance();
15
13
  const logger = require('./logging').getLogger(applicationInfo.applicationUUID);
16
14
  const initLogger = require('./logging').getInitLogger();
17
- const { WorkerMessage, WORKER_STATUS } = require('./worker-entities');
18
15
  const commonUtils = require('./commonUtils');
19
16
  const API = require('../../../nr-security-api');
20
17
  const NRAgent = API.getNRAgent();
21
18
  const {
22
19
  SecWebSocket,
23
20
  setWebSocketConn,
24
- aquireWebSocket,
25
21
  ResponseHandler: {
26
- handle: handleServerResponse,
27
22
  setLogger: setResponseHandlerLogger
28
23
  }
29
24
  } = require('./connections/websocket');
30
25
  const { HC_INTERVAL_MS } = require('../../resources/config');
31
- const { IS_LAMBDA_ENV, LAMBDA_ENABLE_RESPONSE_BLOCKING, LOG_DIR } = require('./sec-agent-constants');
26
+ const { LOG_DIR } = require('./sec-agent-constants');
32
27
  const statusUtils = require('./statusUtils');
33
28
  const njsAgentConstants = require('./sec-agent-constants');
34
29
 
35
- const MAX_BUSY_WAIT_TIME = 5000; // ms
36
- const workerSupported = commonUtils.hasWorker();;
37
- const filePath = path.join(__dirname, 'worker.js');
38
- const localQueue = new RingBuffer(1000);
39
-
40
- let busy = false;
41
- let wsWorker;
42
30
  let wsInstance;
43
31
  let dispatcher;
44
32
 
@@ -65,11 +53,8 @@ const initialize = function () {
65
53
 
66
54
  setResponseHandlerLogger(logger);
67
55
 
68
- if (workerSupported) {
69
- initiateInWorkerThread();
70
- } else {
71
- initializeInMainThread();
72
- }
56
+ initializeInMainThread();
57
+
73
58
  // we'll dispatch the application info if it is updated
74
59
  Agent.eventEmitter.on(Agent.EVENTS.APPLICATION_INFO_UPDATE_EVENT, (applicationInfo) => {
75
60
  if (!NRAgent || (NRAgent && applicationInfo.entityGuid)) {
@@ -78,12 +63,7 @@ const initialize = function () {
78
63
  });
79
64
  Agent.eventEmitter.on(Agent.EVENTS.RECONNECT_WS_EVENT, () => {
80
65
  setWebSocketConn();
81
- if (workerSupported) {
82
- const reConnectMsg = new WorkerMessage(WorkerMessage.TYPE.RECONNECT, {});
83
- wsWorker.postMessage(reConnectMsg);
84
- } else {
85
- wsInstance.reconnect();
86
- }
66
+ wsInstance.reconnect();
87
67
  });
88
68
 
89
69
  setTimeout(() => {
@@ -106,102 +86,11 @@ function initializeInMainThread() {
106
86
  dispatcher = function dispatcher(message) {
107
87
  wsInstance.dispatch(message);
108
88
  };
109
-
110
- // Setup the event listeners
111
- wsInstance.event.on(SecWebSocket.Events.BUSY, function () {
112
- busy = true;
113
- });
114
- wsInstance.event.on(SecWebSocket.Events.INACTIVE, function () {
115
- busy = false;
116
- });
117
89
  } else {
118
90
  return wsInstance;
119
91
  }
120
92
  }
121
93
 
122
- /**
123
- * This initiates the ws in worker thread
124
- */
125
- function initiateInWorkerThread() {
126
- if (workerSupported) {
127
- process.env.WS_WORKER_STATUS = WORKER_STATUS.INITIALIZING;
128
- try {
129
- setWebSocketConn();
130
- const { Worker, SHARE_ENV } = require('worker_threads');
131
- wsWorker = new Worker(filePath, {
132
- workerData: {
133
- applicationInfo
134
- },
135
- env: SHARE_ENV
136
- });
137
- wsWorker.on('message', handleWorkerMessage);
138
- wsWorker.on('error', (err) => {
139
- logger.error('Exception in web socket worker:', err.message);
140
- wsWorker = new Worker(filePath, {
141
- workerData: {
142
- applicationInfo
143
- }, env: SHARE_ENV
144
- });
145
- });
146
- dispatcher = function dispatcher(message) {
147
- if (process.env.WS_WORKER_STATUS !== WORKER_STATUS.RUNNING) {
148
- localQueue.enq(message);
149
- return;
150
- }
151
- // websocket is aquired here and then
152
- // released in worker thread when the
153
- // handoff to websocket is confirmed
154
- aquireWebSocket();
155
- const msg = new WorkerMessage(WorkerMessage.TYPE.MESSAGE, message);
156
- wsWorker.postMessage(msg);
157
- };
158
- logger.info(LOG_MESSAGES.NODE_VERSION_MSG_WORKER, process.version);
159
- } catch (error) {
160
- logger.debug('error is:', error);
161
- }
162
- }
163
- }
164
-
165
- /**
166
- * This handles any messages received from worker
167
- * if websocket worker is initialized
168
- *
169
- * @param {JSON} json
170
- */
171
- function handleWorkerMessage(json) {
172
- const msg = WorkerMessage.parseFromObject(json);
173
- switch (msg.type) {
174
- case WorkerMessage.TYPE.MESSAGE: {
175
- logger.debug(LOG_MESSAGES.MSG_FROM_WORKKER, msg.getPayload());
176
- handleServerResponse(msg.getPayload());
177
- break;
178
- }
179
- case WorkerMessage.TYPE.FLUSH: {
180
- const { status } = msg.getPayload();
181
- if (status === 'flushed') {
182
- logger.debug('Message from worker thread: Flush Completed');
183
- }
184
- break;
185
- }
186
- case WorkerMessage.TYPE.IC_READY_FOR_EVENTS: {
187
- break;
188
- }
189
- case WorkerMessage.TYPE.BUSY: {
190
- busy = true;
191
- break;
192
- }
193
- case WorkerMessage.TYPE.INACTIVE: {
194
- busy = false;
195
- break;
196
- }
197
- case WorkerMessage.TYPE.ERROR: {
198
- statusUtils.addErrortoBuffer(msg.getPayload());
199
- break;
200
- }
201
- default:
202
- }
203
- }
204
-
205
94
  /**
206
95
  * Sends Agent HelthCheck to Validator.
207
96
  */
@@ -267,66 +156,14 @@ function sendEvent(event, callback = DEFAULT_EVENT_SEND_CB) {
267
156
  callback();
268
157
  };
269
158
 
270
- /**
271
- * Flushes local queue to the worker
272
- */
273
- function flushLocalQueue() {
274
- if (!workerSupported) return;
275
-
276
- while (!localQueue.isEmpty()) {
277
- dispatcher(localQueue.deq());
278
- }
279
- }
280
-
281
- /**
282
- * Waits for websocket to get idel before
283
- * exiting the lambda function
284
- * @param {Number} startTime
285
- */
286
- function busyWaitOnWorkerThread(startTime = Date.now()) {
287
- if (!workerSupported) return;
288
-
289
- const workerInitiatedOnWait = process.env.WS_WORKER_STATUS === WORKER_STATUS.RUNNING;
290
- const enableWait = !IS_LAMBDA_ENV || process.env[LAMBDA_ENABLE_RESPONSE_BLOCKING] === 'true';
291
-
292
- let flushed = false;
293
- let wait = (
294
- process.env.CSEC_WS_STATE === SecWebSocket.States.CONNECTING ||
295
- (
296
- enableWait &&
297
- process.env.CSEC_WS_STATE === SecWebSocket.States.BUSY
298
- )
299
- ) && (startTime + MAX_BUSY_WAIT_TIME > Date.now());
300
- while (wait) {
301
- wait = (
302
- process.env.CSEC_WS_STATE === SecWebSocket.States.CONNECTING ||
303
- (
304
- enableWait &&
305
- process.env.CSEC_WS_STATE === SecWebSocket.States.BUSY
306
- )
307
- ) && (startTime + MAX_BUSY_WAIT_TIME > Date.now());
308
-
309
- if (!flushed && !workerInitiatedOnWait && process.env.WS_WORKER_STATUS === WORKER_STATUS.RUNNING) {
310
- flushed = true;
311
- flushLocalQueue();
312
- }
313
- }
314
- }
315
159
 
316
160
  function obeyReconnect() {
317
- if (workerSupported) {
318
- const reConnectMsg = new WorkerMessage(WorkerMessage.TYPE.OBEY_RECONNECT, {});
319
- wsWorker.postMessage(reConnectMsg);
320
- } else {
321
- wsInstance.obeyReconnect();
322
- }
161
+ wsInstance.obeyReconnect();
323
162
  }
324
163
 
325
164
  module.exports = {
326
165
  initialize,
327
166
  write: sendEvent,
328
167
  dispatcher: getDispatcherAndSendEvent,
329
- flushLocalQueue,
330
- busyWaitOnWorkerThread,
331
168
  obeyReconnect
332
169
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newrelic/security-agent",
3
- "version": "0.1.3",
3
+ "version": "0.2.1",
4
4
  "description": "New Relic Security Agent for Node.js",
5
5
  "main": "index.js",
6
6
  "jsonVersion": "1.0.1",
@@ -35,9 +35,9 @@
35
35
  "url": "https://github.com/newrelic/csec-node-agent.git"
36
36
  },
37
37
  "dependencies": {
38
- "@aws-sdk/client-lambda": "^3.348.0",
38
+ "@aws-sdk/client-lambda": "^3.363.0",
39
39
  "axios": "0.21.4",
40
- "check-disk-space": "^3.4.0",
40
+ "check-disk-space": "3.3.1",
41
41
  "content-type": "^1.0.5",
42
42
  "fast-safe-stringify": "^2.1.1",
43
43
  "find-package-json": "^1.2.0",
@@ -51,7 +51,7 @@
51
51
  "pretty-bytes": "^5.6.0",
52
52
  "request-ip": "^3.3.0",
53
53
  "ringbufferjs": "^2.0.0",
54
- "semver": "^7.5.3",
54
+ "semver": "^7.5.4",
55
55
  "sync-request": "^6.1.0",
56
56
  "unescape": "^1.0.1",
57
57
  "unescape-js": "^1.1.4",