@newrelic/security-agent 2.3.2 → 2.4.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,10 @@
|
|
|
1
|
+
### v2.4.0 (2025-03-21)
|
|
2
|
+
#### Features
|
|
3
|
+
* Support for gRPC error reporting
|
|
4
|
+
* Support to detect API endpoints in next.js framework
|
|
5
|
+
#### Miscellaneous chores
|
|
6
|
+
* Updated axios to v1.8.4
|
|
7
|
+
|
|
1
8
|
### v2.3.2 (2025-03-11)
|
|
2
9
|
#### Bug fixes
|
|
3
10
|
* Updated axios to v1.8.2
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -78,7 +78,7 @@ code, the source code can be found at [https://github.com/newrelic/csec-node-age
|
|
|
78
78
|
|
|
79
79
|
### axios
|
|
80
80
|
|
|
81
|
-
This product includes source derived from [axios](https://github.com/axios/axios) ([v1.8.
|
|
81
|
+
This product includes source derived from [axios](https://github.com/axios/axios) ([v1.8.4](https://github.com/axios/axios/tree/v1.8.4)), distributed under the [MIT License](https://github.com/axios/axios/blob/v1.8.4/LICENSE):
|
|
82
82
|
|
|
83
83
|
```
|
|
84
84
|
# Copyright (c) 2014-present Matt Zabriskie & Collaborators
|
|
@@ -16,6 +16,7 @@ const grpcutils = require('../../core/grpc-utils');
|
|
|
16
16
|
const routeManager = require('../../core/route-manager');
|
|
17
17
|
let serverAddress;
|
|
18
18
|
const ExceptionReporting = require('../../../nr-security-agent/lib/core/ExceptionReporting');
|
|
19
|
+
const responseErrorSet = new Set([2, 12, 13, 14, 15])
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
|
|
@@ -58,6 +59,33 @@ module.exports.wrapStartCall = function wrappedClient(shim, callStream) {
|
|
|
58
59
|
shim.wrap(callStream.Http2CallStream.prototype, 'start', wrapStart)
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Wrapper for error collection
|
|
64
|
+
* @param {*} shim
|
|
65
|
+
* @param {*} call
|
|
66
|
+
*/
|
|
67
|
+
module.exports.wrapCall = function wrappedCall(shim, call) {
|
|
68
|
+
shim.wrap(call, 'callErrorFromStatus', function wrapCallErrorFromStatus(shim, fn) {
|
|
69
|
+
if (!shim.isFunction(fn)) {
|
|
70
|
+
return fn
|
|
71
|
+
}
|
|
72
|
+
return function wrappedCallErrorFromStatus() {
|
|
73
|
+
const errRes = fn.apply(this, arguments);
|
|
74
|
+
try {
|
|
75
|
+
let error = new Error(errRes.message);
|
|
76
|
+
error.stack = errRes.stack;
|
|
77
|
+
const request = requestManager.getRequest(shim);
|
|
78
|
+
if (request) {
|
|
79
|
+
ExceptionReporting.generate5xxReportingEvent(error, request);
|
|
80
|
+
}
|
|
81
|
+
} catch (error) {
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return errRes;
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
|
|
61
89
|
module.exports.wrapServer = function wrappedServer(shim, server) {
|
|
62
90
|
const grpcVersion = shim.require('./package.json').version
|
|
63
91
|
logger.info("Instrumenting @grpc/grpc-js", grpcVersion)
|
|
@@ -109,6 +137,7 @@ function wrapStart(shim, original) {
|
|
|
109
137
|
"path": method,
|
|
110
138
|
"protocol": protocol,
|
|
111
139
|
}
|
|
140
|
+
|
|
112
141
|
if (request) {
|
|
113
142
|
const traceObject = secUtils.getTraceObject(shim);
|
|
114
143
|
const secMetadata = securityMetaData.getSecurityMetaData(request, urlObj, traceObject, secUtils.getExecutionId(), EVENT_TYPE.HTTP_REQUEST, EVENT_CATEGORY.HTTP)
|
|
@@ -256,11 +285,11 @@ function wrapCallback(shim, mod, method) {
|
|
|
256
285
|
if (arguments[0].details && request) {
|
|
257
286
|
ExceptionReporting.generateExceptionReportingEvent(arguments[0].details, request);
|
|
258
287
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
288
|
+
|
|
289
|
+
if (arguments[0].code && responseErrorSet.has(arguments[0].code) && request) {
|
|
290
|
+
let responseCode = arguments[0].code
|
|
291
|
+
ExceptionReporting.generate5xxReportingEvent(null, request, responseCode);
|
|
292
|
+
}
|
|
264
293
|
}
|
|
265
294
|
} catch (error) {
|
|
266
295
|
|
|
@@ -282,7 +311,7 @@ function wrapCallback(shim, mod, method) {
|
|
|
282
311
|
function addRequestData(shim, type, path, args) {
|
|
283
312
|
const data = Object.assign({});
|
|
284
313
|
try {
|
|
285
|
-
const transaction = shim.tracer.getTransaction();
|
|
314
|
+
const transaction = shim.tracer.getTransaction();
|
|
286
315
|
if (transaction) {
|
|
287
316
|
data.method = path;
|
|
288
317
|
data.url = path;
|
|
@@ -6,9 +6,14 @@
|
|
|
6
6
|
'use strict'
|
|
7
7
|
const requestManager = require("../../core/request-manager");
|
|
8
8
|
const API = require("../../../nr-security-api");
|
|
9
|
+
const routeManager = require('../../core/route-manager');
|
|
9
10
|
const logger = API.getLogger();
|
|
11
|
+
const lodash = require('lodash');
|
|
12
|
+
const { ATTHERATE, DOUBLE_DOLLAR, EMPTY_STR } = require('../../core/constants');
|
|
10
13
|
|
|
11
14
|
const semver = require('semver')
|
|
15
|
+
const fs = require('fs');
|
|
16
|
+
const path = require('path');
|
|
12
17
|
|
|
13
18
|
module.exports = function initialize(shim, nextjs) {
|
|
14
19
|
const nextVersion = shim.require('./package.json').version
|
|
@@ -16,6 +21,23 @@ module.exports = function initialize(shim, nextjs) {
|
|
|
16
21
|
|
|
17
22
|
const nextServer = nextjs.default;
|
|
18
23
|
hookRunAPI(shim, nextServer.prototype, nextVersion);
|
|
24
|
+
|
|
25
|
+
//TODO need to update for API endpoints
|
|
26
|
+
try {
|
|
27
|
+
const appRoot = process.env.PWD;
|
|
28
|
+
const searchPath = appRoot + '/.next/server/pages/api';
|
|
29
|
+
const allAPIEndpoints = getAllAPIEndpoints(searchPath);
|
|
30
|
+
logger.debug("allAPIEndpoints:", allAPIEndpoints);
|
|
31
|
+
for (let index = 0; index < allAPIEndpoints.length; index++) {
|
|
32
|
+
const element = allAPIEndpoints[index];
|
|
33
|
+
let key = "*" + ATTHERATE + element;
|
|
34
|
+
routeManager.setRoute(key, EMPTY_STR);
|
|
35
|
+
}
|
|
36
|
+
} catch (error) {
|
|
37
|
+
logger.debug("Error while getting all API end points for next.js", error);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
19
41
|
}
|
|
20
42
|
|
|
21
43
|
/**
|
|
@@ -91,3 +113,33 @@ function extractParams(shim, page, params) {
|
|
|
91
113
|
}
|
|
92
114
|
}
|
|
93
115
|
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Utility to scan pages directory to get all avaible routes
|
|
119
|
+
* @param {*} dir
|
|
120
|
+
* @returns
|
|
121
|
+
*/
|
|
122
|
+
const getAllAPIEndpoints = (dir) => {
|
|
123
|
+
logger.debug("dir is:", dir)
|
|
124
|
+
const apiEndpoints = [];
|
|
125
|
+
|
|
126
|
+
const scanDirectory = (currentDir) => {
|
|
127
|
+
logger.debug("currentDir is:", currentDir)
|
|
128
|
+
const files = fs.readdirSync(currentDir);
|
|
129
|
+
|
|
130
|
+
files.forEach((file) => {
|
|
131
|
+
const filePath = path.join(currentDir, file);
|
|
132
|
+
const isDirectory = fs.statSync(filePath).isDirectory();
|
|
133
|
+
|
|
134
|
+
if (isDirectory) {
|
|
135
|
+
scanDirectory(filePath);
|
|
136
|
+
} else {
|
|
137
|
+
const apiEndpoint = filePath.replace(`${dir}/`, '/api/').replace(/\.js*.*/, '');
|
|
138
|
+
apiEndpoints.push(apiEndpoint);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
scanDirectory(dir);
|
|
144
|
+
return apiEndpoints;
|
|
145
|
+
};
|
|
@@ -235,6 +235,15 @@ newrelic.instrument({
|
|
|
235
235
|
}
|
|
236
236
|
})
|
|
237
237
|
|
|
238
|
+
newrelic.instrument({
|
|
239
|
+
moduleName: '@grpc/grpc-js/build/src/call',
|
|
240
|
+
isEsm: true,
|
|
241
|
+
onRequire: require('./hooks/grpc-js/nr-grpc').wrapCall,
|
|
242
|
+
onError: function intrumentErrorHandler(err) {
|
|
243
|
+
logger.error(err.message, err.stack)
|
|
244
|
+
}
|
|
245
|
+
})
|
|
246
|
+
|
|
238
247
|
newrelic.instrument({
|
|
239
248
|
moduleName: 'graphql/execution/execute',
|
|
240
249
|
isEsm: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@newrelic/security-agent",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "New Relic Security Agent for Node.js",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"jsonVersion": "1.2.9",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"url": "https://github.com/newrelic/csec-node-agent.git"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"axios": "^1.8.
|
|
42
|
+
"axios": "^1.8.4",
|
|
43
43
|
"check-disk-space": "^3.4.0",
|
|
44
44
|
"content-type": "^1.0.5",
|
|
45
45
|
"cron": "^3.1.7",
|