@newrelic/security-agent 0.6.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ### v0.7.0 (2024-01-18)
2
+ #### Features
3
+ * Handling to exclude unsupported content types from rxss processing
4
+ * Handling to report errors/critical messages to Security Engine
5
+ #### Bug fixes
6
+ * Fix for file operation event's parameter must be absolute path of file
7
+ * Fix for ReferenceError of commonUtils module
8
+ #### Miscellaneous chores
9
+ * Updated log event jsonName to "critical-messages"
10
+ * Removed dependency @aws-sdk/client-lambda
11
+ * Bumped follow-redirects from v1.15.2 to v1.15.4
12
+ * Upgraded axios to v1.6.5
13
+
1
14
  ### v0.6.0 (2024-01-03)
2
15
  #### Features
3
16
  * Added ws headers NR-CSEC-ENTITY-GUID and NR-CSEC-ENTITY-NAME
@@ -14,7 +14,6 @@ code, the source code can be found at [https://github.com/newrelic/csec-node-age
14
14
 
15
15
  **[dependencies](#dependencies)**
16
16
 
17
- * [@aws-sdk/client-lambda](#aws-sdkclient-lambda)
18
17
  * [axios](#axios)
19
18
  * [check-disk-space](#check-disk-space)
20
19
  * [content-type](#content-type)
@@ -73,218 +72,9 @@ code, the source code can be found at [https://github.com/newrelic/csec-node-age
73
72
 
74
73
  ## dependencies
75
74
 
76
- ### @aws-sdk/client-lambda
77
-
78
- This product includes source derived from [@aws-sdk/client-lambda](https://github.com/aws/aws-sdk-js-v3) ([v3.436.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.436.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.436.0/LICENSE):
79
-
80
- ```
81
- Apache License
82
- Version 2.0, January 2004
83
- http://www.apache.org/licenses/
84
-
85
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
86
-
87
- 1. Definitions.
88
-
89
- "License" shall mean the terms and conditions for use, reproduction,
90
- and distribution as defined by Sections 1 through 9 of this document.
91
-
92
- "Licensor" shall mean the copyright owner or entity authorized by
93
- the copyright owner that is granting the License.
94
-
95
- "Legal Entity" shall mean the union of the acting entity and all
96
- other entities that control, are controlled by, or are under common
97
- control with that entity. For the purposes of this definition,
98
- "control" means (i) the power, direct or indirect, to cause the
99
- direction or management of such entity, whether by contract or
100
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
101
- outstanding shares, or (iii) beneficial ownership of such entity.
102
-
103
- "You" (or "Your") shall mean an individual or Legal Entity
104
- exercising permissions granted by this License.
105
-
106
- "Source" form shall mean the preferred form for making modifications,
107
- including but not limited to software source code, documentation
108
- source, and configuration files.
109
-
110
- "Object" form shall mean any form resulting from mechanical
111
- transformation or translation of a Source form, including but
112
- not limited to compiled object code, generated documentation,
113
- and conversions to other media types.
114
-
115
- "Work" shall mean the work of authorship, whether in Source or
116
- Object form, made available under the License, as indicated by a
117
- copyright notice that is included in or attached to the work
118
- (an example is provided in the Appendix below).
119
-
120
- "Derivative Works" shall mean any work, whether in Source or Object
121
- form, that is based on (or derived from) the Work and for which the
122
- editorial revisions, annotations, elaborations, or other modifications
123
- represent, as a whole, an original work of authorship. For the purposes
124
- of this License, Derivative Works shall not include works that remain
125
- separable from, or merely link (or bind by name) to the interfaces of,
126
- the Work and Derivative Works thereof.
127
-
128
- "Contribution" shall mean any work of authorship, including
129
- the original version of the Work and any modifications or additions
130
- to that Work or Derivative Works thereof, that is intentionally
131
- submitted to Licensor for inclusion in the Work by the copyright owner
132
- or by an individual or Legal Entity authorized to submit on behalf of
133
- the copyright owner. For the purposes of this definition, "submitted"
134
- means any form of electronic, verbal, or written communication sent
135
- to the Licensor or its representatives, including but not limited to
136
- communication on electronic mailing lists, source code control systems,
137
- and issue tracking systems that are managed by, or on behalf of, the
138
- Licensor for the purpose of discussing and improving the Work, but
139
- excluding communication that is conspicuously marked or otherwise
140
- designated in writing by the copyright owner as "Not a Contribution."
141
-
142
- "Contributor" shall mean Licensor and any individual or Legal Entity
143
- on behalf of whom a Contribution has been received by Licensor and
144
- subsequently incorporated within the Work.
145
-
146
- 2. Grant of Copyright License. Subject to the terms and conditions of
147
- this License, each Contributor hereby grants to You a perpetual,
148
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
149
- copyright license to reproduce, prepare Derivative Works of,
150
- publicly display, publicly perform, sublicense, and distribute the
151
- Work and such Derivative Works in Source or Object form.
152
-
153
- 3. Grant of Patent License. Subject to the terms and conditions of
154
- this License, each Contributor hereby grants to You a perpetual,
155
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
156
- (except as stated in this section) patent license to make, have made,
157
- use, offer to sell, sell, import, and otherwise transfer the Work,
158
- where such license applies only to those patent claims licensable
159
- by such Contributor that are necessarily infringed by their
160
- Contribution(s) alone or by combination of their Contribution(s)
161
- with the Work to which such Contribution(s) was submitted. If You
162
- institute patent litigation against any entity (including a
163
- cross-claim or counterclaim in a lawsuit) alleging that the Work
164
- or a Contribution incorporated within the Work constitutes direct
165
- or contributory patent infringement, then any patent licenses
166
- granted to You under this License for that Work shall terminate
167
- as of the date such litigation is filed.
168
-
169
- 4. Redistribution. You may reproduce and distribute copies of the
170
- Work or Derivative Works thereof in any medium, with or without
171
- modifications, and in Source or Object form, provided that You
172
- meet the following conditions:
173
-
174
- (a) You must give any other recipients of the Work or
175
- Derivative Works a copy of this License; and
176
-
177
- (b) You must cause any modified files to carry prominent notices
178
- stating that You changed the files; and
179
-
180
- (c) You must retain, in the Source form of any Derivative Works
181
- that You distribute, all copyright, patent, trademark, and
182
- attribution notices from the Source form of the Work,
183
- excluding those notices that do not pertain to any part of
184
- the Derivative Works; and
185
-
186
- (d) If the Work includes a "NOTICE" text file as part of its
187
- distribution, then any Derivative Works that You distribute must
188
- include a readable copy of the attribution notices contained
189
- within such NOTICE file, excluding those notices that do not
190
- pertain to any part of the Derivative Works, in at least one
191
- of the following places: within a NOTICE text file distributed
192
- as part of the Derivative Works; within the Source form or
193
- documentation, if provided along with the Derivative Works; or,
194
- within a display generated by the Derivative Works, if and
195
- wherever such third-party notices normally appear. The contents
196
- of the NOTICE file are for informational purposes only and
197
- do not modify the License. You may add Your own attribution
198
- notices within Derivative Works that You distribute, alongside
199
- or as an addendum to the NOTICE text from the Work, provided
200
- that such additional attribution notices cannot be construed
201
- as modifying the License.
202
-
203
- You may add Your own copyright statement to Your modifications and
204
- may provide additional or different license terms and conditions
205
- for use, reproduction, or distribution of Your modifications, or
206
- for any such Derivative Works as a whole, provided Your use,
207
- reproduction, and distribution of the Work otherwise complies with
208
- the conditions stated in this License.
209
-
210
- 5. Submission of Contributions. Unless You explicitly state otherwise,
211
- any Contribution intentionally submitted for inclusion in the Work
212
- by You to the Licensor shall be under the terms and conditions of
213
- this License, without any additional terms or conditions.
214
- Notwithstanding the above, nothing herein shall supersede or modify
215
- the terms of any separate license agreement you may have executed
216
- with Licensor regarding such Contributions.
217
-
218
- 6. Trademarks. This License does not grant permission to use the trade
219
- names, trademarks, service marks, or product names of the Licensor,
220
- except as required for reasonable and customary use in describing the
221
- origin of the Work and reproducing the content of the NOTICE file.
222
-
223
- 7. Disclaimer of Warranty. Unless required by applicable law or
224
- agreed to in writing, Licensor provides the Work (and each
225
- Contributor provides its Contributions) on an "AS IS" BASIS,
226
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
227
- implied, including, without limitation, any warranties or conditions
228
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
229
- PARTICULAR PURPOSE. You are solely responsible for determining the
230
- appropriateness of using or redistributing the Work and assume any
231
- risks associated with Your exercise of permissions under this License.
232
-
233
- 8. Limitation of Liability. In no event and under no legal theory,
234
- whether in tort (including negligence), contract, or otherwise,
235
- unless required by applicable law (such as deliberate and grossly
236
- negligent acts) or agreed to in writing, shall any Contributor be
237
- liable to You for damages, including any direct, indirect, special,
238
- incidental, or consequential damages of any character arising as a
239
- result of this License or out of the use or inability to use the
240
- Work (including but not limited to damages for loss of goodwill,
241
- work stoppage, computer failure or malfunction, or any and all
242
- other commercial damages or losses), even if such Contributor
243
- has been advised of the possibility of such damages.
244
-
245
- 9. Accepting Warranty or Additional Liability. While redistributing
246
- the Work or Derivative Works thereof, You may choose to offer,
247
- and charge a fee for, acceptance of support, warranty, indemnity,
248
- or other liability obligations and/or rights consistent with this
249
- License. However, in accepting such obligations, You may act only
250
- on Your own behalf and on Your sole responsibility, not on behalf
251
- of any other Contributor, and only if You agree to indemnify,
252
- defend, and hold each Contributor harmless for any liability
253
- incurred by, or claims asserted against, such Contributor by reason
254
- of your accepting any such warranty or additional liability.
255
-
256
- END OF TERMS AND CONDITIONS
257
-
258
- APPENDIX: How to apply the Apache License to your work.
259
-
260
- To apply the Apache License to your work, attach the following
261
- boilerplate notice, with the fields enclosed by brackets "{}"
262
- replaced with your own identifying information. (Don't include
263
- the brackets!) The text should be enclosed in the appropriate
264
- comment syntax for the file format. We also recommend that a
265
- file or class name and description of purpose be included on the
266
- same "printed page" as the copyright notice for easier
267
- identification within third-party archives.
268
-
269
- Copyright 2018-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
270
-
271
- Licensed under the Apache License, Version 2.0 (the "License");
272
- you may not use this file except in compliance with the License.
273
- You may obtain a copy of the License at
274
-
275
- http://www.apache.org/licenses/LICENSE-2.0
276
-
277
- Unless required by applicable law or agreed to in writing, software
278
- distributed under the License is distributed on an "AS IS" BASIS,
279
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
280
- See the License for the specific language governing permissions and
281
- limitations under the License.
282
-
283
- ```
284
-
285
75
  ### axios
286
76
 
287
- This product includes source derived from [axios](https://github.com/axios/axios) ([v1.6.3](https://github.com/axios/axios/tree/v1.6.3)), distributed under the [MIT License](https://github.com/axios/axios/blob/v1.6.3/LICENSE):
77
+ This product includes source derived from [axios](https://github.com/axios/axios) ([v1.6.5](https://github.com/axios/axios/tree/v1.6.5)), distributed under the [MIT License](https://github.com/axios/axios/blob/v1.6.5/LICENSE):
288
78
 
289
79
  ```
290
80
  # Copyright (c) 2014-present Matt Zabriskie & Collaborators
@@ -118,7 +118,7 @@ function openHook(shim, mod, moduleName) {
118
118
  shim.wrap(mod, "open", function makeOpenWrapper(shim, fn) {
119
119
  logger.debug(`Instrumenting ${moduleName}.open`);
120
120
  return function openWrapper() {
121
- const parameters = Array.prototype.slice.apply(arguments);
121
+ let parameters = Array.prototype.slice.apply(arguments);
122
122
  const interceptedArgs = [arguments[0]];
123
123
  shim.interceptedArgs = interceptedArgs;
124
124
  const request = requestManager.getRequest(shim);
@@ -147,8 +147,9 @@ function openHook(shim, mod, moduleName) {
147
147
  } catch (error) {
148
148
 
149
149
  }
150
+ let absoluteParameters = [parameters[0]];
150
151
  const traceObject = secUtils.getTraceObject(shim);
151
- const secMetadata = securityMetaData.getSecurityMetaData(request, interceptedArgs, traceObject, secUtils.getExecutionId(), getCaseType(parameters[1], parameters[0]), EVENT_CATEGORY.FILE)
152
+ const secMetadata = securityMetaData.getSecurityMetaData(request, absoluteParameters, traceObject, secUtils.getExecutionId(), getCaseType(parameters[1], parameters[0]), EVENT_CATEGORY.FILE)
152
153
  this.secEvent = API.generateSecEvent(secMetadata);
153
154
  API.sendEvent(this.secEvent);
154
155
  const callbackFlag = isCallback(arguments);
@@ -180,12 +181,19 @@ function probableToFAHooks(shim, mod, moduleName) {
180
181
  shim.wrap(mod, fun, function makeFAWrapper(shim, fn) {
181
182
  logger.debug(`Instrumenting ${moduleName}.${fun}`);
182
183
  return function FAWrapper() {
184
+ let parameters = Array.prototype.slice.apply(arguments);
183
185
  const interceptedArgs = [arguments[0]];
184
186
  shim.interceptedArgs = interceptedArgs;
185
187
  const request = requestManager.getRequest(shim);
186
188
  if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
187
189
  const traceObject = secUtils.getTraceObject(shim);
188
- const secMetadata = securityMetaData.getSecurityMetaData(request, interceptedArgs, traceObject, secUtils.getExecutionId(), EVENT_TYPE.FILE_OPERATION, EVENT_CATEGORY.FILE)
190
+ try {
191
+ parameters[0] = path.resolve(parameters[0]);
192
+ } catch (error) {
193
+
194
+ }
195
+ let absoluteParameters = [parameters[0]];
196
+ const secMetadata = securityMetaData.getSecurityMetaData(request, absoluteParameters, traceObject, secUtils.getExecutionId(), EVENT_TYPE.FILE_OPERATION, EVENT_CATEGORY.FILE)
189
197
  this.secEvent = API.generateSecEvent(secMetadata);
190
198
  API.sendEvent(this.secEvent);
191
199
  const callbackFlag = isCallback(arguments);
@@ -210,17 +218,25 @@ function probableToFIHooks(shim, mod, moduleName) {
210
218
  shim.wrap(mod, fun, function makeFIWrapper(shim, fn) {
211
219
  logger.debug(`Instrumenting ${moduleName}.${fun}`);
212
220
  return function FIWrapper() {
221
+ let parameters = Array.prototype.slice.apply(arguments);
213
222
  const interceptedArgs = [arguments[0]];
214
223
  shim.interceptedArgs = interceptedArgs;
215
224
  const request = requestManager.getRequest(shim);
216
225
  if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
217
226
  const traceObject = secUtils.getTraceObject(shim);
227
+ try {
228
+ parameters[0] = path.resolve(parameters[0]);
229
+ parameters[1] = path.resolve(parameters[1]);
230
+ } catch (error) {
231
+
232
+ }
233
+ let absoluteParameters = [parameters[0]];
218
234
  if (fun === COPY_FILE || fun === RENAME) {
219
- const secMetadata = securityMetaData.getSecurityMetaData(request, arguments[1], traceObject, secUtils.getExecutionId(), getCase(arguments[1]), EVENT_CATEGORY.FILE)
235
+ const secMetadata = securityMetaData.getSecurityMetaData(request, parameters[1], traceObject, secUtils.getExecutionId(), getCase(arguments[1]), EVENT_CATEGORY.FILE)
220
236
  this.secEvent = API.generateSecEvent(secMetadata);
221
237
  API.sendEvent(this.secEvent);
222
238
  }
223
- const secMetadata = securityMetaData.getSecurityMetaData(request, interceptedArgs, traceObject, secUtils.getExecutionId(), getCase(arguments[0]), EVENT_CATEGORY.FILE)
239
+ const secMetadata = securityMetaData.getSecurityMetaData(request, absoluteParameters, traceObject, secUtils.getExecutionId(), getCase(arguments[0]), EVENT_CATEGORY.FILE)
224
240
  this.secEvent = API.generateSecEvent(secMetadata);
225
241
  API.sendEvent(this.secEvent);
226
242
  const callbackFlag = isCallback(arguments);
@@ -245,12 +261,19 @@ function probablePromiseToFAHooks(shim, mod, moduleName) {
245
261
  logger.debug(`Instrumenting Promise ${moduleName}.${fun}`);
246
262
  shim.wrap(mod, fun, function makeFAWrapper(shim, fn) {
247
263
  return function FAWrapper() {
264
+ let parameters = Array.prototype.slice.apply(arguments);
248
265
  const interceptedArgs = [arguments[0]];
249
266
  shim.interceptedArgs = interceptedArgs;
250
267
  const request = requestManager.getRequest(shim);
251
268
  if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
252
269
  const traceObject = secUtils.getTraceObject(shim);
253
- const secMetadata = securityMetaData.getSecurityMetaData(request, interceptedArgs, traceObject, secUtils.getExecutionId(), EVENT_TYPE.FILE_OPERATION, EVENT_CATEGORY.FILE)
270
+ try {
271
+ parameters[0] = path.resolve(parameters[0]);
272
+ } catch (error) {
273
+
274
+ }
275
+ let absoluteParameters = [parameters[0]];
276
+ const secMetadata = securityMetaData.getSecurityMetaData(request, absoluteParameters, traceObject, secUtils.getExecutionId(), EVENT_TYPE.FILE_OPERATION, EVENT_CATEGORY.FILE)
254
277
  this.secEvent = API.generateSecEvent(secMetadata);
255
278
  API.sendEvent(this.secEvent);
256
279
  }
@@ -271,17 +294,25 @@ function probablePromiseToFIHooks(shim, mod, moduleName) {
271
294
  logger.debug(`Instrumenting Promise ${moduleName}.${fun}`);
272
295
  shim.wrap(mod, fun, function makeFIWrapper(shim, fn) {
273
296
  return function FIWrapper() {
297
+ let parameters = Array.prototype.slice.apply(arguments);
274
298
  const interceptedArgs = [arguments[0]];
275
299
  shim.interceptedArgs = interceptedArgs;
276
300
  const request = requestManager.getRequest(shim);
277
301
  if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
278
302
  const traceObject = secUtils.getTraceObject(shim);
303
+ try {
304
+ parameters[0] = path.resolve(parameters[0]);
305
+ parameters[1] = path.resolve(parameters[1]);
306
+ } catch (error) {
307
+
308
+ }
309
+ let absoluteParameters = [parameters[0]];
279
310
  if (fun === COPY_FILE || fun === RENAME) {
280
- const secMetadata = securityMetaData.getSecurityMetaData(request, arguments[1], traceObject, secUtils.getExecutionId(), getCase(arguments[1]), EVENT_CATEGORY.FILE)
311
+ const secMetadata = securityMetaData.getSecurityMetaData(request, parameters[1], traceObject, secUtils.getExecutionId(), getCase(arguments[1]), EVENT_CATEGORY.FILE)
281
312
  this.secEvent = API.generateSecEvent(secMetadata);
282
313
  API.sendEvent(this.secEvent);
283
314
  }
284
- const secMetadata = securityMetaData.getSecurityMetaData(request, interceptedArgs, traceObject, secUtils.getExecutionId(), getCase(arguments[0]), EVENT_CATEGORY.FILE)
315
+ const secMetadata = securityMetaData.getSecurityMetaData(request, absoluteParameters, traceObject, secUtils.getExecutionId(), getCase(arguments[0]), EVENT_CATEGORY.FILE)
285
316
  this.secEvent = API.generateSecEvent(secMetadata);
286
317
  API.sendEvent(this.secEvent);
287
318
  }
@@ -272,7 +272,7 @@ function emitHook(shim, mod, moduleName) {
272
272
  if (NRAgent && NRAgent.config.security.detection.rxss.enabled) {
273
273
  responseHook(resp, req, shim);
274
274
  }
275
-
275
+
276
276
  shim.wrap(req, 'on', function makeOnWrapper(shim, fn) {
277
277
  if (!shim.isFunction(fn)) {
278
278
  return fn
@@ -390,30 +390,94 @@ function responseHook(resp, req, shim) {
390
390
  const construct = API.checkForReflectedXSS(request, response.res.body, response.getHeaders());
391
391
  const policy = API.getPolicy();
392
392
  const dynamicScanningFlag = policy.data ? (policy.data.vulnerabilityScan?.enabled && policy.data.vulnerabilityScan.iastScan.enabled) : false;
393
- if (request && (construct || dynamicScanningFlag)) {
393
+ const type = response.getHeader(CONTENT_TYPE);
394
+ let isUnsupportedType = isUnsupportedContentType(type);
395
+
396
+ if (request && (construct || dynamicScanningFlag) && !isUnsupportedType) {
394
397
  const args = [];
395
398
  args.push(construct);
396
399
  args.push(response.res.body);
397
400
  const traceObject = secUtils.getTraceObject(shim);
398
401
  const secMetadata = securityMetaData.getSecurityMetaData(request, args, traceObject, secUtils.getExecutionId(), EVENT_TYPE.REFLECTED_XSS, EVENT_CATEGORY.REFLECTED_XSS)
399
402
  const secEvent = API.generateSecEvent(secMetadata);
400
-
403
+ secEvent.httpResponse = {};
404
+ secEvent.httpResponse.contentType = response.getHeader(CONTENT_TYPE);
401
405
  API.sendEvent(secEvent);
402
406
  }
403
407
  return fn.apply(this, arguments);
404
408
  }
405
409
  })
406
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
+ }
407
465
 
408
466
  function responseBodyCompute(response, args) {
409
467
  let encoding = UTF8;
410
468
  const type = response.getHeader(CONTENT_TYPE);
469
+ let isUnsupportedType = isUnsupportedContentType(type);
470
+ if (isUnsupportedType) {
471
+ return;
472
+ }
473
+
411
474
  let contentType = TEXT_HTML;
412
475
  if (type) {
413
476
  const obj = ConType.parse(type);
414
477
  contentType = obj.type;
415
478
  encoding = obj.parameters.charset;
416
479
  }
480
+
417
481
  if (args[0]) {
418
482
  switch (contentType) {
419
483
  case APPLICATION_JSON:
@@ -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
 
@@ -19,7 +19,7 @@ function logMessageException(exception) {
19
19
  let exceptionObject = {};
20
20
  try {
21
21
  exceptionObject.message = exception.message ? exception.message : '';
22
- exceptionObject.cause = exception.cause ? exception.cause : '';
22
+ exceptionObject.cause = null;
23
23
  if (exception.stack) {
24
24
  let stacktraceInList = exception.stack.split('\n');
25
25
  stacktraceInList = stacktraceInList.slice(1);
@@ -46,7 +46,8 @@ function logMessage(level, message, caller, exception) {
46
46
  try {
47
47
  BasicInfo.call(this);
48
48
  this.jsonVersion = applicationInfo.jsonVersion;
49
- this.jsonName = 'log-message';
49
+ this.pid = applicationInfo.pid ? applicationInfo.pid : null;
50
+ this.jsonName = 'critical-messages';
50
51
  this.applicationUUID = applicationInfo.applicationUUID;
51
52
  this.groupName = applicationInfo.groupName;
52
53
  this.policyVersion = applicationInfo.policyVersion;
@@ -24,6 +24,7 @@ let websocketHealth;
24
24
  const ringBuffer = require('ringbufferjs');
25
25
  const bufferedLogEvents = new ringBuffer(10);
26
26
 
27
+
27
28
  /**
28
29
  * Utility to generate UUID
29
30
  * @returns UUID
@@ -105,6 +106,9 @@ function createPathIfNotExist(dir) {
105
106
  }
106
107
  } catch (error) {
107
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);
108
112
  }
109
113
  }
110
114
 
@@ -283,6 +287,9 @@ function removeOlderSnapshots() {
283
287
  }
284
288
  } catch (error) {
285
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);
286
293
  }
287
294
  }
288
295
  /**
@@ -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 = {
@@ -101,7 +101,7 @@ function handler(json) {
101
101
  logger.error('Parsing exeception in fuzz request: ', error);
102
102
 
103
103
  const logMessage = new LogMessage.logMessage(SEVERE, 'Parsing exeception in fuzz request', __filename, error);
104
- commonUtils.addLogEventtoBuffer(logMessage);
104
+ require('../../../commonUtils').addLogEventtoBuffer(logMessage);
105
105
  }
106
106
  if (!fuzzRequest) {
107
107
  return;
@@ -41,7 +41,7 @@ const handle = function handle (json) {
41
41
  } catch (error) {
42
42
  logger.error("Error in handling Control Command",error);
43
43
  const logMessage = new LogMessage.logMessage(SEVERE, 'Error in handling Control Command', __filename, error);
44
- commonUtils.addLogEventtoBuffer(logMessage);
44
+ require('../../../commonUtils').addLogEventtoBuffer(logMessage);
45
45
  }
46
46
 
47
47
  };
@@ -83,7 +83,7 @@ function getFormattedData() {
83
83
  const appInfo = Agent.applicationInfo;
84
84
  const deployedApplications = appInfo && appInfo.serverInfo && appInfo.serverInfo.deployedApplications;
85
85
  const appLoc = deployedApplications[0].deployedPath;
86
- const formattedSnapshot = util.format(statusTemplate, new Date().toString(), appLoc, appInfo.serverInfo.name, njsAgentConstants.FRAMEWORK,commonUtils.getWSHealthStatus(), appInfo.policyVersion, getKeyValPairs(lastHC.stats), getKeyValPairs(lastHC.serviceStatus), JSON.stringify(getBufferedErrors()), JSON.stringify(getBufferedHC()));
86
+ const formattedSnapshot = util.format(statusTemplate, new Date().toString(), appLoc, appInfo.serverInfo.name, njsAgentConstants.FRAMEWORK, commonUtils.getWSHealthStatus(), appInfo.policyVersion, getKeyValPairs(lastHC.stats), getKeyValPairs(lastHC.serviceStatus), JSON.stringify(getBufferedErrors()), JSON.stringify(getBufferedHC()));
87
87
  return formattedSnapshot;
88
88
  }
89
89
 
@@ -96,6 +96,9 @@ function writeSnapshot() {
96
96
  fs.writeFile(statusFile, snapshot, { mode: 0o777 }, function (err) {
97
97
  if (err) {
98
98
  logger.debug(err.message);
99
+ const LogMessage = require('./LogMessage');
100
+ const logMessage = new LogMessage.logMessage("SEVERE", 'Error in creating snapshot file', __filename, err);
101
+ commonUtils.addLogEventtoBuffer(logMessage);
99
102
  } else {
100
103
  logger.info('Snapshot updated to file: %s', statusFile);
101
104
  fs.chmod(statusFile, 0o777, (err) => {
@@ -15,6 +15,7 @@ const initLogger = require('./logging').getInitLogger();
15
15
  const commonUtils = require('./commonUtils');
16
16
  const API = require('../../../nr-security-api');
17
17
  const NRAgent = API.getNRAgent();
18
+ const LogMessage = require('./LogMessage');
18
19
  const {
19
20
  SecWebSocket,
20
21
  setWebSocketConn,
@@ -69,6 +70,15 @@ const initialize = function () {
69
70
  setTimeout(() => {
70
71
  setInterval(sendHC, HC_INTERVAL_MS);
71
72
  sendHC();
73
+ try {
74
+ const framework = NRAgent.environment.get('Framework')[0];
75
+ const dispatcher = NRAgent.environment.get('Dispatcher')[0];
76
+ const logMessage = new LogMessage.logMessage("SEVERE", `Detected framework: ${framework} and dispatcher: ${dispatcher}`, __filename, null);
77
+ commonUtils.addLogEventtoBuffer(logMessage);
78
+ } catch (error) {
79
+ logger.debug("Error while extracting data from APM environment",error);
80
+ }
81
+
72
82
  }, 30000);
73
83
 
74
84
  setInterval(commonUtils.logRollOver, 30000);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newrelic/security-agent",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "New Relic Security Agent for Node.js",
5
5
  "main": "index.js",
6
6
  "jsonVersion": "1.1.1",
@@ -35,8 +35,7 @@
35
35
  "url": "https://github.com/newrelic/csec-node-agent.git"
36
36
  },
37
37
  "dependencies": {
38
- "@aws-sdk/client-lambda": "^3.436.0",
39
- "axios": "^1.6.3",
38
+ "axios": "^1.6.5",
40
39
  "check-disk-space": "^3.4.0",
41
40
  "content-type": "^1.0.5",
42
41
  "fast-safe-stringify": "^2.1.1",