@newrelic/security-agent 1.5.0 → 2.1.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 (43) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/THIRD_PARTY_NOTICES.md +48 -1
  3. package/lib/instrumentation-security/core/constants.js +8 -1
  4. package/lib/instrumentation-security/core/event-constants.js +5 -3
  5. package/lib/instrumentation-security/core/request-manager.js +40 -8
  6. package/lib/instrumentation-security/core/sec-utils.js +6 -5
  7. package/lib/instrumentation-security/hooks/director/nr-director.js +6 -6
  8. package/lib/instrumentation-security/hooks/express/nr-express.js +11 -8
  9. package/lib/instrumentation-security/hooks/fastify/nr-fastify.js +6 -6
  10. package/lib/instrumentation-security/hooks/fs/nr-fs.js +11 -28
  11. package/lib/instrumentation-security/hooks/grpc-js/nr-grpc.js +4 -4
  12. package/lib/instrumentation-security/hooks/hapi/nr-hapi.js +7 -7
  13. package/lib/instrumentation-security/hooks/http/nr-http.js +137 -13
  14. package/lib/instrumentation-security/hooks/koa/@koa/nr-@koa-router.js +5 -5
  15. package/lib/instrumentation-security/hooks/ldap/nr-ldap.js +4 -0
  16. package/lib/instrumentation-security/hooks/mongodb/nr-mongodb.js +4 -0
  17. package/lib/instrumentation-security/hooks/mysql/nr-mysql.js +4 -0
  18. package/lib/instrumentation-security/hooks/native/nr-childProcess.js +4 -0
  19. package/lib/instrumentation-security/hooks/postgres/nr-postgres.js +4 -0
  20. package/lib/instrumentation-security/hooks/restify/nr-restify.js +7 -7
  21. package/lib/instrumentation-security/hooks/undici/nr-undici.js +4 -0
  22. package/lib/instrumentation-security/hooks/xpath/nr-xpath.js +4 -0
  23. package/lib/nr-security-agent/index.js +38 -5
  24. package/lib/nr-security-agent/lib/core/Auth-headers.js +20 -0
  25. package/lib/nr-security-agent/lib/core/ExceptionReporting.js +1 -0
  26. package/lib/nr-security-agent/lib/core/Policy.js +0 -12
  27. package/lib/nr-security-agent/lib/core/agent.js +5 -1
  28. package/lib/nr-security-agent/lib/core/applicationinfo.js +2 -2
  29. package/lib/nr-security-agent/lib/core/commonUtils.js +141 -45
  30. package/lib/nr-security-agent/lib/core/connections/websocket/proxy-util.js +61 -0
  31. package/lib/nr-security-agent/lib/core/connections/websocket/response/IASTUtils.js +34 -6
  32. package/lib/nr-security-agent/lib/core/connections/websocket/response/fuzz-request-handler.js +36 -6
  33. package/lib/nr-security-agent/lib/core/connections/websocket/response/startup-handshake-handler.js +5 -1
  34. package/lib/nr-security-agent/lib/core/connections/websocket/response/ws-reconnect.js +7 -4
  35. package/lib/nr-security-agent/lib/core/connections/websocket/websocket.js +32 -14
  36. package/lib/nr-security-agent/lib/core/event.js +2 -2
  37. package/lib/nr-security-agent/lib/core/health-check.js +8 -2
  38. package/lib/nr-security-agent/lib/core/sec-agent-constants.js +2 -3
  39. package/lib/nr-security-agent/lib/core/sec-util.js +40 -4
  40. package/lib/nr-security-agent/lib/core/websocket-client.js +35 -12
  41. package/lib/nr-security-api/index.js +47 -15
  42. package/package.json +10 -4
  43. package/lib/nr-security-agent/lib/core/statusUtils.js +0 -165
package/CHANGELOG.md CHANGED
@@ -1,3 +1,34 @@
1
+ ### v2.1.0 (2024-11-05)
2
+ #### Features
3
+ * IAST support for CI/CD
4
+ * Support for IAST schedule, delay and ignore scan categories
5
+ #### Bug fixes
6
+ * Added default values for scan_schedule, scan_controllers and exclude_from_iast_scan config
7
+ * Fix for security home placeholder replacement in fuzz requests
8
+ * Handling to not resolve file path in fs module instrumentation
9
+ * Fix for batch size and condition of iast-data-request sending
10
+ #### Miscellaneous chores
11
+ * Added requestURI field in http request for application-runtime-error
12
+ * Updated instrumented to get the transaction directly instead of from the active segment
13
+
14
+ ### v2.0.0 (2024-09-20)
15
+ ### ⚠ BREAKING CHANGES
16
+ * Dropped support for Node.js v16
17
+ * Dropped functionality to generate snapshot file
18
+ #### Features
19
+ * Support to honour proxy settings via config
20
+ * Support for secure cookie security event generation
21
+ * Report error to Error Inbox upon connection failure to Security Engine
22
+ * Support to detect application and server path
23
+ * Functionality to truncate Incoming HTTP request upto default limit
24
+ * Dropped support for Node.js v16
25
+ * Dropped functionality to generate snapshot file
26
+ #### Bug fixes
27
+ * Handling for empty data in IAST fuzzing header
28
+ * Added identifiers in events
29
+ * Fix for file integrity security event generation
30
+ * Fix for missing identifiers in iast-data-request JSON
31
+
1
32
  ### v1.5.0 (2024-08-14)
2
33
  #### Features
3
34
  * Support for Node.js v22.x
@@ -17,10 +17,12 @@ code, the source code can be found at [https://github.com/newrelic/csec-node-age
17
17
  * [axios](#axios)
18
18
  * [check-disk-space](#check-disk-space)
19
19
  * [content-type](#content-type)
20
+ * [cron](#cron)
20
21
  * [fast-safe-stringify](#fast-safe-stringify)
21
22
  * [find-package-json](#find-package-json)
22
23
  * [hash.js](#hashjs)
23
24
  * [html-entities](#html-entities)
25
+ * [https-proxy-agent](#https-proxy-agent)
24
26
  * [is-invalid-path](#is-invalid-path)
25
27
  * [js-yaml](#js-yaml)
26
28
  * [jsonschema](#jsonschema)
@@ -149,6 +151,22 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
149
151
 
150
152
  ```
151
153
 
154
+ ### cron
155
+
156
+ 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):
157
+
158
+ ```
159
+ The MIT License (MIT)
160
+ Copyright © 2017 Nicholas Campbell <nicholas.j.campbell@gmail.com>
161
+
162
+ 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:
163
+
164
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
165
+
166
+ 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.
167
+
168
+ ```
169
+
152
170
  ### fast-safe-stringify
153
171
 
154
172
  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):
@@ -239,6 +257,35 @@ THE SOFTWARE.
239
257
 
240
258
  ```
241
259
 
260
+ ### https-proxy-agent
261
+
262
+ This product includes source derived from [https-proxy-agent](https://github.com/TooTallNate/proxy-agents) ([v7.0.4](https://github.com/TooTallNate/proxy-agents/tree/v7.0.4)), distributed under the [MIT License](https://github.com/TooTallNate/proxy-agents/blob/v7.0.4/LICENSE):
263
+
264
+ ```
265
+ (The MIT License)
266
+
267
+ Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net>
268
+
269
+ Permission is hereby granted, free of charge, to any person obtaining
270
+ a copy of this software and associated documentation files (the
271
+ 'Software'), to deal in the Software without restriction, including
272
+ without limitation the rights to use, copy, modify, merge, publish,
273
+ distribute, sublicense, and/or sell copies of the Software, and to
274
+ permit persons to whom the Software is furnished to do so, subject to
275
+ the following conditions:
276
+
277
+ The above copyright notice and this permission notice shall be
278
+ included in all copies or substantial portions of the Software.
279
+
280
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
281
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
282
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
283
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
284
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
285
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
286
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
287
+ ```
288
+
242
289
  ### is-invalid-path
243
290
 
244
291
  This product includes source derived from [is-invalid-path](https://github.com/jonschlinkert/is-invalid-path) ([v1.0.2](https://github.com/jonschlinkert/is-invalid-path/tree/v1.0.2)), distributed under the [MIT License](https://github.com/jonschlinkert/is-invalid-path/blob/v1.0.2/LICENSE):
@@ -588,7 +635,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
588
635
 
589
636
  ### ws
590
637
 
591
- This product includes source derived from [ws](https://github.com/websockets/ws) ([v8.17.1](https://github.com/websockets/ws/tree/v8.17.1)), distributed under the [MIT License](https://github.com/websockets/ws/blob/v8.17.1/LICENSE):
638
+ This product includes source derived from [ws](https://github.com/websockets/ws) ([v8.18.0](https://github.com/websockets/ws/tree/v8.18.0)), distributed under the [MIT License](https://github.com/websockets/ws/blob/v8.18.0/LICENSE):
592
639
 
593
640
  ```
594
641
  Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com>
@@ -62,6 +62,13 @@ module.exports = {
62
62
  UNDEFINED: 'undefined',
63
63
  SELF_FD_PATH: '/proc/self/fd/',
64
64
  NR_CSEC_FUZZ_REQUEST_ID: 'nr-csec-fuzz-request-id',
65
- ASTERISK: "*"
65
+ ASTERISK: "*",
66
+ COMMA_SPACE: ", ",
67
+ SEMI_COLON: ';',
68
+ EQUAL: '=',
69
+ SECURE: 'secure',
70
+ HTTPONLY: 'httponly',
71
+ SAMESITE: 'samesite',
72
+ STRICT: 'strict'
66
73
 
67
74
  };
@@ -20,9 +20,10 @@ const EVENT_TYPE = {
20
20
  UNVALIDATED_REDIRECT: 'UNVALIDATED_REDIRECT',
21
21
  REFLECTED_XSS: 'REFLECTED_XSS',
22
22
  XPATH: 'XPATH',
23
- LDAP: 'LDAP'
23
+ LDAP: 'LDAP',
24
+ SECURE_COOKIE: 'SECURE_COOKIE'
24
25
  }
25
- const EVENT_CATEGORY = {
26
+ const EVENT_CATEGORY = {
26
27
  MYSQL: 'MYSQL',
27
28
  POSTGRES: 'POSTGRES',
28
29
  ORACLE: 'ORACLE',
@@ -40,7 +41,8 @@ const EVENT_CATEGORY = {
40
41
  UNVALIDATED_REDIRECT: 'UNVALIDATED_REDIRECT',
41
42
  REFLECTED_XSS: 'REFLECTED_XSS',
42
43
  XPATH: 'XPATH',
43
- LDAP: 'LDAP'
44
+ LDAP: 'LDAP',
45
+ SECURE_COOKIE: 'SECURE_COOKIE'
44
46
  }
45
47
 
46
48
  module.exports = {
@@ -4,6 +4,10 @@
4
4
  */
5
5
 
6
6
  const requestMap = new Map();
7
+ const API = require("../../nr-security-api");
8
+ const NRAgent = API.getNRAgent();
9
+ const logger = API.getLogger();
10
+ const regexPatterns = NRAgent && NRAgent.config.security.exclude_from_iast_scan.api
7
11
 
8
12
  /**
9
13
  * Utility to get request by transaction Id
@@ -20,7 +24,33 @@ function getRequestFromId(id) {
20
24
  * @param {*} requestData
21
25
  */
22
26
  function setRequest(id, requestData) {
27
+
23
28
  requestMap.set(id, requestData);
29
+ try {
30
+ const stringToMatch = requestData.url;
31
+ // const filteredString = stringToMatch.split('?')[0];
32
+ const filteredString = stringToMatch;
33
+ let isRegexMatchestoURL = false;
34
+ for (let index = 0; index < regexPatterns.length; index++) {
35
+ const regex = new RegExp(regexPatterns[index], 'gm');
36
+ const matchResult = filteredString.match(regex);
37
+ if (matchResult && matchResult.length > 0) {
38
+ const data = matchResult[0];
39
+ if (filteredString === data) {
40
+ isRegexMatchestoURL = true;
41
+ }
42
+ }
43
+ }
44
+ if (isRegexMatchestoURL) {
45
+ requestMap.delete(id);
46
+ if (API.getSecAgent().status.getStatus() !== 'disabled') {
47
+ logger.debug("Excluding URL %s from IAST processing due to ignore API setting", filteredString);
48
+ }
49
+ }
50
+ } catch (error) {
51
+ logger.debug("Error while processing API regex for restriction", error);
52
+ }
53
+
24
54
  }
25
55
 
26
56
  /**
@@ -29,9 +59,9 @@ function setRequest(id, requestData) {
29
59
  * @returns
30
60
  */
31
61
  function getRequest(shim) {
32
- const segment = shim.getActiveSegment();
33
- if (segment) {
34
- const transactionId = segment.transaction.id;
62
+ const transaction = shim.tracer.getTransaction();
63
+ if (transaction) {
64
+ const transactionId = transaction.id;
35
65
  return getRequestFromId(transactionId);
36
66
  }
37
67
  else if (shim.agent.getLinkingMetadata()) {
@@ -48,13 +78,14 @@ function getRequest(shim) {
48
78
  * @param {*} shim
49
79
  * @param {*} data
50
80
  */
51
- function updateRequestBody(shim, data) {
52
- const segment = shim.getActiveSegment();
53
- if (segment) {
54
- const transactionId = segment.transaction.id;
81
+ function updateRequestBody(shim, data, isTruncated) {
82
+ const transaction = shim.tracer.getTransaction();
83
+ if (transaction) {
84
+ const transactionId = transaction.id;
55
85
  const requestData = getRequestFromId(transactionId);
56
86
  if (requestData) {
57
87
  requestData.body = data;
88
+ requestData.dataTruncated = isTruncated;
58
89
  setRequest(transactionId, requestData);
59
90
  }
60
91
  }
@@ -65,6 +96,7 @@ function updateRequestBody(shim, data) {
65
96
  const requestData = getRequestFromId(traceId);
66
97
  if (requestData) {
67
98
  requestData.body = data;
99
+ requestData.dataTruncated = isTruncated;
68
100
  setRequest(traceId, requestData)
69
101
  }
70
102
  }
@@ -93,4 +125,4 @@ module.exports = {
93
125
  updateRequestBody,
94
126
  gcRequestMap,
95
127
  requestMap
96
- }
128
+ }
@@ -172,15 +172,15 @@ function createPathIfNotExist(dir) {
172
172
  function addRequestData(shim, request) {
173
173
  try {
174
174
  const data = Object.assign({});
175
- const segment = shim.getActiveSegment();
176
- if (segment && segment.transaction) {
175
+ const transaction = shim.tracer.getTransaction();
176
+ if (transaction) {
177
177
  data.protocol = (request.connection && request.connection.encrypted) ? 'https' : 'http';
178
178
  data.body = null;
179
179
  data.headers = request.headers;
180
180
  data.url = request.url;
181
181
  data.method = request.method;
182
182
  data.httpVersion = request.httpVersion;
183
- data.serverPort = segment.transaction.port;
183
+ data.serverPort = transaction.port;
184
184
  data.contextPath = '/';
185
185
  const queryObject = URL.parse(request.url, true).query;
186
186
  data.parameterMap = {};
@@ -194,7 +194,8 @@ function addRequestData(shim, request) {
194
194
  });
195
195
  }
196
196
  data.clientIP = requestIp.getClientIp(request);
197
- const transactionId = segment.transaction.id;
197
+ data.dataTruncated = false;
198
+ const transactionId = transaction.id;
198
199
  const storedRequest = requestManager.getRequestFromId(transactionId);
199
200
  if (storedRequest && storedRequest.uri) {
200
201
  data.uri = storedRequest.uri;
@@ -262,4 +263,4 @@ module.exports = {
262
263
  addRequestData,
263
264
  decryptData,
264
265
  hashVerifier
265
- }
266
+ }
@@ -71,15 +71,15 @@ module.exports = function initialize(shim, director) {
71
71
  * @param {*} params
72
72
  */
73
73
  function extractParams(shim, params) {
74
- const segment = shim.getActiveSegment();
75
- if (segment && segment.transaction) {
76
- let request = requestManager.getRequestFromId(segment.transaction.id);
74
+ const transaction = shim.tracer.getTransaction();
75
+ if (transaction) {
76
+ let request = requestManager.getRequestFromId(transaction.id);
77
77
  if (params && request) {
78
78
  Object.keys(params).forEach(function (key) {
79
79
  if (params[key]) {
80
80
  if (!request.parameterMap[key]) {
81
81
  request.parameterMap[key] = new Array(params[key].toString());
82
- requestManager.setRequest(segment.transaction.id, request);
82
+ requestManager.setRequest(transaction.id, request);
83
83
  }
84
84
  }
85
85
  });
@@ -91,8 +91,8 @@ function extractParams(shim, params) {
91
91
  if (uri.includes(param)) {
92
92
  uri = lodash.replace(uri, param, ':param_input');
93
93
  request.uri = uri;
94
- requestManager.setRequest(segment.transaction.id, request);
94
+ requestManager.setRequest(transaction.id, request);
95
95
  }
96
96
  }
97
97
  }
98
- }
98
+ }
@@ -31,8 +31,11 @@ module.exports = function initialize(shim, express) {
31
31
  if (express.Router.use) {
32
32
  wrapExpress4(shim, express)
33
33
  }
34
- expressFileHook(shim, express && express.response, 'download')
35
- expressFileHook(shim, express && express.response, 'sendFile')
34
+ if(API && API.getNRAgent() && !API.getNRAgent().config.security.exclude_from_iast_scan.iast_detection_category.invalid_file_access){
35
+ expressFileHook(shim, express && express.response, 'download')
36
+ expressFileHook(shim, express && express.response, 'sendFile')
37
+ }
38
+
36
39
  }
37
40
 
38
41
  /**
@@ -82,15 +85,15 @@ function extractParams(shim, req) {
82
85
  if (!requestManager.getRequest(shim)) {
83
86
  secUtils.addRequestData(shim, req);
84
87
  }
85
- const segment = shim.getActiveSegment();
86
- if (segment && segment.transaction) {
87
- let request = requestManager.getRequestFromId(segment.transaction.id);
88
+ const transaction = shim.tracer.getTransaction();
89
+ if (transaction) {
90
+ let request = requestManager.getRequestFromId(transaction.id);
88
91
  if (req.params && request) {
89
92
  Object.keys(req.params).forEach(function (key) {
90
93
  if (req.params[key]) {
91
94
  if (!request.parameterMap[key]) {
92
95
  request.parameterMap[key] = new Array(req.params[key].toString());
93
- requestManager.setRequest(segment.transaction.id, request);
96
+ requestManager.setRequest(transaction.id, request);
94
97
  }
95
98
  }
96
99
  });
@@ -100,14 +103,14 @@ function extractParams(shim, req) {
100
103
  if (req.query[key]) {
101
104
  if (!request.parameterMap[key]) {
102
105
  request.parameterMap[key] = new Array(req.query[key].toString());
103
- requestManager.setRequest(segment.transaction.id, request);
106
+ requestManager.setRequest(transaction.id, request);
104
107
  }
105
108
  }
106
109
  });
107
110
  }
108
111
  if (req.route && req.route.path && request) {
109
112
  request.uri = req.route.path;
110
- requestManager.setRequest(segment.transaction.id, request);
113
+ requestManager.setRequest(transaction.id, request);
111
114
  }
112
115
  }
113
116
  }
@@ -121,15 +121,15 @@ function extractParams(shim, req) {
121
121
  try {
122
122
  const reqURL = req.url || req.raw.url;
123
123
  const parsedURI = url.parse(reqURL).pathname;
124
- const segment = shim.getActiveSegment();
125
- if (segment && segment.transaction) {
126
- let request = requestManager.getRequestFromId(segment.transaction.id);
124
+ const transaction = shim.tracer.getTransaction();
125
+ if (transaction) {
126
+ let request = requestManager.getRequestFromId(transaction.id);
127
127
  if (req.params && segment && request) {
128
128
  Object.keys(req.params).forEach(function (key) {
129
129
  if (req.params[key]) {
130
130
  if (!request.parameterMap[key]) {
131
131
  request.parameterMap[key] = new Array(req.params[key].toString());
132
- requestManager.setRequest(segment.transaction.id, request);
132
+ requestManager.setRequest(transaction.id, request);
133
133
  }
134
134
  }
135
135
  });
@@ -139,7 +139,7 @@ function extractParams(shim, req) {
139
139
  if (req.query[key]) {
140
140
  if (!request.parameterMap[key]) {
141
141
  request.parameterMap[key] = new Array(req.query[key].toString());
142
- requestManager.setRequest(segment.transaction.id, request);
142
+ requestManager.setRequest(transaction.id, request);
143
143
  }
144
144
  }
145
145
  });
@@ -147,7 +147,7 @@ function extractParams(shim, req) {
147
147
  let method = request.method.toUpperCase();
148
148
  if (parsedURI && request && requestManager.requestMap[method + ATTHERATE + parsedURI]) {
149
149
  request.uri = parsedURI;
150
- requestManager.setRequest(segment.transaction.id, request);
150
+ requestManager.setRequest(transaction.id, request);
151
151
  }
152
152
  }
153
153
  } catch (error) {
@@ -25,6 +25,7 @@ const RENAME = 'rename';
25
25
  const FSReqCallback = 'FSReqCallback';
26
26
  const FSReqWrap = 'FSReqWrap';
27
27
  const OBJECT = 'object';
28
+ const semver = require('semver');
28
29
 
29
30
  const functionsProbableToFA = [
30
31
  "fstat",
@@ -37,7 +38,7 @@ const functionsProbableToFA = [
37
38
  "realpath",
38
39
  ];
39
40
 
40
- const functionProbableToFI = [
41
+ let functionProbableToFI = [
41
42
  "rename",
42
43
  "ftruncate",
43
44
  "rmdir",
@@ -93,8 +94,10 @@ const promiseFunctionProbableToFI = [
93
94
  * @param {*} moduleName
94
95
  */
95
96
  function initialize(shim, mod, moduleName) {
96
-
97
-
97
+ if(API && API.getNRAgent() && API.getNRAgent().config.security.exclude_from_iast_scan.iast_detection_category.invalid_file_access){
98
+ logger.warn('invalid_file_access detection is disabled');
99
+ return;
100
+ }
98
101
  logger.info(`Instrumenting ${moduleName}`);
99
102
  requireHook.initialize(shim)
100
103
  const binding = process.binding("fs");
@@ -141,9 +144,8 @@ function openHook(shim, mod, moduleName) {
141
144
  parameters[0] = API.getSecAgent().applicationInfo.serverInfo.deployedApplications[0].deployedPath + SLASH + parameters[0];
142
145
  } else if (parameters[0].startsWith(SLASHDOTDOT)) {
143
146
  parameters[0] = API.getSecAgent().applicationInfo.serverInfo.deployedApplications[0].deployedPath + parameters[0];
144
- } else {
145
- parameters[0] = path.resolve(parameters[0]);
146
- }
147
+ }
148
+
147
149
  } catch (error) {
148
150
 
149
151
  }
@@ -187,11 +189,6 @@ function probableToFAHooks(shim, mod, moduleName) {
187
189
  const request = requestManager.getRequest(shim);
188
190
  if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
189
191
  const traceObject = secUtils.getTraceObject(shim);
190
- try {
191
- parameters[0] = path.resolve(parameters[0]);
192
- } catch (error) {
193
-
194
- }
195
192
  let absoluteParameters = [parameters[0]];
196
193
  const secMetadata = securityMetaData.getSecurityMetaData(request, absoluteParameters, traceObject, secUtils.getExecutionId(), EVENT_TYPE.FILE_OPERATION, EVENT_CATEGORY.FILE)
197
194
  this.secEvent = API.generateSecEvent(secMetadata);
@@ -214,6 +211,9 @@ function probableToFAHooks(shim, mod, moduleName) {
214
211
  * @param {*} moduleName
215
212
  */
216
213
  function probableToFIHooks(shim, mod, moduleName) {
214
+ if (semver.satisfies(process.version, '>19.0.0')) {
215
+ functionProbableToFI.push('writeFileSync');
216
+ }
217
217
  functionProbableToFI.forEach(function (fun) {
218
218
  shim.wrap(mod, fun, function makeFIWrapper(shim, fn) {
219
219
  logger.debug(`Instrumenting ${moduleName}.${fun}`);
@@ -224,12 +224,6 @@ function probableToFIHooks(shim, mod, moduleName) {
224
224
  const request = requestManager.getRequest(shim);
225
225
  if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
226
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
227
  let absoluteParameters = [parameters[0]];
234
228
  if (fun === COPY_FILE || fun === RENAME) {
235
229
  const secMetadata = securityMetaData.getSecurityMetaData(request, parameters[1], traceObject, secUtils.getExecutionId(), getCase(arguments[1]), EVENT_CATEGORY.FILE)
@@ -267,11 +261,6 @@ function probablePromiseToFAHooks(shim, mod, moduleName) {
267
261
  const request = requestManager.getRequest(shim);
268
262
  if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
269
263
  const traceObject = secUtils.getTraceObject(shim);
270
- try {
271
- parameters[0] = path.resolve(parameters[0]);
272
- } catch (error) {
273
-
274
- }
275
264
  let absoluteParameters = [parameters[0]];
276
265
  const secMetadata = securityMetaData.getSecurityMetaData(request, absoluteParameters, traceObject, secUtils.getExecutionId(), EVENT_TYPE.FILE_OPERATION, EVENT_CATEGORY.FILE)
277
266
  this.secEvent = API.generateSecEvent(secMetadata);
@@ -300,12 +289,6 @@ function probablePromiseToFIHooks(shim, mod, moduleName) {
300
289
  const request = requestManager.getRequest(shim);
301
290
  if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
302
291
  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
292
  let absoluteParameters = [parameters[0]];
310
293
  if (fun === COPY_FILE || fun === RENAME) {
311
294
  const secMetadata = securityMetaData.getSecurityMetaData(request, parameters[1], traceObject, secUtils.getExecutionId(), getCase(arguments[1]), EVENT_CATEGORY.FILE)
@@ -282,8 +282,8 @@ function wrapCallback(shim, mod, method) {
282
282
  function addRequestData(shim, type, path, args) {
283
283
  const data = Object.assign({});
284
284
  try {
285
- const segment = shim.getActiveSegment();
286
- if (segment && segment.transaction) {
285
+ const transaction = shim.tracer.getTransaction();
286
+ if (transaction) {
287
287
  data.method = path;
288
288
  data.url = path;
289
289
  data.uri = path;
@@ -298,7 +298,7 @@ function addRequestData(shim, type, path, args) {
298
298
  data.isGrpc = true;
299
299
  data.body = JSON.stringify(args.request);
300
300
  data.serverPort = shim.serverPort;
301
- const transactionId = segment.transaction.id;
301
+ const transactionId = transaction.id;
302
302
  requestManager.setRequest(transactionId, data);
303
303
  }
304
304
  } catch (error) {
@@ -339,4 +339,4 @@ function iterateNestedObjectForServiceLookup(result, serviceObject) {
339
339
  } catch (error) {
340
340
  logger.error("Error while getting service definition", error);
341
341
  }
342
- }
342
+ }
@@ -101,15 +101,15 @@ function handlerWrapper(shim, mod) {
101
101
  * @param {*} req
102
102
  */
103
103
  function extractParams(shim, req) {
104
- const segment = shim.getActiveSegment();
105
- if (segment && segment.transaction) {
106
- let request = requestManager.getRequestFromId(segment.transaction.id);
104
+ const transaction = shim.tracer.getTransaction();
105
+ if (transaction) {
106
+ let request = requestManager.getRequestFromId(transaction.id);
107
107
  if (req.params && request) {
108
108
  Object.keys(req.params).forEach(function (key) {
109
109
  if (req.params[key]) {
110
110
  if (!request.parameterMap[key]) {
111
111
  request.parameterMap[key] = new Array(req.params[key].toString());
112
- requestManager.setRequest(segment.transaction.id, request);
112
+ requestManager.setRequest(transaction.id, request);
113
113
  }
114
114
  }
115
115
  });
@@ -119,14 +119,14 @@ function extractParams(shim, req) {
119
119
  if (req.query[key]) {
120
120
  if (!request.parameterMap[key]) {
121
121
  request.parameterMap[key] = new Array(req.query[key].toString());
122
- requestManager.setRequest(segment.transaction.id, request);
122
+ requestManager.setRequest(transaction.id, request);
123
123
  }
124
124
  }
125
125
  });
126
126
  }
127
127
  if (req.route && req.route.path && request) {
128
128
  request.uri = req.route.path;
129
- requestManager.setRequest(segment.transaction.id, request);
129
+ requestManager.setRequest(transaction.id, request);
130
130
  }
131
131
  }
132
- }
132
+ }