@newrelic/security-agent 3.0.1 → 3.0.3

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,18 @@
1
+ ### v3.0.3 (2026-04-08)
2
+ #### Miscellaneous chores
3
+ * (deps-dev): bump koa from 3.0.3 to 3.1.2 (#330)
4
+ * (deps): bump minimatch from 3.1.2 to 3.1.5 (#332)
5
+ * (deps): bump undici from 7.19.0 to 7.24.0 (#335)
6
+ * (deps): bump flatted from 3.2.9 to 3.4.2 (#339)
7
+ * (deps-dev): bump fast-xml-parser, @aws-sdk/credential-providers and @aws-sdk/client-lambda (#338)
8
+ * (deps-dev): bump picomatch from 2.3.1 to 2.3.2 (#340)
9
+ * (deps-dev): bump lodash.template from 4.5.0 to 4.18.1 (#342)
10
+
11
+ ### v3.0.2 (2026-02-17)
12
+ #### Miscellaneous chores
13
+ * refactor: Removed dependence on lodash in lieu of using native javascript
14
+ * refactor: Replace cron module with node-cron. Removed pretty-bytes, js-yaml and jsonschema modules
15
+
1
16
  ### v3.0.1 (2026-01-29)
2
17
  #### Miscellaneous chores
3
18
  * (deps): Updated lodash to v4.17.23 and undici to v7.19.0
@@ -16,18 +16,14 @@ code, the source code can be found at [https://github.com/newrelic/csec-node-age
16
16
 
17
17
  * [check-disk-space](#check-disk-space)
18
18
  * [content-type](#content-type)
19
- * [cron](#cron)
20
19
  * [fast-safe-stringify](#fast-safe-stringify)
21
20
  * [find-package-json](#find-package-json)
22
21
  * [hash.js](#hashjs)
23
22
  * [html-entities](#html-entities)
24
23
  * [https-proxy-agent](#https-proxy-agent)
25
24
  * [is-invalid-path](#is-invalid-path)
26
- * [js-yaml](#js-yaml)
27
- * [jsonschema](#jsonschema)
28
- * [lodash](#lodash)
29
25
  * [log4js](#log4js)
30
- * [pretty-bytes](#pretty-bytes)
26
+ * [node-cron](#node-cron)
31
27
  * [request-ip](#request-ip)
32
28
  * [ringbufferjs](#ringbufferjs)
33
29
  * [semver](#semver)
@@ -132,22 +128,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
132
128
 
133
129
  ```
134
130
 
135
- ### cron
136
-
137
- This product includes source derived from [cron](https://github.com/kelektiv/node-cron) ([v3.1.7](https://github.com/kelektiv/node-cron/tree/v3.1.7)), distributed under the [MIT License](https://github.com/kelektiv/node-cron/blob/v3.1.7/LICENSE):
138
-
139
- ```
140
- The MIT License (MIT)
141
- Copyright © 2017 Nicholas Campbell <nicholas.j.campbell@gmail.com>
142
-
143
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
144
-
145
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
146
-
147
- THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
148
-
149
- ```
150
-
151
131
  ### fast-safe-stringify
152
132
 
153
133
  This product includes source derived from [fast-safe-stringify](https://github.com/davidmarkclements/fast-safe-stringify) ([v2.1.1](https://github.com/davidmarkclements/fast-safe-stringify/tree/v2.1.1)), distributed under the [MIT License](https://github.com/davidmarkclements/fast-safe-stringify/blob/v2.1.1/LICENSE):
@@ -296,119 +276,6 @@ THE SOFTWARE.
296
276
 
297
277
  ```
298
278
 
299
- ### js-yaml
300
-
301
- This product includes source derived from [js-yaml](https://github.com/nodeca/js-yaml) ([v4.1.1](https://github.com/nodeca/js-yaml/tree/v4.1.1)), distributed under the [MIT License](https://github.com/nodeca/js-yaml/blob/v4.1.1/LICENSE):
302
-
303
- ```
304
- (The MIT License)
305
-
306
- Copyright (C) 2011-2015 by Vitaly Puzrin
307
-
308
- Permission is hereby granted, free of charge, to any person obtaining a copy
309
- of this software and associated documentation files (the "Software"), to deal
310
- in the Software without restriction, including without limitation the rights
311
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
312
- copies of the Software, and to permit persons to whom the Software is
313
- furnished to do so, subject to the following conditions:
314
-
315
- The above copyright notice and this permission notice shall be included in
316
- all copies or substantial portions of the Software.
317
-
318
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
319
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
320
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
321
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
322
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
323
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
324
- THE SOFTWARE.
325
-
326
- ```
327
-
328
- ### jsonschema
329
-
330
- This product includes source derived from [jsonschema](https://github.com/tdegrunt/jsonschema) ([v1.4.1](https://github.com/tdegrunt/jsonschema/tree/v1.4.1)), distributed under the [MIT License](https://github.com/tdegrunt/jsonschema/blob/v1.4.1/LICENSE):
331
-
332
- ```
333
- jsonschema is licensed under MIT license.
334
-
335
- Copyright (C) 2012-2015 Tom de Grunt <tom@degrunt.nl>
336
-
337
- Permission is hereby granted, free of charge, to any person obtaining a copy of
338
- this software and associated documentation files (the "Software"), to deal in
339
- the Software without restriction, including without limitation the rights to
340
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
341
- of the Software, and to permit persons to whom the Software is furnished to do
342
- so, subject to the following conditions:
343
-
344
- The above copyright notice and this permission notice shall be included in all
345
- copies or substantial portions of the Software.
346
-
347
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
348
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
349
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
350
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
351
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
352
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
353
- SOFTWARE.
354
-
355
- ```
356
-
357
- ### lodash
358
-
359
- This product includes source derived from [lodash](https://github.com/lodash/lodash) ([v4.17.23](https://github.com/lodash/lodash/tree/v4.17.23)), distributed under the [MIT License](https://github.com/lodash/lodash/blob/v4.17.23/LICENSE):
360
-
361
- ```
362
- Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
363
-
364
- Based on Underscore.js, copyright Jeremy Ashkenas,
365
- DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
366
-
367
- This software consists of voluntary contributions made by many
368
- individuals. For exact contribution history, see the revision history
369
- available at https://github.com/lodash/lodash
370
-
371
- The following license applies to all parts of this software except as
372
- documented below:
373
-
374
- ====
375
-
376
- Permission is hereby granted, free of charge, to any person obtaining
377
- a copy of this software and associated documentation files (the
378
- "Software"), to deal in the Software without restriction, including
379
- without limitation the rights to use, copy, modify, merge, publish,
380
- distribute, sublicense, and/or sell copies of the Software, and to
381
- permit persons to whom the Software is furnished to do so, subject to
382
- the following conditions:
383
-
384
- The above copyright notice and this permission notice shall be
385
- included in all copies or substantial portions of the Software.
386
-
387
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
388
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
389
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
390
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
391
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
392
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
393
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
394
-
395
- ====
396
-
397
- Copyright and related rights for sample code are waived via CC0. Sample
398
- code is defined as all source code displayed within the prose of the
399
- documentation.
400
-
401
- CC0: http://creativecommons.org/publicdomain/zero/1.0/
402
-
403
- ====
404
-
405
- Files located in the node_modules and vendor directories are externally
406
- maintained libraries used by this software which have their own
407
- licenses; we recommend you read them, as their terms may differ from the
408
- terms above.
409
-
410
- ```
411
-
412
279
  ### log4js
413
280
 
414
281
  This product includes source derived from [log4js](https://github.com/log4js-node/log4js-node) ([v6.9.1](https://github.com/log4js-node/log4js-node/tree/v6.9.1)), distributed under the [Apache-2.0 License](https://github.com/log4js-node/log4js-node/blob/v6.9.1/LICENSE):
@@ -430,20 +297,18 @@ Copyright 2015 Gareth Jones (with contributions from many other people)
430
297
 
431
298
  ```
432
299
 
433
- ### pretty-bytes
300
+ ### node-cron
434
301
 
435
- This product includes source derived from [pretty-bytes](https://github.com/sindresorhus/pretty-bytes) ([v5.6.0](https://github.com/sindresorhus/pretty-bytes/tree/v5.6.0)), distributed under the [MIT License](https://github.com/sindresorhus/pretty-bytes/blob/v5.6.0/license):
302
+ This product includes source derived from [node-cron](https://github.com/merencia/node-cron) ([v4.2.1](https://github.com/merencia/node-cron/tree/v4.2.1)), distributed under the [ISC License](https://github.com/merencia/node-cron/blob/v4.2.1/LICENSE.md):
436
303
 
437
304
  ```
438
- MIT License
305
+ ## ISC License
439
306
 
440
- Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
307
+ Copyright (c) 2016, Lucas Merencia \<lucas.merencia@gmail.com\>
441
308
 
442
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
309
+ Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
443
310
 
444
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
445
-
446
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
311
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
447
312
 
448
313
  ```
449
314
 
@@ -516,7 +381,7 @@ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
516
381
 
517
382
  ### undici
518
383
 
519
- This product includes source derived from [undici](https://github.com/nodejs/undici) ([v7.19.0](https://github.com/nodejs/undici/tree/v7.19.0)), distributed under the [MIT License](https://github.com/nodejs/undici/blob/v7.19.0/LICENSE):
384
+ This product includes source derived from [undici](https://github.com/nodejs/undici) ([v7.24.0](https://github.com/nodejs/undici/tree/v7.24.0)), distributed under the [MIT License](https://github.com/nodejs/undici/blob/v7.24.0/LICENSE):
520
385
 
521
386
  ```
522
387
  MIT License
@@ -1830,7 +1695,7 @@ Library.
1830
1695
 
1831
1696
  ### koa
1832
1697
 
1833
- This product includes source derived from [koa](https://github.com/koajs/koa) ([v3.0.3](https://github.com/koajs/koa/tree/v3.0.3)), distributed under the [MIT License](https://github.com/koajs/koa/blob/v3.0.3/LICENSE):
1698
+ This product includes source derived from [koa](https://github.com/koajs/koa) ([v3.1.2](https://github.com/koajs/koa/tree/v3.1.2)), distributed under the [MIT License](https://github.com/koajs/koa/blob/v3.1.2/LICENSE):
1834
1699
 
1835
1700
  ```
1836
1701
  (The MIT License)
@@ -9,7 +9,6 @@
9
9
  const requestManager = require("../../core/request-manager");
10
10
  const secUtils = require('../../core/sec-utils');
11
11
  const { ATTHERATE, DOUBLE_DOLLAR, COLON } = require('../../core/constants');
12
- const lodash = require('lodash');
13
12
  const routeManager = require('../../core/route-manager');
14
13
  const API = require("../../../nr-security-api");
15
14
  const logger = API.getLogger();
@@ -50,7 +49,7 @@ module.exports = function initialize(shim, director) {
50
49
  const path = "/" + arguments[1].join('/')
51
50
  const stakTrace = secUtils.traceElementForRoute();
52
51
  const splittedStack = stakTrace[0].split(DOUBLE_DOLLAR);
53
- const key = lodash.upperCase(method) + ATTHERATE + path;
52
+ const key = method.toUpperCase() + ATTHERATE + path;
54
53
  routeManager.setRoute(key, splittedStack[0]);
55
54
  if (path.includes(COLON)) {
56
55
  const dummyKey = key.split(COLON)[0] + ":param_input";
@@ -89,7 +88,7 @@ function extractParams(shim, params) {
89
88
  let uri = request.url.split("?")[0];
90
89
  const param = Object.values(params)[0];
91
90
  if (uri.includes(param)) {
92
- uri = lodash.replace(uri, param, ':param_input');
91
+ uri = uri.replace(param, ':param_input');
93
92
  request.uri = uri;
94
93
  requestManager.setRequest(transaction.id, request);
95
94
  }
@@ -14,7 +14,6 @@
14
14
  const requestManager = require("../../core/request-manager");
15
15
  const secUtils = require('../../core/sec-utils');
16
16
  const { ATTHERATE, DOUBLE_DOLLAR } = require('../../core/constants');
17
- const lodash = require('lodash');
18
17
  const routeManager = require('../../core/route-manager');
19
18
  const API = require("../../../nr-security-api");
20
19
  const logger = API.getLogger();
@@ -55,7 +54,7 @@ function wrapExpress4(shim, express) {
55
54
  try {
56
55
  const stakTrace = secUtils.traceElementForRoute();
57
56
  const splittedStack = stakTrace[0].split(DOUBLE_DOLLAR);
58
- const key = lodash.upperCase(splittedStack[1]) + ATTHERATE + arguments[0];
57
+ const key = splittedStack[1].toUpperCase() + ATTHERATE + arguments[0];
59
58
  routeManager.setRoute(key, splittedStack[0]);
60
59
  } catch (error) {
61
60
 
@@ -134,7 +133,7 @@ function expressFileHook(shim, mod, fun) {
134
133
  const interceptedArgs = [arguments[0]];
135
134
  shim.interceptedArgs = interceptedArgs;
136
135
  const request = requestManager.getRequest(shim);
137
- if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
136
+ if (request && typeof arguments[0] === STRING && arguments[0]) {
138
137
  const traceObject = secUtils.getTraceObject(shim);
139
138
  try {
140
139
  parameters[0] = path.resolve(parameters[0]);
@@ -166,7 +165,7 @@ function wrapExpress5(shim, express) {
166
165
  try {
167
166
  const stakTrace = secUtils.traceElementForRoute();
168
167
  const splittedStack = stakTrace[0].split(DOUBLE_DOLLAR);
169
- const key = lodash.upperCase(splittedStack[1]) + ATTHERATE + arguments[0];
168
+ const key = splittedStack[1].toUpperCase() + ATTHERATE + arguments[0];
170
169
  routeManager.setRoute(key, splittedStack[0]);
171
170
  } catch (error) {
172
171
 
@@ -7,7 +7,6 @@
7
7
  const requestManager = require("../../core/request-manager");
8
8
  const secUtils = require('../../core/sec-utils');
9
9
  const { ATTHERATE, DOUBLE_DOLLAR } = require('../../core/constants');
10
- const lodash = require('lodash');
11
10
  const routeManager = require('../../core/route-manager');
12
11
  const semver = require('semver')
13
12
  const API = require("../../../nr-security-api");
@@ -44,7 +43,7 @@ const setupRouteHandler = (shim, fastify, moduleName) => {
44
43
  try {
45
44
  const stakTrace = secUtils.traceElementForRoute();
46
45
  const splittedStack = stakTrace[0].split(DOUBLE_DOLLAR);
47
- const key = lodash.upperCase(splittedStack[1]) + ATTHERATE + arguments[0];
46
+ const key = splittedStack[1].toUpperCase() + ATTHERATE + arguments[0];
48
47
  routeManager.setRoute(key, splittedStack[0]);
49
48
  } catch (error) {
50
49
  }
@@ -141,7 +140,8 @@ function extractParams(shim, req) {
141
140
  }
142
141
  });
143
142
  }
144
- const txInfo = lodash.get(req, Object.getOwnPropertySymbols(req).find(symbol => symbol.toString() === 'Symbol(fastify.context)'));
143
+ const symbolKey = Object.getOwnPropertySymbols(req).find(symbol => symbol.toString() === 'Symbol(fastify.context)');
144
+ const txInfo = symbolKey ? req[symbolKey] : undefined;
145
145
  if (request && txInfo && txInfo.config && txInfo.config.url) {
146
146
  request.uri = txInfo.config.url;
147
147
  requestManager.setRequest(transaction.id, request);
@@ -16,7 +16,6 @@ const logger = API.getLogger();
16
16
  const { STRING, QUESTIONMARK, DOTDOTSLASH, UNDEFINED, SELF_FD_PATH, SLASH, SLASHDOTDOT, NR_CSEC_FUZZ_REQUEST_ID } = require('../../core/constants');
17
17
  const fsConsts = process.binding('constants').fs;
18
18
  const agentModule = API.getSecAgent();
19
- const lodash = require('lodash');
20
19
 
21
20
  const requireHook = require('../require/nr-require');
22
21
 
@@ -132,7 +131,7 @@ function openHook(shim, mod, moduleName) {
132
131
  parameters[0] = arguments[0];
133
132
  }
134
133
  }
135
- if (request && typeof parameters[0] === STRING && !lodash.isEmpty(parameters[0])) {
134
+ if (request && typeof parameters[0] === STRING && parameters[0]) {
136
135
  const policy = API.getPolicy();
137
136
  const dynamicScanningFlag = policy.data ? policy.data.vulnerabilityScan.iastScan.enabled : false;
138
137
  const url = request.url;
@@ -187,7 +186,7 @@ function probableToFAHooks(shim, mod, moduleName) {
187
186
  const interceptedArgs = [arguments[0]];
188
187
  shim.interceptedArgs = interceptedArgs;
189
188
  const request = requestManager.getRequest(shim);
190
- if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
189
+ if (request && typeof arguments[0] === STRING && arguments[0]) {
191
190
  const traceObject = secUtils.getTraceObject(shim);
192
191
  let absoluteParameters = [parameters[0]];
193
192
  const secMetadata = securityMetaData.getSecurityMetaData(request, absoluteParameters, traceObject, secUtils.getExecutionId(), EVENT_TYPE.FILE_OPERATION, EVENT_CATEGORY.FILE)
@@ -222,7 +221,7 @@ function probableToFIHooks(shim, mod, moduleName) {
222
221
  const interceptedArgs = [arguments[0]];
223
222
  shim.interceptedArgs = interceptedArgs;
224
223
  const request = requestManager.getRequest(shim);
225
- if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
224
+ if (request && typeof arguments[0] === STRING && arguments[0]) {
226
225
  const traceObject = secUtils.getTraceObject(shim);
227
226
  let absoluteParameters = [parameters[0]];
228
227
  if (fun === COPY_FILE || fun === RENAME) {
@@ -259,7 +258,7 @@ function probablePromiseToFAHooks(shim, mod, moduleName) {
259
258
  const interceptedArgs = [arguments[0]];
260
259
  shim.interceptedArgs = interceptedArgs;
261
260
  const request = requestManager.getRequest(shim);
262
- if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
261
+ if (request && typeof arguments[0] === STRING && arguments[0]) {
263
262
  const traceObject = secUtils.getTraceObject(shim);
264
263
  let absoluteParameters = [parameters[0]];
265
264
  const secMetadata = securityMetaData.getSecurityMetaData(request, absoluteParameters, traceObject, secUtils.getExecutionId(), EVENT_TYPE.FILE_OPERATION, EVENT_CATEGORY.FILE)
@@ -287,7 +286,7 @@ function probablePromiseToFIHooks(shim, mod, moduleName) {
287
286
  const interceptedArgs = [arguments[0]];
288
287
  shim.interceptedArgs = interceptedArgs;
289
288
  const request = requestManager.getRequest(shim);
290
- if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
289
+ if (request && typeof arguments[0] === STRING && arguments[0]) {
291
290
  const traceObject = secUtils.getTraceObject(shim);
292
291
  let absoluteParameters = [parameters[0]];
293
292
  if (fun === COPY_FILE || fun === RENAME) {
@@ -15,7 +15,6 @@
15
15
  const requestManager = require("../../core/request-manager");
16
16
  const secUtils = require('../../core/sec-utils');
17
17
  const { ATTHERATE, DOUBLE_DOLLAR } = require('../../core/constants');
18
- const lodash = require('lodash');
19
18
  const routeManager = require('../../core/route-manager');
20
19
  const API = require("../../../nr-security-api");
21
20
  const logger = API.getLogger();
@@ -58,7 +57,7 @@ function wrapProtoRoute(shim, proto) {
58
57
  const obj = args[0];
59
58
  for (let i = 0; i < obj.length; i++) {
60
59
  try {
61
- const method = lodash.upperCase(obj[i].method);
60
+ const method = obj[i].method.toUpperCase();
62
61
  const path = obj[i].path;
63
62
  const stakTrace = secUtils.traceElementForRoute();
64
63
  const splittedStack = stakTrace[0].split(DOUBLE_DOLLAR);
@@ -13,7 +13,6 @@ const UINT8ARRAY_TYPE = 'Uint8Array';
13
13
  const OBJECT_TYPE = 'object'
14
14
  const unescapeJs = require('unescape-js');
15
15
  const ConType = require('content-type');
16
- const lodash = require('lodash');
17
16
  const URL = require('url')
18
17
  const secUtils = require('../../core/sec-utils');
19
18
  const API = require("../../../nr-security-api");
@@ -69,7 +68,7 @@ function setupRequestMapCleanup() {
69
68
  if (NRAgent) {
70
69
  NRAgent.on('transactionFinished', function onTransactionFinished(transaction) {
71
70
  const requestData = requestManager.getRequestFromId(transaction.id);
72
- if (requestData && requestData.tempFiles && !lodash.isEmpty(requestData.tempFiles)) {
71
+ if (requestData && requestData.tempFiles && requestData.tempFiles.length > 0) {
73
72
  const tempFiles = requestData.tempFiles;
74
73
  for (let i = 0; i < tempFiles.length; i++) {
75
74
  const file = tempFiles[i];
@@ -123,7 +122,7 @@ function outboundHook(shim, mod, method, moduleName) {
123
122
  let completeURL = data.protocol + '//' + data.headers.host + (data.port ? (':' + data.port) : '') + data.path;
124
123
  completeURL = completeURL.split(QUESTION_MARK)[0];
125
124
 
126
- if (request && !lodash.isEmpty(data.headers.host) && !lodash.isEmpty(data.path)) {
125
+ if (request && data.headers.host && data.path) {
127
126
  const appUUID = API.getSecAgent().applicationInfo.applicationUUID;
128
127
  const id = secUtils.getExecutionId().toString();
129
128
  let generateFlag = false;
@@ -181,7 +180,7 @@ function parseFuzzheaders(requestData, transactionId) {
181
180
  let encryptedData = additionalData[6].trim();
182
181
  let hashVerifier = additionalData[7].trim();
183
182
 
184
- if (lodash.isEmpty(encryptedData) || lodash.isEmpty(hashVerifier)) {
183
+ if (!encryptedData || !hashVerifier) {
185
184
  return;
186
185
  }
187
186
  let decryptedData = secUtils.decryptData(encryptedData);
@@ -427,7 +426,8 @@ function responseHook(resp, req, shim) {
427
426
  return function wrappedEnd() {
428
427
  const response = this;
429
428
  const request = requestManager.getRequest(shim);
430
- const txInfo = lodash.get(response, Object.getOwnPropertySymbols(response).find(symbol => symbol.toString() === 'Symbol(transactionInfo)'));
429
+ const symbolKey = Object.getOwnPropertySymbols(response).find(symbol => symbol.toString() === 'Symbol(transactionInfo)');
430
+ const txInfo = symbolKey ? response[symbolKey] : undefined;
431
431
  try {
432
432
  if (txInfo && txInfo.error && request) {
433
433
  ExceptionReporting.generateExceptionReportingEvent(txInfo.error, request);
@@ -756,7 +756,7 @@ function trustBoundaryCheck(sessionObject, shim) {
756
756
  params.push(String(sessionObject[key]));
757
757
  }
758
758
  });
759
- if (!lodash.isEmpty(params)) {
759
+ if (params.length > 0) {
760
760
  const traceObject = secUtils.getTraceObject(shim);
761
761
  const secMetadata = securityMetaData.getSecurityMetaData(request, params, traceObject, secUtils.getExecutionId(), EVENT_TYPE.TRUSTBOUNDARY, EVENT_CATEGORY.TRUSTBOUNDARY)
762
762
  const secEvent = API.generateSecEvent(secMetadata);
@@ -7,7 +7,6 @@ module.exports = initialize
7
7
  const requestManager = require('../../../core/request-manager');
8
8
  const secUtils = require('../../../core/sec-utils');
9
9
  const { ATTHERATE, DOUBLE_DOLLAR } = require('../../../core/constants');
10
- const lodash = require('lodash');
11
10
  const routeManager = require('../../../core/route-manager');
12
11
  const url = require('url');
13
12
  const API = require("../../../../nr-security-api");
@@ -34,7 +33,7 @@ function initialize(shim, mod, moduleName) {
34
33
  try {
35
34
  const stakTrace = secUtils.traceElementForRoute();
36
35
  const splittedStack = stakTrace[0].split(DOUBLE_DOLLAR);
37
- const key = lodash.upperCase(splittedStack[1]) + ATTHERATE + arguments[0];
36
+ const key = splittedStack[1].toUpperCase() + ATTHERATE + arguments[0];
38
37
  routeManager.setRoute(key, splittedStack[0]);
39
38
  } catch (error) {
40
39
  }
@@ -88,7 +87,7 @@ function paramHook(shim, mod, moduleName) {
88
87
  });
89
88
  }
90
89
  // logic to get path param
91
- if (!lodash.isEmpty(result)) {
90
+ if (!!result) {
92
91
  Object.keys(result).forEach(function (key) {
93
92
  if (result[key]) {
94
93
  if (!request.parameterMap[key]) {
@@ -8,7 +8,6 @@ const requestManager = require("../../core/request-manager");
8
8
  const API = require("../../../nr-security-api");
9
9
  const routeManager = require('../../core/route-manager');
10
10
  const logger = API.getLogger();
11
- const lodash = require('lodash');
12
11
  const { ATTHERATE, DOUBLE_DOLLAR, EMPTY_STR } = require('../../core/constants');
13
12
 
14
13
  const semver = require('semver')
@@ -7,7 +7,6 @@ module.exports = initialize
7
7
  const requestManager = require('../../core/request-manager');
8
8
  const secUtils = require('../../core/sec-utils');
9
9
  const { ATTHERATE, DOUBLE_DOLLAR } = require('../../core/constants');
10
- const lodash = require('lodash');
11
10
  const routeManager = require('../../core/route-manager');
12
11
  const url = require('url');
13
12
  const API = require("../../../nr-security-api");
@@ -31,7 +30,7 @@ function initialize(shim, mod, moduleName) {
31
30
  return function wrapper() {
32
31
  if (arguments[0]) {
33
32
  try {
34
- const method = lodash.upperCase(arguments[0].method);
33
+ const method = arguments[0].method.toUpperCase();
35
34
  const path = arguments[0].path;
36
35
  const key = method + ATTHERATE + path;
37
36
  const stakTrace = secUtils.traceElementForRoute();
@@ -7,7 +7,6 @@ module.exports = initialize
7
7
  const requestManager = require('../../core/request-manager');
8
8
  const secUtils = require("../../core/sec-utils");
9
9
  const API = require("../../../nr-security-api");
10
- const lodash = require('lodash');
11
10
  const securityMetaData = require('../../core/security-metadata');
12
11
  const { EVENT_TYPE, EVENT_CATEGORY } = require('../../core/event-constants');
13
12
  const { NR_CSEC_FUZZ_REQUEST_ID, QUESTION_MARK, EMPTY_STRING, COLON, SLASH } = require('../../core/constants');
@@ -103,7 +102,7 @@ function fetchHook(shim, mod, methodName) {
103
102
  data.port = parsedUrl.port ? parsedUrl.port : parsedUrl.port;
104
103
 
105
104
  shim.interceptedArgs = data;
106
- if (request && !lodash.isEmpty(data.headers.host) && !lodash.isEmpty(data.path)) {
105
+ if (request && data.headers.host && data.path) {
107
106
  const appUUID = API.getSecAgent().applicationInfo.applicationUUID;
108
107
  const traceObject = secUtils.getTraceObject(shim);
109
108
  const secMetadata = securityMetaData.getSecurityMetaData(request, data, traceObject, secUtils.getExecutionId(), EVENT_TYPE.HTTP_REQUEST, EVENT_CATEGORY.HTTP)
@@ -11,7 +11,6 @@ const logger = logs.getLogger();
11
11
  const initLogger = logs.getInitLogger();
12
12
  const LinkingMetaData = require('./LinkingMetadata');
13
13
  const LogMessage = require('./LogMessage');
14
- const lodash = require('lodash');
15
14
 
16
15
 
17
16
  /* eslint-disable camelcase */
@@ -47,7 +46,7 @@ function AuthHeaders() {
47
46
  instanceCount = 0;
48
47
  }
49
48
  authHeaders['NR-CSEC-IAST-SCAN-INSTANCE-COUNT'] = instanceCount ? instanceCount : 0
50
- if ((NRAgent.config.security.iast_test_identifier && !lodash.isEmpty(NRAgent.config.security.iast_test_identifier)) || process.env.NEW_RELIC_SECURITY_IAST_TEST_IDENTIFIER) {
49
+ if ((NRAgent.config.security.iast_test_identifier && NRAgent.config.security.iast_test_identifier) || process.env.NEW_RELIC_SECURITY_IAST_TEST_IDENTIFIER) {
51
50
  let iast_test_identifier = NRAgent.config.security.iast_test_identifier || process.env.NEW_RELIC_SECURITY_IAST_TEST_IDENTIFIER
52
51
  authHeaders['NR-CSEC-IAST-TEST-IDENTIFIER'] = iast_test_identifier;
53
52
  logger.debug("iast_test_identifier is:", iast_test_identifier);
@@ -6,17 +6,12 @@
6
6
 
7
7
  const API = require('../../../nr-security-api');
8
8
  const NRAgent = API.getNRAgent();
9
- const { Agent } = require('./agent');
10
-
11
9
  let policy;
12
- const path = require('path');
13
- const fs = require('fs');
14
- const yaml = require('js-yaml');
15
10
  const logs = require('./logging');
16
11
  const logger = logs.getLogger();
17
12
  const initLogger = logs.getInitLogger();
18
- const jsonValidator = require('./jsonValidator');
19
13
  const LOG_MESSAGES = require('./sec-agent-constants').LOG_MESSAGES;
14
+ const default_policy = {"version":"DEFAULT","logLevel":"INFO","policyPull":true,"policyPullInterval":60,"vulnerabilityScan":{"enabled":false,"cveScan":{"enabled":false,"enableEnvScan":false,"cveDefinitionUpdateInterval":360},"iastScan":{"enabled":false,"probing":{"interval":1,"batchSize":17}}},"protectionMode":{"enabled":false,"ipBlocking":{"enabled":false,"attackerIpBlocking":false,"ipDetectViaXFF":false,"timeout":2},"apiBlocking":{"enabled":false,"protectAllApis":false,"protectKnownVulnerableApis":false,"protectAttackedApis":false}},"sendCompleteStackTrace":false,"enableHTTPRequestPrinting":false,"policyParameters":{"allowedIps":[],"blockedIps":[],"allowedApis":[],"blockedApis":[],"allowedRequests":[]}}
20
15
 
21
16
  function Policy() {
22
17
  this.data = {};
@@ -40,12 +35,6 @@ function getInstance() {
40
35
  // sets up policy data to use globally.
41
36
  function setPolicyData(data) {
42
37
  policy = getInstance();
43
- const jsonValidationResult = jsonValidator.validate(data);
44
- if (jsonValidationResult && jsonValidationResult.errors && jsonValidationResult.errors.length > 0) {
45
- logger.error(LOG_MESSAGES.EXP_RAISE_POL, JSON.stringify(jsonValidationResult.errors));
46
- logger.info(LOG_MESSAGES.FALLBACK_TO_CURR_POLICY, JSON.stringify(policy.data));
47
- return false;
48
- }
49
38
  if (policy.data.version !== data.version) {
50
39
  policy.data = data;
51
40
  appInfoVersionUpdate(policy, data);
@@ -59,13 +48,7 @@ function setPolicyData(data) {
59
48
 
60
49
  // function to setup default policy provided in resources directory
61
50
  function setDefaultPolicy() {
62
- let default_policy_file = path.resolve(__dirname, '../../resources/default-policy.yaml');
63
- if(process.platform == 'win32'){
64
- default_policy_file = path.resolve(__dirname, '..\\..\\resources\\default-policy.yaml');
65
- }
66
- // Get document, or throw exception on error
67
51
  try {
68
- const default_policy = yaml.load(fs.readFileSync(default_policy_file, 'utf8'));
69
52
  policy = getInstance();
70
53
  policy.data = default_policy;
71
54
  logger.info(LOG_MESSAGES.DEFAULT_POL_SET, JSON.stringify(policy.data));
@@ -76,8 +59,8 @@ function setDefaultPolicy() {
76
59
 
77
60
  /**
78
61
  * Function to set applicationInfo with updated policy version
79
- * @param {*} policy
80
- * @param {*} data
62
+ * @param {*} policy
63
+ * @param {*} data
81
64
  */
82
65
  function appInfoVersionUpdate(policy, data) {
83
66
  const appInfo = require('./applicationinfo').getInstance();
@@ -9,7 +9,6 @@ const { BasicInfo } = require('./event');
9
9
  const { JsonHandler } = require('./json-file-handler');
10
10
  const fs = require('fs');
11
11
  const shaSizeUtil = require('./sha-size-util');
12
- const _ = require('lodash');
13
12
  const OS = require('os');
14
13
  const { Agent } = require('./agent');
15
14
  const commonUtils = require('./commonUtils');
@@ -115,7 +114,7 @@ function ApplicationInfo () {
115
114
  this.identifier.envInfo.name = getHostName();
116
115
  this.identifier.envInfo.ipaddress = localIpAddress();
117
116
 
118
- if (!_.isEmpty(containerId)) {
117
+ if (containerId) {
119
118
  this.identifier.id = containerId;
120
119
  this.identifier.kind = "CONTAINER";
121
120
  const containerProps = setContainerProperties(this.identifier);
@@ -131,10 +130,10 @@ function ApplicationInfo () {
131
130
  } else if (isLambda) {
132
131
  const lambdaARN = process.env[AWS_LAMBDA_QUALIFIED_ARN_ENV_IDENTIFIER];
133
132
  const lambdaVersion = process.env[AWS_LAMBDA_FUNCTION_VERSION_ENV_IDENTIFIER];
134
- this.applicationUUID = _.isEmpty(lambdaARN) ? ApplicationInfo.Constants.EMPTY_UUID : `${lambdaARN}:${lambdaVersion}`;
133
+ this.applicationUUID = !lambdaARN ? ApplicationInfo.Constants.EMPTY_UUID : `${lambdaARN}:${lambdaVersion}`;
135
134
  this.identifier.isHost = true;
136
135
  this.identifier.isLambda = isLambda;
137
- this.identifier.lambdaFunctionARN = _.isEmpty(lambdaARN)
136
+ this.identifier.lambdaFunctionARN = !lambdaARN
138
137
  ? `${process.env[AWS_LAMBDA_FUNCTION_NAME_ENV_IDENTIFIER]}:${lambdaVersion}`
139
138
  : `${lambdaARN}:${lambdaVersion}`;
140
139
  this.identifier.lambdaAWSSessionToken = process.env[AWS_SESSION_TOKEN_ENV_IDENTIFIER];
@@ -347,7 +346,7 @@ function getContainerID () {
347
346
  // podman
348
347
  if (st.indexOf(LIBPOD) > -1 && st.indexOf(SCOPE_IDENTIFIER) > -1) {
349
348
  const containerId = st.split(LIBPOD).pop().split(SCOPE_IDENTIFIER)[0];
350
- if (!_.isEmpty(containerId)) {
349
+ if (containerId) {
351
350
  return containerId;
352
351
  }
353
352
  }
@@ -17,16 +17,14 @@ const { CSEC_HOME, SLASH, EMPTY_STR } = require('./sec-agent-constants');
17
17
  const njsAgentConstants = require('./sec-agent-constants');
18
18
  const API = require('../../../nr-security-api');
19
19
  const NRAgent = API.getNRAgent();
20
- const lodash = require('lodash')
21
20
  const backupLogFileRegex = /.log.\d/gm;
22
21
  let websocketHealth;
23
22
 
24
23
  const ringBuffer = require('ringbufferjs');
25
24
  const bufferedLogEvents = new ringBuffer(10);
26
- const { CronJob } = require('cron');
25
+ const nodeCron = require('node-cron');
27
26
  let scanStartTime = 0;
28
27
  let trafficStartedTime = 0;
29
- const cron = require('cron');
30
28
 
31
29
  const skip_detection_category_map = {
32
30
  insecure_settings: ['CRYPTO', 'HASH', 'RANDOM', 'SECURE_COOKIE', 'TRUSTBOUNDARY'],
@@ -72,7 +70,7 @@ function getKindIdPair(identifier, hostId) {
72
70
 
73
71
  /**
74
72
  * Utility to check worker thread support
75
- * @returns
73
+ * @returns
76
74
  */
77
75
  function hasWorker() {
78
76
  let workerFlag = false;
@@ -109,7 +107,7 @@ function runtimeSupportsAsyncFunctionGenerators() {
109
107
 
110
108
  /**
111
109
  * Utility to create directory and set permissions
112
- * @param {*} dir
110
+ * @param {*} dir
113
111
  */
114
112
  function createPathIfNotExist(dir) {
115
113
  try {
@@ -131,7 +129,7 @@ function createPathIfNotExist(dir) {
131
129
 
132
130
  /**
133
131
  * Utility to get OS
134
- * @returns
132
+ * @returns
135
133
  */
136
134
  function getOS() {
137
135
  if (process.platform === 'darwin') {
@@ -351,11 +349,11 @@ function logRollOver() {
351
349
 
352
350
  /**
353
351
  * Utility to get validator service endpoint
354
- * @returns
352
+ * @returns
355
353
  */
356
354
  function getValidatorServiceEndpointURL() {
357
355
  let validatorServiceEndpointURL = NRAgent ? NRAgent.config.security.validator_service_url : "wss://csec.nr-data.net";
358
- if (lodash.isEmpty(validatorServiceEndpointURL)) {
356
+ if (!validatorServiceEndpointURL) {
359
357
  validatorServiceEndpointURL = "wss://csec.nr-data.net";
360
358
  }
361
359
  return validatorServiceEndpointURL
@@ -363,7 +361,7 @@ function getValidatorServiceEndpointURL() {
363
361
 
364
362
  /**
365
363
  * Utility to get security mode
366
- * @returns
364
+ * @returns
367
365
  */
368
366
  function getCSECmode() {
369
367
  const mode = NRAgent ? NRAgent.config.security.mode : 'IAST';
@@ -372,7 +370,7 @@ function getCSECmode() {
372
370
 
373
371
  /**
374
372
  * Utility to get path of CA Cert
375
- * @returns
373
+ * @returns
376
374
  */
377
375
  function getPathOfCACert() {
378
376
  let relativePath = path.resolve(__dirname, '../../resources/cert.pem');
@@ -384,7 +382,7 @@ function getPathOfCACert() {
384
382
  }
385
383
  /**
386
384
  * Setting ws health status
387
- * @param {*} status
385
+ * @param {*} status
388
386
  */
389
387
  function setWSHealthStatus(status) {
390
388
  websocketHealth = status;
@@ -424,7 +422,7 @@ function addLogEventtoBuffer(logMessage) {
424
422
  }
425
423
  /**
426
424
  * Utility to get framework from APM
427
- * @returns
425
+ * @returns
428
426
  */
429
427
  function getFramework() {
430
428
  let framework = EMPTY_STR;
@@ -451,6 +449,8 @@ function listSkipDetectionCategory() {
451
449
  return skipList;
452
450
  }
453
451
 
452
+ let cronJobInstance = null;
453
+
454
454
  function refreshAgent() {
455
455
  const { Agent } = require('./agent');
456
456
  if (Agent.getAgent().status.getStatus() == 'disabled' || Agent.getAgent().delayed) {
@@ -465,22 +465,32 @@ function refreshAgent() {
465
465
  function executeCronSchedule() {
466
466
  try {
467
467
  let schedule = NRAgent.config.security.scan_schedule.schedule;
468
- if (lodash.isEmpty(schedule)) {
468
+ if (!schedule) {
469
+ return;
470
+ }
471
+
472
+ // Prevent creating multiple cron jobs
473
+ if (cronJobInstance) {
469
474
  return;
470
475
  }
476
+
471
477
  logger.debug("Schedule config is set to:", schedule);
472
478
  schedule = schedule.replace(/\?/g, '*');
473
- logger.info("Security Agent scheduled time is set to:", getScheduledScanTime(Math.ceil(cron.timeout(schedule) / 60000)))
474
- const job = new cron.CronJob(
475
- schedule, // cronTime
476
- function () {
477
- logger.debug('Cron schedule invoked');
478
- logger.info("Security Agent scheduled time is set to:", getScheduledScanTime(Math.ceil(cron.timeout(schedule) / 60000)))
479
- refreshAgent()
480
- }, // onTick
481
- null, // onComplete
482
- true, // start
479
+ logger.info("Security Agent scheduled time is set to:", schedule);
480
+ const { Agent } = require('./agent');
481
+ Agent.getAgent().delayed = true
482
+ cronJobInstance = nodeCron.schedule(
483
+ schedule,
484
+ () => {
485
+ logger.info('Cron schedule invoked at the schedule:',schedule);
486
+ refreshAgent();
487
+ },
488
+ {
489
+ scheduled: true,
490
+ runOnInit: false,
491
+ }
483
492
  );
493
+ logger.debug("Cron job instance created successfully");
484
494
  } catch (error) {
485
495
  logger.error("Error while processing schedule. Please check schedule cron expression", error);
486
496
  shutDownAgent();
@@ -506,7 +516,7 @@ function honourDurationConfiguration() {
506
516
  }
507
517
  /**
508
518
  * Utility to send error to error inbox of APM
509
- * @param {*} error
519
+ * @param {*} error
510
520
  */
511
521
  function sendErrorToErrorInbox(error) {
512
522
  API.newrelic.noticeError(error);
@@ -3,8 +3,6 @@
3
3
  * SPDX-License-Identifier: New Relic Software License v1.0
4
4
  */
5
5
 
6
- const _ = require('lodash');
7
-
8
6
  const logger = require('../logging').getLogger();
9
7
 
10
8
  let lambdaClient;
@@ -21,7 +19,7 @@ function invokeLambda (arn, version, data) {
21
19
  if (!lambdaClient) {
22
20
  throw new Error('Cannot invoke lambda, client not initialized');
23
21
  }
24
- if (_.isEmpty(arn) || _.isEmpty(version)) {
22
+ if (!arn || !version) {
25
23
  throw new Error('Cannot invoke lambda, invalid ARN specified');
26
24
  }
27
25
  const dataString = JSON.stringify(data);
@@ -3,8 +3,6 @@
3
3
  * SPDX-License-Identifier: New Relic Software License v1.0
4
4
  */
5
5
 
6
- const _ = require('lodash');
7
-
8
6
  const { SERVER_COMMAND, SEVERE } = require('../../../sec-agent-constants');
9
7
  const UnsupportedAgentHandler = require('./unsupported-agent-handler');
10
8
  const StartupHandshakeHandler = require('./startup-handshake-handler');
@@ -47,7 +45,7 @@ const handle = function handle (json) {
47
45
  };
48
46
 
49
47
  const setLogger = function setLogger (logger) {
50
- _.forEach(commandHandlerMap, (handler) => {
48
+ Object.values(commandHandlerMap).forEach((handler) => {
51
49
  handler.setLogger(logger);
52
50
  });
53
51
  NoOpHandler.setLogger(logger);
@@ -10,7 +10,6 @@ const policyManager = require('./Policy');
10
10
  const LinkingMetaData = require('./LinkingMetadata');
11
11
  const API = require('../../../nr-security-api');
12
12
  const NRAgent = API.getNRAgent();
13
- const lodash = require('lodash');
14
13
  const commonUtils = require('./commonUtils');
15
14
  const crypto = require('crypto');
16
15
  /**
@@ -32,7 +31,8 @@ function BasicInfo() {
32
31
  this.framework = EMPTY_STR;
33
32
  }
34
33
  this.groupName = commonUtils.getCSECmode();
35
- this.policyVersion = (!lodash.isEmpty(policyManager.getInstance().data)) ? policyManager.getInstance().data.version : 'DEFAULT';
34
+ const policyData = policyManager.getInstance().data;
35
+ this.policyVersion = (policyData && Object.keys(policyData).length > 0) ? policyData.version : 'DEFAULT';
36
36
 
37
37
  if (NRAgent && NRAgent.config) {
38
38
  this.appAccountId = NRAgent.config.account_id;
@@ -3,7 +3,6 @@
3
3
  * SPDX-License-Identifier: New Relic Software License v1.0
4
4
  */
5
5
 
6
- const _ = require('lodash');
7
6
  const decode = require('unescape');
8
7
  const querystring = require('querystring');
9
8
 
@@ -178,7 +177,7 @@ function getXSSConstructs (data) {
178
177
  return constructs;
179
178
  }
180
179
 
181
- if (_.isEmpty(tagName)) {
180
+ if (!tagName) {
182
181
  return constructs;
183
182
  }
184
183
 
@@ -206,7 +205,7 @@ function getXSSConstructs (data) {
206
205
  attribRegex.lastIndex++;
207
206
  }
208
207
 
209
- let attribData = _.trim(attribMatcher[0]);
208
+ let attribData = attribMatcher[0].trim();
210
209
 
211
210
  currPos = attribRegex.lastIndex - 1;
212
211
  tmpCurrPos = data.indexOf(ANGLE_END, tmpStartPos);
@@ -214,7 +213,7 @@ function getXSSConstructs (data) {
214
213
  if ((tmpCurrPos === -1 || attribMatcher.index < tmpCurrPos)) {
215
214
  tmpStartPos = tmpCurrPos = attribRegex.lastIndex - 1;
216
215
  tmpStartPos++;
217
- if (_.isEmpty(attribMatcher[3]) && attribRegex.lastIndex >= tmpCurrPos) {
216
+ if (!attribMatcher[3] && attribRegex.lastIndex >= tmpCurrPos) {
218
217
  tmpStartPos = tmpCurrPos = data.indexOf(ANGLE_END, attribMatcher.index);
219
218
  if (tmpStartPos > -1) {
220
219
  attribData = attribData.substring(0, tmpStartPos);
@@ -224,7 +223,7 @@ function getXSSConstructs (data) {
224
223
  const val = attribData.split(EQUALS)[1];
225
224
  const upperCaseAttribKey = key.toUpperCase();
226
225
 
227
- if (!_.isEmpty(key) && (upperCaseAttribKey.startsWith('ON') || upperCaseAttribKey === 'SRC' || upperCaseAttribKey === 'HREF' ||
226
+ if (key && (upperCaseAttribKey.startsWith('ON') || upperCaseAttribKey === 'SRC' || upperCaseAttribKey === 'HREF' ||
228
227
  upperCaseAttribKey === 'ACTION' || upperCaseAttribKey === 'FORMACTION' || upperCaseAttribKey === 'SRCDOC' ||
229
228
  upperCaseAttribKey === 'DATA' || decode(val).toUpperCase().replace(/\s/g, '').includes('JAVASCRIPT:') ||
230
229
  htmlEntities.decode(val).toUpperCase().replace(/\s/g, '').includes('JAVASCRIPT:'))) {
@@ -259,7 +258,7 @@ function getXSSConstructs (data) {
259
258
  let body = data.substring(currPos + 1);
260
259
  const tagEnd = body.indexOf(ANGLE_END);
261
260
 
262
- if (!_.isEmpty(body) && tagEnd !== -1) {
261
+ if (body && tagEnd !== -1) {
263
262
  body = data.substring(tagEnd);
264
263
  constructs.add(data.substring(startPos, currPos + 1) + body);
265
264
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newrelic/security-agent",
3
- "version": "3.0.1",
3
+ "version": "3.0.3",
4
4
  "description": "New Relic Security Agent for Node.js",
5
5
  "main": "index.js",
6
6
  "jsonVersion": "1.2.9",
@@ -41,18 +41,14 @@
41
41
  "dependencies": {
42
42
  "check-disk-space": "^3.4.0",
43
43
  "content-type": "^1.0.5",
44
- "cron": "^3.1.7",
45
44
  "fast-safe-stringify": "^2.1.1",
46
45
  "find-package-json": "^1.2.0",
47
46
  "hash.js": "^1.1.7",
48
47
  "html-entities": "^2.3.6",
49
48
  "https-proxy-agent": "^7.0.4",
50
49
  "is-invalid-path": "^1.0.2",
51
- "js-yaml": "^4.1.1",
52
- "jsonschema": "^1.4.1",
53
- "lodash": "^4.17.23",
54
50
  "log4js": "^6.9.1",
55
- "pretty-bytes": "^5.6.0",
51
+ "node-cron": "^4.2.1",
56
52
  "request-ip": "^3.3.0",
57
53
  "ringbufferjs": "^2.0.0",
58
54
  "semver": "^7.5.4",
@@ -1,149 +0,0 @@
1
- /*
2
- * Copyright 2023 New Relic Corporation. All rights reserved.
3
- * SPDX-License-Identifier: New Relic Software License v1.0
4
- */
5
-
6
- const Validator = require('jsonschema').Validator;
7
- const v = new Validator();
8
- const schema = {
9
- title: 'LCPolicy',
10
- description: 'A policy for language collectors',
11
- type: 'object',
12
- properties: {
13
- version: {
14
- type: 'string',
15
- minLength: 1
16
- },
17
- policyPull: {
18
- type: 'boolean'
19
- },
20
- policyPullInterval: {
21
- type: 'integer',
22
- minimum: 0,
23
- maximum: 2678400
24
- },
25
- vulnerabilityScan: {
26
- type: 'object',
27
- properties: {
28
- enabled: {
29
- type: 'boolean'
30
- },
31
- iastScan: {
32
- type: 'object',
33
- properties: {
34
- enabled: {
35
- type: 'boolean'
36
- },
37
- probing: {
38
- type: 'object',
39
- properties: {
40
- interval: {
41
- type: 'integer',
42
- minimum: 1,
43
- maximum: 60
44
- },
45
- batchSize: {
46
- type: 'integer',
47
- minimum: 1,
48
- maximum: 300
49
- }
50
- },
51
- required: [
52
- 'interval',
53
- 'batchSize'
54
- ]
55
- }
56
- },
57
- required: [
58
- 'enabled',
59
- 'probing'
60
- ]
61
- }
62
- },
63
- required: [
64
- 'enabled',
65
- 'iastScan'
66
- ]
67
- },
68
- protectionMode: {
69
- type: 'object',
70
- properties: {
71
- enabled: {
72
- type: 'boolean'
73
- },
74
- ipBlocking: {
75
- type: 'object',
76
- properties: {
77
- enabled: {
78
- type: 'boolean'
79
- },
80
- attackerIpBlocking: {
81
- type: 'boolean'
82
- },
83
- ipDetectViaXFF: {
84
- type: 'boolean'
85
- }
86
- },
87
- required: [
88
- 'enabled',
89
- 'attackerIpBlocking',
90
- 'ipDetectViaXFF'
91
- ]
92
- },
93
- apiBlocking: {
94
- type: 'object',
95
- properties: {
96
- enabled: {
97
- type: 'boolean'
98
- },
99
- protectAllApis: {
100
- type: 'boolean'
101
- },
102
- protectKnownVulnerableApis: {
103
- type: 'boolean'
104
- },
105
- protectAttackedApis: {
106
- type: 'boolean'
107
- }
108
- },
109
- required: [
110
- 'enabled',
111
- 'protectAllApis',
112
- 'protectKnownVulnerableApis',
113
- 'protectAttackedApis'
114
- ]
115
- }
116
- },
117
- required: [
118
- 'enabled',
119
- 'ipBlocking',
120
- 'apiBlocking'
121
- ]
122
- },
123
- sendCompleteStackTrace: {
124
- type: 'boolean'
125
- },
126
- enableHTTPRequestPrinting: {
127
- type: 'boolean'
128
- }
129
- },
130
- required: [
131
- 'version',
132
- 'policyPull',
133
- 'policyPullInterval',
134
- 'vulnerabilityScan',
135
- 'protectionMode',
136
- 'sendCompleteStackTrace',
137
- 'enableHTTPRequestPrinting'
138
- ]
139
- };
140
-
141
- function validate (data) {
142
- const result = v.validate(data, schema);
143
- return result;
144
- }
145
-
146
-
147
- module.exports = {
148
- validate
149
- };