@newrelic/security-agent 0.5.0 → 0.7.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.
Files changed (33) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +1 -0
  3. package/THIRD_PARTY_NOTICES.md +1 -211
  4. package/lib/instrumentation-security/core/sec-utils.js +1 -0
  5. package/lib/instrumentation-security/hooks/@nestjs/nr-nestjs-core.js +1 -0
  6. package/lib/instrumentation-security/hooks/express/nr-express.js +2 -0
  7. package/lib/instrumentation-security/hooks/fastify/nr-fastify.js +1 -0
  8. package/lib/instrumentation-security/hooks/fs/nr-fs.js +56 -20
  9. package/lib/instrumentation-security/hooks/hapi/nr-hapi.js +2 -1
  10. package/lib/instrumentation-security/hooks/http/nr-http.js +96 -4
  11. package/lib/instrumentation-security/hooks/koa/@koa/nr-@koa-router.js +3 -1
  12. package/lib/instrumentation-security/hooks/ldap/nr-ldap.js +1 -0
  13. package/lib/instrumentation-security/hooks/mongodb/common.js +2 -0
  14. package/lib/instrumentation-security/hooks/mongodb/nr-mongodb.js +1 -1
  15. package/lib/instrumentation-security/hooks/mysql/nr-mysql.js +5 -2
  16. package/lib/instrumentation-security/hooks/native/nr-childProcess.js +3 -0
  17. package/lib/instrumentation-security/hooks/postgres/nr-postgres.js +1 -0
  18. package/lib/instrumentation-security/hooks/require/nr-require.js +3 -2
  19. package/lib/instrumentation-security/hooks/restify/nr-restify.js +3 -1
  20. package/lib/instrumentation-security/hooks/xpath/nr-xpath.js +4 -2
  21. package/lib/nr-security-agent/index.js +9 -4
  22. package/lib/nr-security-agent/lib/core/Auth-headers.js +7 -0
  23. package/lib/nr-security-agent/lib/core/LogMessage.js +40 -14
  24. package/lib/nr-security-agent/lib/core/commonUtils.js +35 -4
  25. package/lib/nr-security-agent/lib/core/connections/aws-lambda-client.js +6 -8
  26. package/lib/nr-security-agent/lib/core/connections/websocket/response/fuzz-request-handler.js +21 -6
  27. package/lib/nr-security-agent/lib/core/connections/websocket/response/index.js +5 -2
  28. package/lib/nr-security-agent/lib/core/connections/websocket/websocket.js +20 -1
  29. package/lib/nr-security-agent/lib/core/sec-agent-constants.js +3 -0
  30. package/lib/nr-security-agent/lib/core/sec-util.js +14 -6
  31. package/lib/nr-security-agent/lib/core/statusUtils.js +4 -1
  32. package/lib/nr-security-agent/lib/core/websocket-client.js +19 -8
  33. package/package.json +4 -5
@@ -46,7 +46,7 @@ const CSEC_HOME_TMP = `${CSEC_HOME}/nr-security-home/tmp/language-agent/${proces
46
46
  * @param {*} moduleName
47
47
  */
48
48
  function initialize(shim, mod, moduleName) {
49
- logger.info('Instrumenting HTTP module');
49
+ logger.info(`Instrumenting ${moduleName}`);
50
50
  emitHook(shim, mod, moduleName);
51
51
  createServerHook(shim, mod, moduleName);
52
52
  outboundHook(shim, mod, 'request', moduleName);
@@ -87,7 +87,11 @@ function setupRequestMapCleanup() {
87
87
  * @param {*} moduleName
88
88
  */
89
89
  function outboundHook(shim, mod, method, moduleName) {
90
+ logger.debug(`Instrumenting ${moduleName}.${method}`);
90
91
  shim.wrap(mod, method, function makeRequestWrapper(shim, fn) {
92
+ if (!shim.isFunction(fn)) {
93
+ return fn
94
+ }
91
95
  return function requestWrapper() {
92
96
  const request = requestManager.getRequest(shim);
93
97
  const data = {};
@@ -206,6 +210,7 @@ function addRequestData(shim, request) {
206
210
  const data = Object.assign({});
207
211
  const segment = shim.getActiveSegment();
208
212
  if (segment && segment.transaction) {
213
+ data.protocol = (request.connection && request.connection.encrypted) ? 'https' : 'http';
209
214
  data.body = null;
210
215
  data.headers = request.headers;
211
216
  data.url = request.url;
@@ -255,6 +260,10 @@ function addRequestData(shim, request) {
255
260
  */
256
261
  function emitHook(shim, mod, moduleName) {
257
262
  shim.wrap(mod && mod.Server && mod.Server.prototype, 'emit', function makeEmitWrapper(shim, fn) {
263
+ logger.debug(`Instrumenting ${moduleName}.Server.prototype.emit`);
264
+ if (!shim.isFunction(fn)) {
265
+ return fn
266
+ }
258
267
  return function emitWrapper() {
259
268
  const req = arguments[1];
260
269
  const resp = arguments[2];
@@ -265,6 +274,9 @@ function emitHook(shim, mod, moduleName) {
265
274
  }
266
275
 
267
276
  shim.wrap(req, 'on', function makeOnWrapper(shim, fn) {
277
+ if (!shim.isFunction(fn)) {
278
+ return fn
279
+ }
268
280
  return function OnWrapper() {
269
281
  if (!requestManager.getRequest(shim)) {
270
282
  addRequestData(shim, req);
@@ -292,10 +304,17 @@ function emitHook(shim, mod, moduleName) {
292
304
  * @param {*} shim
293
305
  * @param {*} mod
294
306
  */
295
- function createServerHook(shim, mod) {
307
+ function createServerHook(shim, mod, moduleName) {
296
308
  shim.wrap(mod, 'createServer', function createServerWrapper(shim, fn) {
309
+ logger.debug(`Instrumenting ${moduleName}.createServer`);
310
+ if (!shim.isFunction(fn)) {
311
+ return fn
312
+ }
297
313
  return function wrappedCreateServer() {
298
314
  shim.wrap(arguments, '0', function appWrapper(shim, fn) {
315
+ if (!shim.isFunction(fn)) {
316
+ return fn
317
+ }
299
318
  return function wrappedApp() {
300
319
  let req = arguments[0];
301
320
  if (!requestManager.getRequest(shim)) {
@@ -316,6 +335,9 @@ function createServerHook(shim, mod) {
316
335
  */
317
336
  function onDataHook(shim, mod) {
318
337
  shim.wrap(mod, '1', function makeOnDataWrapper(shim, fn) {
338
+ if (!shim.isFunction(fn)) {
339
+ return fn
340
+ }
319
341
  return function onDataWrapper() {
320
342
  const chunk = arguments[0];
321
343
  const chunkType = typeof chunk;
@@ -347,6 +369,9 @@ function responseHook(resp, req, shim) {
347
369
  resp.res.body = EMPTY_STRING;
348
370
 
349
371
  shim.wrap(resp, 'write', function makeWriteWrapper(shim, fn) {
372
+ if (!shim.isFunction(fn)) {
373
+ return fn
374
+ }
350
375
  return function wrappedWrite() {
351
376
  const response = this;
352
377
  responseBodyCompute(response, arguments);
@@ -355,6 +380,9 @@ function responseHook(resp, req, shim) {
355
380
  })
356
381
  // wrapper for response.end()
357
382
  shim.wrap(resp, 'end', function makeEndWrapper(shim, fn) {
383
+ if (!shim.isFunction(fn)) {
384
+ return fn
385
+ }
358
386
  return function wrappedEnd() {
359
387
  const response = this;
360
388
  responseBodyCompute(response, arguments);
@@ -362,30 +390,94 @@ function responseHook(resp, req, shim) {
362
390
  const construct = API.checkForReflectedXSS(request, response.res.body, response.getHeaders());
363
391
  const policy = API.getPolicy();
364
392
  const dynamicScanningFlag = policy.data ? (policy.data.vulnerabilityScan?.enabled && policy.data.vulnerabilityScan.iastScan.enabled) : false;
365
- if (request && (construct || dynamicScanningFlag)) {
393
+ const type = response.getHeader(CONTENT_TYPE);
394
+ let isUnsupportedType = isUnsupportedContentType(type);
395
+
396
+ if (request && (construct || dynamicScanningFlag) && !isUnsupportedType) {
366
397
  const args = [];
367
398
  args.push(construct);
368
399
  args.push(response.res.body);
369
400
  const traceObject = secUtils.getTraceObject(shim);
370
401
  const secMetadata = securityMetaData.getSecurityMetaData(request, args, traceObject, secUtils.getExecutionId(), EVENT_TYPE.REFLECTED_XSS, EVENT_CATEGORY.REFLECTED_XSS)
371
402
  const secEvent = API.generateSecEvent(secMetadata);
372
-
403
+ secEvent.httpResponse = {};
404
+ secEvent.httpResponse.contentType = response.getHeader(CONTENT_TYPE);
373
405
  API.sendEvent(secEvent);
374
406
  }
375
407
  return fn.apply(this, arguments);
376
408
  }
377
409
  })
378
410
  }
411
+ /**
412
+ * Utility to check unsupported content types
413
+ * @param {*} conType
414
+ * @returns
415
+ */
416
+ function isUnsupportedContentType(conType) {
417
+ try {
418
+ if (!conType) {
419
+ return true;
420
+ }
421
+ const unsupportedTypes = ["video/",
422
+ "image/",
423
+ "font/",
424
+ "audio/",
425
+ "application/zip",
426
+ "application/epub+zip",
427
+ "application/gzip",
428
+ "application/java-archive",
429
+ "application/msword",
430
+ "application/octet-stream",
431
+ "application/ogg",
432
+ "application/pdf",
433
+ "application/rtf",
434
+ "application/vnd.amazon.ebook",
435
+ "application/vnd.apple.installer+xml",
436
+ "application/vnd.ms-excel",
437
+ "application/vnd.ms-fontobject",
438
+ "application/vnd.ms-powerpoint",
439
+ "application/vnd.oasis.opendocument.presentation",
440
+ "application/vnd.oasis.opendocument.spreadsheet",
441
+ "application/vnd.oasis.opendocument.text",
442
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
443
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
444
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
445
+ "application/vnd.rar",
446
+ "application/vnd.visio",
447
+ "application/x-7z-compressed",
448
+ "application/x-abiword",
449
+ "application/x-bzip",
450
+ "application/x-bzip2",
451
+ "application/x-cdf",
452
+ "application/x-freearc",
453
+ "application/x-tar",
454
+ "application/zip",
455
+ "text/calendar"
456
+ ];
457
+
458
+ const startsWithAny = unsupportedTypes.some(prefix => conType.startsWith(prefix));
459
+ return startsWithAny;
460
+ } catch (error) {
461
+ logger.debug("Error while checking unsupported content type");
462
+ }
463
+
464
+ }
379
465
 
380
466
  function responseBodyCompute(response, args) {
381
467
  let encoding = UTF8;
382
468
  const type = response.getHeader(CONTENT_TYPE);
469
+ let isUnsupportedType = isUnsupportedContentType(type);
470
+ if (isUnsupportedType) {
471
+ return;
472
+ }
473
+
383
474
  let contentType = TEXT_HTML;
384
475
  if (type) {
385
476
  const obj = ConType.parse(type);
386
477
  contentType = obj.type;
387
478
  encoding = obj.parameters.charset;
388
479
  }
480
+
389
481
  if (args[0]) {
390
482
  switch (contentType) {
391
483
  case APPLICATION_JSON:
@@ -20,7 +20,7 @@ const logger = API.getLogger();
20
20
  * @param {*} moduleName
21
21
  */
22
22
  function initialize(shim, mod, moduleName) {
23
- logger.info('Instrumenting @koa/router');
23
+ logger.info(`Instrumenting ${moduleName}`);
24
24
  const VerbMethods = ['all', 'delete', 'get', 'head', 'opts', 'post', 'put', 'patch'];
25
25
 
26
26
  // RouteMap hooks
@@ -29,6 +29,7 @@ function initialize(shim, mod, moduleName) {
29
29
  if (!shim.isFunction(fn)) {
30
30
  return fn
31
31
  }
32
+ logger.debug(`Instrumenting ${moduleName}.prototype.${fun}`);
32
33
  return function wrappedRoute() {
33
34
  try {
34
35
  const stakTrace = secUtils.traceElementForRoute();
@@ -59,6 +60,7 @@ function initialize(shim, mod, moduleName) {
59
60
  */
60
61
  function paramHook(shim, mod, moduleName) {
61
62
  shim.wrap(mod && mod.prototype, 'params', function wrapMatch(shim, fn) {
63
+ logger.debug(`Instrumenting ${moduleName}.prototype.params`);
62
64
  return function wrappedMatch() {
63
65
  const segment = shim.getActiveSegment();
64
66
  if (segment && segment.transaction) {
@@ -35,6 +35,7 @@ function initialize(shim, mod, moduleName){
35
35
  */
36
36
  function ldapHooks(shim, mod, methodName, moduleName){
37
37
  shim.wrap(mod, methodName, function makeWrapper(shim,fn){
38
+ logger.debug(`Instrumenting ${moduleName}.${methodName}`);
38
39
  return function wrapper(){
39
40
  const param = {};
40
41
  param.name = arguments[0];
@@ -55,6 +55,7 @@ function payloadType(obj) {
55
55
 
56
56
  function queryHook(shim, mod, method) {
57
57
  shim.wrap(mod, method, function makeQueryWrapper(shim, fn) {
58
+ logger.debug(`Instrumenting mongodb.${method}`);
58
59
  return function queryWrapper() {
59
60
  const request = requestManager.getRequest(shim);
60
61
  if (CURSOR_OPS.includes(method)) {
@@ -194,6 +195,7 @@ function callbackHook(shim, mod, fun, secEvent) {
194
195
 
195
196
  common.queryHookV2 = function queryHookV2(shim, mod, method) {
196
197
  shim.wrap(mod, method, function makeQueryWrapper(shim, fn) {
198
+ logger.debug(`Instrumenting mongodb.${method}`);
197
199
  return function queryWrapper() {
198
200
  const request = requestManager.getRequest(shim);
199
201
  if (CURSOR_OPS.includes(method)) {
@@ -32,7 +32,7 @@ module.exports = initialize;
32
32
  * @param {Shim} shim
33
33
  */
34
34
  function initialize(shim, mongodb, moduleName) {
35
- logger.info("Instrumenting Mongodb");
35
+ logger.info(`Instrumenting ${moduleName}`);
36
36
  if (!mongodb) {
37
37
  return;
38
38
  }
@@ -18,7 +18,7 @@ const symbols = {
18
18
  createPoolCluster: Symbol('createPoolCluster'),
19
19
  wrappedPoolConnection: Symbol('wrappedPoolConnection')
20
20
  }
21
-
21
+ let modName = '';
22
22
  module.exports = initialize;
23
23
 
24
24
  /**
@@ -28,6 +28,7 @@ module.exports = initialize;
28
28
  * @param {*} moduleName
29
29
  */
30
30
  function initialize(shim, mysql, moduleName) {
31
+ modName = moduleName;
31
32
  logger.info("Instrumenting", moduleName);
32
33
  if (shim._moduleRoot.includes("mysql2")) {
33
34
  promiseInitialize(shim, mysql, moduleName);
@@ -119,6 +120,7 @@ function wrapGetConnection(shim, connectable) {
119
120
 
120
121
  const proto = Object.getPrototypeOf(connectable);
121
122
  shim.wrap(proto, "getConnection", function doWrapGetConnection(shim, fn) {
123
+ logger.debug(`Instrumenting ${modName}.getConnection`);
122
124
  return function wrappedGetConnection() {
123
125
  const args = shim.toArray(arguments);
124
126
  const cbIdx = args.length - 1;
@@ -208,7 +210,7 @@ function extractQueryArgs(shim, args) {
208
210
  // query(opts [, values], callback)
209
211
  rawQuery = args[0].sql;
210
212
  try {
211
- if (args[0].values && typeof args[0].values == 'object') {
213
+ if (args[0].values && typeof args[0].values == 'object') {
212
214
  param = Object.values(args[0].values)
213
215
  }
214
216
  } catch (error) {
@@ -240,6 +242,7 @@ function extractQueryArgs(shim, args) {
240
242
  */
241
243
  function queryHook(shim, mod, method, isPoolQuery) {
242
244
  shim.wrap(mod, method, function makeQueryWrapper(shim, fn) {
245
+ logger.debug(`Instrumenting ${modName}.${method}`);
243
246
  return function queryWrapper() {
244
247
  const parameters = extractQueryArgs(shim, arguments);
245
248
  shim.interceptedArgs = parameters;
@@ -26,6 +26,7 @@ function initialize(shim, childProcess, moduleName) {
26
26
  */
27
27
  function execFileHook(shim, childProcess, moduleName) {
28
28
  shim.wrap(childProcess, "execFile", function makeWrapper(shim, fn) {
29
+ logger.debug(`Instrumenting ${moduleName}.execFile`);
29
30
  return function wrapper() {
30
31
  const interceptedArgs = [arguments[0]];
31
32
  shim.interceptedArgs = interceptedArgs;
@@ -54,6 +55,7 @@ function execFileHook(shim, childProcess, moduleName) {
54
55
  */
55
56
  function spawnSyncHook(shim, childProcess, moduleName) {
56
57
  shim.wrap(childProcess, "spawn", function makeWrapper(shim, fn) {
58
+ logger.debug(`Instrumenting ${moduleName}.spawnSync`);
57
59
  return function wrapper() {
58
60
  const interceptedArgs = arguments[0].args;
59
61
  shim.interceptedArgs = interceptedArgs;
@@ -83,6 +85,7 @@ function spawnSyncHook(shim, childProcess, moduleName) {
83
85
  */
84
86
  function spawnHook(shim, childProcess, moduleName) {
85
87
  shim.wrap(childProcess, "spawn", function makeWrapper(shim, fn) {
88
+ logger.debug(`Instrumenting ${moduleName}.spawn`);
86
89
  return function wrapper() {
87
90
  let param = [];
88
91
  param.push(arguments[0]);
@@ -66,6 +66,7 @@ module.exports = function initialize(shim, pgsql, moduleName) {
66
66
 
67
67
  function queryHook(shim, mod, method){
68
68
  shim.wrap(mod, method, function makeQueryWrapper(shim, fn){
69
+ logger.debug(`Instrumenting pg.${method}`);
69
70
  return function queryWrapper(){
70
71
  const request = requestManager.getRequest(shim);
71
72
  const sqlArgs = [];
@@ -73,7 +73,8 @@ function requireHook(shim, moduleName, parent) {
73
73
  }
74
74
  }
75
75
  if (request) {
76
- const interceptedArgs = [moduleName];
76
+ let resolvedModulePath = require.resolve(moduleName)
77
+ const interceptedArgs = [resolvedModulePath];
77
78
  let traceObject;
78
79
  if (!fallback) {
79
80
  traceObject = secUtils.getTraceObject(shim);
@@ -86,7 +87,7 @@ function requireHook(shim, moduleName, parent) {
86
87
  API.sendEvent(secEvent);
87
88
  }
88
89
  } catch (error) {
89
-
90
+
90
91
  }
91
92
 
92
93
 
@@ -21,12 +21,13 @@ const logger = API.getLogger();
21
21
  * @param {*} moduleName
22
22
  */
23
23
  function initialize(shim, mod, moduleName) {
24
- logger.info('Instrumenting Restify');
24
+ logger.info(`Instrumenting ${moduleName}`);
25
25
  try {
26
26
  const registryRadix = shim.require("./lib/routerRegistryRadix");
27
27
 
28
28
  //routerRadix hook
29
29
  shim.wrap(registryRadix && registryRadix.prototype, 'add', function makeWrapper(shim, fn) {
30
+ logger.info(`Instrumenting registryRadix.prototype.add`);
30
31
  return function wrapper() {
31
32
  if (arguments[0]) {
32
33
  try {
@@ -47,6 +48,7 @@ function initialize(shim, mod, moduleName) {
47
48
  const router = shim.require("./lib/router");
48
49
 
49
50
  shim.wrap(router && router.prototype, 'lookup', function lookupWrapper(shim, fn) {
51
+ logger.info(`Instrumenting router.prototype.lookup`);
50
52
  return function wrappedLookup() {
51
53
  const result = fn.apply(this, arguments);
52
54
  extractParams(shim, arguments[0]);
@@ -27,7 +27,7 @@ function initialize(shim, mod, moduleName){
27
27
  xpathHooks(shim, mod, 'useNamespaces', moduleName);
28
28
  }
29
29
  else if(moduleName==='xpath.js'){
30
- wrappedXPathDotJS(shim, mod);
30
+ wrappedXPathDotJS(shim, mod, moduleName);
31
31
  }
32
32
 
33
33
  }
@@ -40,6 +40,7 @@ function initialize(shim, mod, moduleName){
40
40
  */
41
41
  function xpathHooks(shim, mod, methodName, moduleName){
42
42
  shim.wrap(mod, methodName, function makeWrapper(shim,fn){
43
+ logger.debug(`Instrumenting ${moduleName}.${methodName}`);
43
44
  return function wrapper(){
44
45
  const interceptedArgs = [arguments[0]];
45
46
  shim.interceptedArgs = interceptedArgs;
@@ -67,8 +68,9 @@ function xpathHooks(shim, mod, methodName, moduleName){
67
68
  * @param {*} shim
68
69
  * @param {*} mod
69
70
  */
70
- function wrappedXPathDotJS(shim, mod){
71
+ function wrappedXPathDotJS(shim, mod, moduleName){
71
72
  const wrappedExport = shim.wrapExport(mod, function wrapXpathJSModule(shim, fn) {
73
+ logger.debug(`Instrumenting ${moduleName}`);
72
74
  return function wrappedXpathJSModule() {
73
75
  const interceptedArgs = [arguments[1]];
74
76
  shim.interceptedArgs = interceptedArgs;
@@ -14,6 +14,9 @@ const agentConfig = require('./resources/config');
14
14
  const shaSizeUtil = require('./lib/core/sha-size-util');
15
15
  const njsAgentConstants = require('./lib/core/sec-agent-constants');
16
16
 
17
+ const NRLogger = API.newrelic.shim.logger.child({ component: 'security-agent' });
18
+ NRLogger.info("Starting New Relic Node.js Security Agent ");
19
+
17
20
  const {
18
21
  IS_LAMBDA_ENV,
19
22
  AWS_LAMBDA_FUNCTION_NAME_ENV_IDENTIFIER,
@@ -106,6 +109,7 @@ function initialize() {
106
109
  initLogger.info("[STEP-3] => Gathering information about the application :", JSON.stringify(applicationInfo));
107
110
  if (NRAgent) {
108
111
  NRAgent.on('started', () => {
112
+ NRLogger.info("Started New Relic Node.js Security Agent");
109
113
  if (NRAgent.config.security.enabled || !NRAgent.config.high_security) {
110
114
  wsClient.initialize();
111
115
  logger.info('NR Agent started with agent_run_id:', NRAgent.config.run_id, NRAgent.config.account_id);
@@ -113,7 +117,8 @@ function initialize() {
113
117
  Agent.setNRAgent(NRAgent);
114
118
  }
115
119
  else {
116
- logger.info("security.enabled flag is set to false")
120
+ logger.warn("security.enabled flag is set to false");
121
+ NRLogger.warn("Failed to Start New Relic Node.js Security Agent. Please check security.enabled and high_security flags");
117
122
  }
118
123
  });
119
124
  }
@@ -131,9 +136,9 @@ function initialize() {
131
136
  }
132
137
  }
133
138
  logger.info(LOG_MESSAGES.AGENT_INFO, applicationInfo.collectorVersion, applicationInfo.jsonVersion, applicationInfo.buildNumber);
134
-
139
+
135
140
  applicationInfoModule.addProperty('serverInfo.deployedApplications', applications);
136
-
141
+
137
142
  shaSizeUtil.setLogger(logger);
138
143
 
139
144
  // Initialize Agent Status
@@ -159,7 +164,7 @@ function getProcCMDLineSanitized(applicationInfoModule) {
159
164
  }
160
165
 
161
166
  (() => {
162
- if(!NRAgent.config.security.enabled){
167
+ if (!NRAgent.config.security.enabled) {
163
168
  logger.warn("security.enabled flag is set to false");
164
169
  return;
165
170
  }
@@ -9,6 +9,8 @@ const appInfo = require('./applicationinfo').getInstance();
9
9
  const logs = require('./logging');
10
10
  const logger = logs.getLogger();
11
11
  const initLogger = logs.getInitLogger();
12
+ const LinkingMetaData = require('./LinkingMetadata');
13
+ const LogMessage = require('./LogMessage');
12
14
 
13
15
 
14
16
  /* eslint-disable camelcase */
@@ -20,6 +22,7 @@ function AuthHeaders() {
20
22
  try {
21
23
  const NRAgent = API.getNRAgent();
22
24
  authHeaders = {}
25
+ const metadata = LinkingMetaData.getLinkingMetadata();
23
26
  authHeaders['NR-CSEC-CONNECTION-TYPE'] = 'LANGUAGE_COLLECTOR';
24
27
  authHeaders['NR-AGENT-RUN-TOKEN'] = NRAgent.config.run_id;
25
28
  const COLLECTOR_VERSION = appInfo.collectorVersion || '';
@@ -32,8 +35,12 @@ function AuthHeaders() {
32
35
  authHeaders['NR-ACCOUNT-ID'] = NRAgent.config.account_id;
33
36
  authHeaders['NR-LICENSE-KEY'] = NRAgent ? NRAgent.config.license_key : '';
34
37
  authHeaders["NR-CSEC-IAST-DATA-TRANSFER-MODE"] = "PULL";
38
+ authHeaders['NR-CSEC-ENTITY-NAME'] = metadata['entity.name'] ? metadata['entity.name'] : '';
39
+ authHeaders['NR-CSEC-ENTITY-GUID'] = metadata['entity.guid'] ? metadata['entity.guid'] : '';
35
40
  } catch (error) {
36
41
  logger.error("Exception in preparing auth headers:", error);
42
+ const logMessage = new LogMessage.logMessage("SEVERE", 'Exception in preparing auth headers', __filename, error);
43
+ commonUtils.addLogEventtoBuffer(logMessage);
37
44
  }
38
45
 
39
46
  return authHeaders;
@@ -6,6 +6,8 @@
6
6
  const LinkingMetaData = require('./LinkingMetadata');
7
7
  const API = require('../../../nr-security-api');
8
8
  const NRAgent = API.getNRAgent();
9
+ const { BasicInfo } = require('./event');
10
+ const applicationInfo = require('./applicationinfo').getInstance();
9
11
 
10
12
  /**
11
13
  * constructor function to create LogMessageException object
@@ -13,10 +15,22 @@ const NRAgent = API.getNRAgent();
13
15
  * @param {*} cause
14
16
  * @param {*} stacktrace
15
17
  */
16
- function logMessageException (exception) {
17
- this.message = exception.message;
18
- this.cause = exception.cause ? exception.cause : '';
19
- this.stacktrace = exception.stack;
18
+ function logMessageException(exception) {
19
+ let exceptionObject = {};
20
+ try {
21
+ exceptionObject.message = exception.message ? exception.message : '';
22
+ exceptionObject.cause = null;
23
+ if (exception.stack) {
24
+ let stacktraceInList = exception.stack.split('\n');
25
+ stacktraceInList = stacktraceInList.slice(1);
26
+ exceptionObject.stacktrace = stacktraceInList;
27
+ }
28
+
29
+ } catch (error) {
30
+
31
+ }
32
+
33
+ return exceptionObject;
20
34
  }
21
35
 
22
36
  /**
@@ -28,17 +42,29 @@ function logMessageException (exception) {
28
42
  * @param {*} exception
29
43
  * @param {*} linkingMetadata
30
44
  */
31
- function logMessage (level, message, caller, exception) {
32
- this.timestamp = Date.now();
33
- this.level = level;
34
- this.message = message;
35
- this.caller = caller;
36
- if (exception) {
37
- this.exception = logMessageException(exception);
38
- }
39
- if (NRAgent) {
40
- this.linkingMetadata = LinkingMetaData.getLinkingMetadata();
45
+ function logMessage(level, message, caller, exception) {
46
+ try {
47
+ BasicInfo.call(this);
48
+ this.jsonVersion = applicationInfo.jsonVersion;
49
+ this.pid = applicationInfo.pid ? applicationInfo.pid : null;
50
+ this.jsonName = 'critical-messages';
51
+ this.applicationUUID = applicationInfo.applicationUUID;
52
+ this.groupName = applicationInfo.groupName;
53
+ this.policyVersion = applicationInfo.policyVersion;
54
+ this.timestamp = Date.now();
55
+ this.level = level ? level : 'SEVERE';
56
+ this.message = message;
57
+ this.caller = caller;
58
+ if (exception) {
59
+ this.exception = logMessageException(exception);
60
+ }
61
+ if (NRAgent) {
62
+ this.linkingMetadata = LinkingMetaData.getLinkingMetadata();
63
+ }
64
+ } catch (error) {
65
+
41
66
  }
67
+
42
68
  }
43
69
 
44
70
  module.exports = {
@@ -12,16 +12,19 @@ const OS = require('os');
12
12
  const path = require('path');
13
13
  const checkDiskSpace = require('check-disk-space').default;
14
14
  const AgentStatus = require('../core/agent-status');
15
- const { LOG_MESSAGES, CSEC_HOME, SLASH } = require('./sec-agent-constants');
15
+ const { CSEC_HOME, SLASH } = require('./sec-agent-constants');
16
16
 
17
- const prettyBytes = require('pretty-bytes');
18
17
  const njsAgentConstants = require('./sec-agent-constants');
19
- const LinkingMetaData = require('./LinkingMetadata');
20
18
  const API = require('../../../nr-security-api');
21
19
  const NRAgent = API.getNRAgent();
22
20
  const lodash = require('lodash')
23
21
  const backupLogFileRegex = /.log.\d/gm;
24
22
  let websocketHealth;
23
+
24
+ const ringBuffer = require('ringbufferjs');
25
+ const bufferedLogEvents = new ringBuffer(10);
26
+
27
+
25
28
  /**
26
29
  * Utility to generate UUID
27
30
  * @returns UUID
@@ -103,6 +106,9 @@ function createPathIfNotExist(dir) {
103
106
  }
104
107
  } catch (error) {
105
108
  logger.debug(dir + ' Not Created', error);
109
+ const LogMessage = require('./LogMessage');
110
+ const logMessage = new LogMessage.logMessage("SEVERE", 'Error in creating directory', __filename, error);
111
+ addLogEventtoBuffer(logMessage);
106
112
  }
107
113
  }
108
114
 
@@ -281,6 +287,9 @@ function removeOlderSnapshots() {
281
287
  }
282
288
  } catch (error) {
283
289
  logger.debug(error);
290
+ const LogMessage = require('./LogMessage');
291
+ const logMessage = new LogMessage.logMessage("SEVERE", 'Error in processing snapshot files', __filename, error);
292
+ addLogEventtoBuffer(logMessage);
284
293
  }
285
294
  }
286
295
  /**
@@ -417,6 +426,26 @@ function getWSHealthStatus() {
417
426
  }
418
427
  }
419
428
 
429
+ /**
430
+ * return buffered Log Event instance.
431
+ */
432
+ function getLogEvents() {
433
+ return bufferedLogEvents;
434
+ }
435
+
436
+
437
+ /**
438
+ * Utility to add error object in error buffer
439
+ * @param {*} error
440
+ */
441
+ function addLogEventtoBuffer(logMessage) {
442
+ try {
443
+ bufferedLogEvents.enq(logMessage);
444
+ } catch (error) {
445
+ logger.debug(error);
446
+ }
447
+ }
448
+
420
449
  module.exports = {
421
450
  getUUID,
422
451
  getKindIdPair,
@@ -438,5 +467,7 @@ module.exports = {
438
467
  getCSECmode,
439
468
  getPathOfCACert,
440
469
  getWSHealthStatus,
441
- setWSHealthStatus
470
+ setWSHealthStatus,
471
+ addLogEventtoBuffer,
472
+ getLogEvents
442
473
  };
@@ -38,16 +38,14 @@ function invokeLambda (arn, version, data) {
38
38
  }
39
39
 
40
40
  function init () {
41
- if (
42
- !process.csecRuntimeSupportsFunctionGenerators ||
43
- !process.csecRuntimeSupportsAsyncFunctionGenerators
44
- ) {
45
- return;
41
+ try {
42
+ const { Lambda } = require('@aws-sdk/client-lambda');
43
+ lambdaClient = new Lambda();
44
+ } catch (error) {
45
+ logger.error("Unable to initialize lambda client", error);
46
46
  }
47
-
48
- const { Lambda } = require('@aws-sdk/client-lambda');
49
- lambdaClient = new Lambda();
50
47
  }
48
+
51
49
  init();
52
50
 
53
51
  module.exports = {