@newrelic/security-agent 0.7.0 → 1.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.
- package/CHANGELOG.md +23 -0
- package/LICENSE +20 -25
- package/README.md +16 -2
- package/lib/instrumentation-security/core/constants.js +1 -1
- package/lib/instrumentation-security/core/event-constants.js +1 -1
- package/lib/instrumentation-security/core/grpc-utils.js +53 -0
- package/lib/instrumentation-security/core/request-manager.js +1 -1
- package/lib/instrumentation-security/core/route-manager.js +29 -6
- package/lib/instrumentation-security/core/sec-trace.js +1 -1
- package/lib/instrumentation-security/core/sec-utils.js +4 -4
- package/lib/instrumentation-security/core/security-metadata.js +1 -1
- package/lib/instrumentation-security/core/stack-trace.js +1 -1
- package/lib/instrumentation-security/hooks/@nestjs/nr-nestjs-core.js +1 -1
- package/lib/instrumentation-security/hooks/director/nr-director.js +1 -1
- package/lib/instrumentation-security/hooks/express/nr-express.js +3 -5
- package/lib/instrumentation-security/hooks/fastify/nr-fastify.js +1 -1
- package/lib/instrumentation-security/hooks/fs/nr-fs.js +1 -1
- package/lib/instrumentation-security/hooks/grpc-js/nr-grpc.js +284 -0
- package/lib/instrumentation-security/hooks/hapi/nr-hapi.js +1 -1
- package/lib/instrumentation-security/hooks/http/nr-http.js +1 -1
- package/lib/instrumentation-security/hooks/koa/@koa/nr-@koa-router.js +1 -1
- package/lib/instrumentation-security/hooks/ldap/nr-ldap.js +1 -1
- package/lib/instrumentation-security/hooks/mongodb/common.js +1 -1
- package/lib/instrumentation-security/hooks/mongodb/constants.js +1 -1
- package/lib/instrumentation-security/hooks/mongodb/nr-mongodb.js +1 -1
- package/lib/instrumentation-security/hooks/mongodb/v2-mongo.js +1 -1
- package/lib/instrumentation-security/hooks/mongodb/v3-mongo.js +1 -1
- package/lib/instrumentation-security/hooks/mongodb/v4-mongo.js +1 -1
- package/lib/instrumentation-security/hooks/mysql/nr-mysql.js +1 -1
- package/lib/instrumentation-security/hooks/native/nr-childProcess.js +1 -1
- package/lib/instrumentation-security/hooks/postgres/nr-postgres.js +1 -1
- package/lib/instrumentation-security/hooks/require/nr-require.js +1 -1
- package/lib/instrumentation-security/hooks/restify/nr-restify.js +1 -1
- package/lib/instrumentation-security/hooks/undici/nr-undici.js +139 -0
- package/lib/instrumentation-security/hooks/xpath/nr-xpath.js +1 -1
- package/lib/instrumentation-security/index.js +57 -1
- package/lib/nr-security-agent/index.js +1 -1
- package/lib/nr-security-agent/lib/core/Auth-headers.js +1 -1
- package/lib/nr-security-agent/lib/core/ContainerProperties.js +1 -1
- package/lib/nr-security-agent/lib/core/ECSProperties.js +1 -1
- package/lib/nr-security-agent/lib/core/FuzzFailEvent.js +1 -1
- package/lib/nr-security-agent/lib/core/LinkingMetadata.js +1 -1
- package/lib/nr-security-agent/lib/core/LogMessage.js +1 -1
- package/lib/nr-security-agent/lib/core/PodProperties.js +1 -1
- package/lib/nr-security-agent/lib/core/Policy.js +1 -1
- package/lib/nr-security-agent/lib/core/agent-status.js +1 -1
- package/lib/nr-security-agent/lib/core/agent.js +1 -1
- package/lib/nr-security-agent/lib/core/apiEndpoints.js +29 -0
- package/lib/nr-security-agent/lib/core/applicationinfo.js +1 -1
- package/lib/nr-security-agent/lib/core/commonUtils.js +5 -5
- package/lib/nr-security-agent/lib/core/connections/aws-lambda-client.js +1 -1
- package/lib/nr-security-agent/lib/core/connections/grpcClient.js +111 -0
- package/lib/nr-security-agent/lib/core/connections/restclient.js +1 -1
- package/lib/nr-security-agent/lib/core/connections/websocket/index.js +1 -1
- package/lib/nr-security-agent/lib/core/connections/websocket/response/IASTUtils.js +1 -1
- package/lib/nr-security-agent/lib/core/connections/websocket/response/collecotor-policy-error-handler.js +1 -1
- package/lib/nr-security-agent/lib/core/connections/websocket/response/collector-policy-handler.js +1 -1
- package/lib/nr-security-agent/lib/core/connections/websocket/response/fuzz-request-handler.js +32 -12
- package/lib/nr-security-agent/lib/core/connections/websocket/response/iast-cool-down.js +1 -1
- package/lib/nr-security-agent/lib/core/connections/websocket/response/iast-record-deletion.js +1 -1
- package/lib/nr-security-agent/lib/core/connections/websocket/response/index.js +1 -1
- package/lib/nr-security-agent/lib/core/connections/websocket/response/no-op-handler.js +1 -1
- package/lib/nr-security-agent/lib/core/connections/websocket/response/startup-handshake-handler.js +4 -1
- package/lib/nr-security-agent/lib/core/connections/websocket/response/unsupported-agent-handler.js +1 -1
- package/lib/nr-security-agent/lib/core/connections/websocket/response/ws-reconnect.js +1 -1
- package/lib/nr-security-agent/lib/core/connections/websocket/websocket.js +1 -1
- package/lib/nr-security-agent/lib/core/event-stats.js +1 -1
- package/lib/nr-security-agent/lib/core/event.js +7 -2
- package/lib/nr-security-agent/lib/core/health-check.js +1 -1
- package/lib/nr-security-agent/lib/core/json-file-handler.js +1 -1
- package/lib/nr-security-agent/lib/core/jsonValidator.js +1 -1
- package/lib/nr-security-agent/lib/core/lambda-delegated-task-service.js +1 -1
- package/lib/nr-security-agent/lib/core/logging.js +6 -6
- package/lib/nr-security-agent/lib/core/sec-agent-constants.js +1 -1
- package/lib/nr-security-agent/lib/core/sec-util.js +1 -1
- package/lib/nr-security-agent/lib/core/sha-size-util.js +1 -1
- package/lib/nr-security-agent/lib/core/sha_worker.js +1 -1
- package/lib/nr-security-agent/lib/core/startup-config.js +1 -1
- package/lib/nr-security-agent/lib/core/statusUtils.js +3 -3
- package/lib/nr-security-agent/lib/core/timeunit.js +1 -1
- package/lib/nr-security-agent/lib/core/websocket-client.js +11 -2
- package/lib/nr-security-agent/lib/core/xss-utils.js +1 -1
- package/lib/nr-security-agent/lib/models/lambda-delegated-task/constants.js +1 -1
- package/lib/nr-security-agent/lib/models/lambda-delegated-task/index.js +1 -1
- package/lib/nr-security-agent/lib/models/lambda-delegated-task/lambda-delegated-sha-calculation.js +1 -1
- package/lib/nr-security-agent/lib/models/lambda-delegated-task/lambda-delegated-task-base.js +1 -1
- package/lib/nr-security-agent/lib/models/lambda-delegated-task/lambda-delegated-task-type.js +1 -1
- package/lib/nr-security-agent/resources/config.js +1 -1
- package/lib/nr-security-api/index.js +1 -1
- package/package.json +7 -3
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: New Relic Pre-Release
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const requestManager = require("../../core/request-manager");
|
|
8
|
+
const secUtils = require("../../core/sec-utils");
|
|
9
|
+
const API = require("../../../nr-security-api");
|
|
10
|
+
const securityMetaData = require('../../core/security-metadata');
|
|
11
|
+
const { EVENT_TYPE, EVENT_CATEGORY } = require('../../core/event-constants');
|
|
12
|
+
const { NR_CSEC_FUZZ_REQUEST_ID } = require('../../core/constants');
|
|
13
|
+
const logger = API.getLogger();
|
|
14
|
+
const semver = require('semver');
|
|
15
|
+
const grpcutils = require('../../core/grpc-utils');
|
|
16
|
+
let serverAddress;
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
module.exports.initialize = function initialize(shim, grpc, moduleName) {
|
|
20
|
+
logger.info('Instrumenting grpc', moduleName);
|
|
21
|
+
const grpcVersion = shim.require('./package.json').version;
|
|
22
|
+
logger.debug("grpc version:", grpcVersion);
|
|
23
|
+
|
|
24
|
+
if (semver.lt(grpcVersion, '1.4.0')) {
|
|
25
|
+
logger.warn('gRPC server-side instrumentation only supported on grpc-js >=1.4.0')
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (semver.gte(grpcVersion, '1.8.0')) {
|
|
30
|
+
const resolvingCall = shim.require('./build/src/resolving-call')
|
|
31
|
+
shim.wrap(resolvingCall.ResolvingCall.prototype, 'start', wrapStart)
|
|
32
|
+
} else {
|
|
33
|
+
const callStream = shim.require('./build/src/call-stream')
|
|
34
|
+
shim.wrap(callStream.Http2CallStream.prototype, 'start', wrapStart)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
const server = shim.require('./build/src/server')
|
|
39
|
+
shim.wrap(server.Server.prototype, 'bindAsync', bindAsyncWrapper)
|
|
40
|
+
shim.wrap(server.Server.prototype, 'register', wrapRegister)
|
|
41
|
+
|
|
42
|
+
//get all service
|
|
43
|
+
shim.wrap(server.Server.prototype, 'addService', wrapAddService);
|
|
44
|
+
|
|
45
|
+
//laod package def
|
|
46
|
+
const makeClient = shim.require('./build/src/make-client');
|
|
47
|
+
shim.wrap(makeClient, 'loadPackageDefinition', wrapLoadPackageDefinition);
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
module.exports.wrapStartResolve = function wrappedStartResolve(shim, resolvingCall) {
|
|
53
|
+
shim.wrap(resolvingCall.ResolvingCall.prototype, 'start', wrapStart)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports.wrapStartCall = function wrappedClient(shim, callStream) {
|
|
57
|
+
shim.wrap(callStream.Http2CallStream.prototype, 'start', wrapStart)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports.wrapServer = function wrappedServer(shim, server) {
|
|
61
|
+
const grpcVersion = shim.require('./package.json').version
|
|
62
|
+
logger.info("Instrumenting @grpc/grpc-js", grpcVersion)
|
|
63
|
+
if (semver.lt(grpcVersion, '1.4.0')) {
|
|
64
|
+
logger.warn('gRPC server-side instrumentation only supported on grpc-js >=1.4.0')
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
shim.wrap(server.Server.prototype, 'register', wrapRegister)
|
|
69
|
+
shim.wrap(server.Server.prototype, 'bindAsync', bindAsyncWrapper)
|
|
70
|
+
//get all service
|
|
71
|
+
shim.wrap(server.Server.prototype, 'addService', wrapAddService);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
module.exports.wrapMakeClient = function wrapMakeClient(shim, makeClient) {
|
|
75
|
+
shim.wrap(makeClient, 'loadPackageDefinition', wrapLoadPackageDefinition);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Instruments grpc-js client by intercepting the function that
|
|
81
|
+
* initiates client requests. This handles all four types of client
|
|
82
|
+
* invocations: unary, client-streaming, server-streaming, and
|
|
83
|
+
* bidirectional streaming.
|
|
84
|
+
*
|
|
85
|
+
* @param {object} shim the generic shim to instrument with
|
|
86
|
+
* @param {Function} original the original function
|
|
87
|
+
* @returns {Function} the instrumented function
|
|
88
|
+
*/
|
|
89
|
+
function wrapStart(shim, original) {
|
|
90
|
+
return function wrappedStart() {
|
|
91
|
+
const channel = this.channel;
|
|
92
|
+
const authorityName = (channel.target && channel.target.path) || channel.getDefaultAuthority;
|
|
93
|
+
// in 1.8.0 this changed from methodName to method
|
|
94
|
+
const method = this.methodName || this.method;
|
|
95
|
+
const protocol = 'grpc:';
|
|
96
|
+
const url = `${protocol}//${authorityName}${method}`;
|
|
97
|
+
logger.debug("grpc url is:", url)
|
|
98
|
+
const request = requestManager.getRequest(shim);
|
|
99
|
+
let urlObj = {
|
|
100
|
+
"headers":
|
|
101
|
+
{
|
|
102
|
+
"host": authorityName
|
|
103
|
+
},
|
|
104
|
+
"method": method,
|
|
105
|
+
"path": method,
|
|
106
|
+
"protocol": protocol,
|
|
107
|
+
}
|
|
108
|
+
if (request) {
|
|
109
|
+
const traceObject = secUtils.getTraceObject(shim);
|
|
110
|
+
const secMetadata = securityMetaData.getSecurityMetaData(request, urlObj, traceObject, secUtils.getExecutionId(), EVENT_TYPE.HTTP_REQUEST, EVENT_CATEGORY.HTTP)
|
|
111
|
+
const secEvent = API.generateSecEvent(secMetadata);
|
|
112
|
+
API.sendEvent(secEvent);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const res = original.apply(this, arguments);
|
|
116
|
+
return res;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
function wrapAddService(shim, original) {
|
|
123
|
+
return function wrappedbindAsync() {
|
|
124
|
+
const result = original.apply(this, arguments);
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function wrapLoadPackageDefinition(shim, original) {
|
|
130
|
+
return function wrappedbindAsync() {
|
|
131
|
+
let serviceObject = arguments[0];
|
|
132
|
+
const result = original.apply(this, arguments);
|
|
133
|
+
iterateNestedObjectForServiceLookup(result, serviceObject);
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
function bindAsyncWrapper(shim, original) {
|
|
142
|
+
return function wrappedbindAsync() {
|
|
143
|
+
serverAddress = arguments[0];
|
|
144
|
+
shim.grpcServerAddress = serverAddress;
|
|
145
|
+
try {
|
|
146
|
+
const splittedData = serverAddress.split(":");
|
|
147
|
+
serverPort = splittedData[1];
|
|
148
|
+
shim.serverPort = parseInt(serverPort);
|
|
149
|
+
} catch (error) {
|
|
150
|
+
|
|
151
|
+
}
|
|
152
|
+
const result = original.apply(this, arguments);
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Instruments the grpc-js server by intercepting the moment when
|
|
161
|
+
* server methods are registered from the method implementations
|
|
162
|
+
* provided to grpc-js. This handles all four types of server
|
|
163
|
+
* invocations: unary, client-streaming, server-streaming, and
|
|
164
|
+
* bidirectional streaming.
|
|
165
|
+
*
|
|
166
|
+
* @param {object} shim the web shim to instrument with
|
|
167
|
+
* @param {Function} original the original function
|
|
168
|
+
* @returns {Function} the instrumented function
|
|
169
|
+
*/
|
|
170
|
+
function wrapRegister(shim, original) {
|
|
171
|
+
return function wrappedRegister() {
|
|
172
|
+
wrapHandler(shim, arguments, '1');
|
|
173
|
+
const result = original.apply(this, arguments);
|
|
174
|
+
return result;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Wrapper to hook handler function
|
|
181
|
+
* @param {*} shim
|
|
182
|
+
* @param {*} mod
|
|
183
|
+
* @param {*} method
|
|
184
|
+
*/
|
|
185
|
+
function wrapHandler(shim, mod, method) {
|
|
186
|
+
shim.wrap(mod, method, function wrapHandler(shim, fn) {
|
|
187
|
+
return function wrappedHandler() {
|
|
188
|
+
const type = this.type;
|
|
189
|
+
const path = this.path;
|
|
190
|
+
wrapCallback(shim, arguments, '1');
|
|
191
|
+
addRequestData(shim, type, path, arguments[0]);
|
|
192
|
+
const result = fn.apply(this, arguments);
|
|
193
|
+
return result;
|
|
194
|
+
|
|
195
|
+
}
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Wrapper to hook callback response
|
|
201
|
+
* @param {*} shim
|
|
202
|
+
* @param {*} mod
|
|
203
|
+
* @param {*} method
|
|
204
|
+
*/
|
|
205
|
+
function wrapCallback(shim, mod, method) {
|
|
206
|
+
shim.wrap(mod, method, function wrapCallback(shim, fn) {
|
|
207
|
+
return function wrappedCallback() {
|
|
208
|
+
const response = arguments[1];
|
|
209
|
+
const result = fn.apply(this, arguments);
|
|
210
|
+
return result;
|
|
211
|
+
|
|
212
|
+
}
|
|
213
|
+
})
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Utility function to add grpc request data in request map
|
|
218
|
+
* @param {*} shim
|
|
219
|
+
* @param {*} type
|
|
220
|
+
* @param {*} path
|
|
221
|
+
* @param {*} args
|
|
222
|
+
*/
|
|
223
|
+
function addRequestData(shim, type, path, args) {
|
|
224
|
+
const data = Object.assign({});
|
|
225
|
+
try {
|
|
226
|
+
const segment = shim.getActiveSegment();
|
|
227
|
+
if (segment && segment.transaction) {
|
|
228
|
+
data.method = path;
|
|
229
|
+
data.url = path;
|
|
230
|
+
data.uri = path;
|
|
231
|
+
data.headers = args.metadata.getMap();
|
|
232
|
+
if (data.headers && data.headers[NR_CSEC_FUZZ_REQUEST_ID]) {
|
|
233
|
+
let bufferObj = Buffer.from(data.headers[NR_CSEC_FUZZ_REQUEST_ID], "base64");
|
|
234
|
+
let decodedString = bufferObj.toString("utf8");
|
|
235
|
+
data.headers[NR_CSEC_FUZZ_REQUEST_ID] = decodedString;
|
|
236
|
+
}
|
|
237
|
+
data.type = type;
|
|
238
|
+
data.protocol = 'grpc';
|
|
239
|
+
data.isGRPC = true;
|
|
240
|
+
data.body = JSON.stringify(args.request);
|
|
241
|
+
data.serverPort = shim.serverPort;
|
|
242
|
+
const transactionId = segment.transaction.id;
|
|
243
|
+
requestManager.setRequest(transactionId, data);
|
|
244
|
+
}
|
|
245
|
+
} catch (error) {
|
|
246
|
+
logger.error("Error occured while extracting grpc request", error);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Utilty to set grpc util Maps
|
|
252
|
+
* @param {*} serviceObject
|
|
253
|
+
*/
|
|
254
|
+
function serviceUtil(serviceObject) {
|
|
255
|
+
let serviceValues = Object.values(serviceObject)[0];
|
|
256
|
+
for (const [key, value] of Object.entries(serviceValues)) {
|
|
257
|
+
let servObj = {
|
|
258
|
+
'serviceName': serviceObject.serviceName,
|
|
259
|
+
'originalName': value.originalName,
|
|
260
|
+
}
|
|
261
|
+
grpcutils.setMethod(value.path, servObj);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function iterateNestedObjectForServiceLookup(result, serviceObject) {
|
|
266
|
+
try {
|
|
267
|
+
for (const key in result) {
|
|
268
|
+
if (typeof result[key] === 'object' && result[key] !== 'null') {
|
|
269
|
+
iterateNestedObjectForServiceLookup(result[key], serviceObject); // Recurse into nested object
|
|
270
|
+
} else {
|
|
271
|
+
let value = result[key];
|
|
272
|
+
if (value && value.serviceName) {
|
|
273
|
+
if (!value.type && value.serviceName) {
|
|
274
|
+
grpcutils.setService(value.serviceName, serviceObject);
|
|
275
|
+
serviceUtil(value);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
} catch (error) {
|
|
281
|
+
logger.error("Error while getting service definition", error);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: New Relic Pre-Release
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
module.exports = initialize
|
|
7
|
+
const requestManager = require('../../core/request-manager');
|
|
8
|
+
const secUtils = require("../../core/sec-utils");
|
|
9
|
+
const API = require("../../../nr-security-api");
|
|
10
|
+
const lodash = require('lodash');
|
|
11
|
+
const securityMetaData = require('../../core/security-metadata');
|
|
12
|
+
const { EVENT_TYPE, EVENT_CATEGORY } = require('../../core/event-constants');
|
|
13
|
+
const { NR_CSEC_FUZZ_REQUEST_ID, QUESTION_MARK, EMPTY_STRING, COLON, SLASH } = require('../../core/constants');
|
|
14
|
+
const NRCSECTRACINGDATA = 'NR-CSEC-TRACING-DATA';
|
|
15
|
+
const DOUBLE_SLASH = '//';
|
|
16
|
+
const logger = API.getLogger();
|
|
17
|
+
const url = require('url');
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Entry point undici module instrumentation.
|
|
22
|
+
* @param {*} shim
|
|
23
|
+
* @param {*} mod
|
|
24
|
+
* @param {*} moduleName
|
|
25
|
+
*/
|
|
26
|
+
function initialize(shim, mod, moduleName) {
|
|
27
|
+
logger.info('Instrumenting ' + moduleName);
|
|
28
|
+
fetchHook(shim, mod, "fetch");
|
|
29
|
+
let util = shim.require('./lib/core/util');
|
|
30
|
+
parseOriginHook(shim, util, "parseOrigin")
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Wrapper for util.parseOrigin
|
|
35
|
+
* @param {*} shim
|
|
36
|
+
* @param {*} mod
|
|
37
|
+
* @param {*} methodName
|
|
38
|
+
*/
|
|
39
|
+
function parseOriginHook(shim, mod, methodName) {
|
|
40
|
+
shim.wrap(mod, methodName, function ClientWrapper(shim, fn) {
|
|
41
|
+
logger.debug(`Instrumenting ${methodName}`);
|
|
42
|
+
if (!shim.isFunction(fn)) {
|
|
43
|
+
return fn
|
|
44
|
+
}
|
|
45
|
+
return function wrapper() {
|
|
46
|
+
const request = requestManager.getRequest(shim);
|
|
47
|
+
try {
|
|
48
|
+
if (typeof arguments[0] === 'string') {
|
|
49
|
+
let URLObject = new URL(arguments[0]);
|
|
50
|
+
const data = {};
|
|
51
|
+
data.headers = {};
|
|
52
|
+
data.path = URLObject.pathname ? URLObject.pathname : EMPTY_STRING;
|
|
53
|
+
data.protocol = URLObject.protocol ? URLObject.protocol : 'http:';
|
|
54
|
+
data.headers.host = URLObject.host ? URLObject.host : URLObject.hostname;
|
|
55
|
+
shim.interceptedArgs = data;
|
|
56
|
+
if (request) {
|
|
57
|
+
const traceObject = secUtils.getTraceObject(shim);
|
|
58
|
+
const secMetadata = securityMetaData.getSecurityMetaData(request, data, traceObject, secUtils.getExecutionId(), EVENT_TYPE.HTTP_REQUEST, EVENT_CATEGORY.HTTP)
|
|
59
|
+
this.secEvent = API.generateSecEvent(secMetadata);
|
|
60
|
+
API.sendEvent(this.secEvent);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
} catch (error) {
|
|
64
|
+
|
|
65
|
+
}
|
|
66
|
+
const result = fn.apply(this, arguments);
|
|
67
|
+
if (result && request && request.headers[NR_CSEC_FUZZ_REQUEST_ID]) {
|
|
68
|
+
API.generateExitEvent(this.secEvent);
|
|
69
|
+
delete this.secEvent
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Wrapper to hook undici.fetch()
|
|
78
|
+
* @param {*} shim
|
|
79
|
+
* @param {*} mod
|
|
80
|
+
* @param {*} methodName
|
|
81
|
+
*/
|
|
82
|
+
function fetchHook(shim, mod, methodName) {
|
|
83
|
+
shim.wrap(mod, methodName, function makeWrapper(shim, fn) {
|
|
84
|
+
logger.debug(`Instrumenting ${methodName}`);
|
|
85
|
+
if (!shim.isFunction(fn)) {
|
|
86
|
+
return fn
|
|
87
|
+
}
|
|
88
|
+
return function wrapper() {
|
|
89
|
+
const request = requestManager.getRequest(shim);
|
|
90
|
+
try {
|
|
91
|
+
const completeURL = arguments[0];
|
|
92
|
+
const parsedUrl = url.parse(completeURL);
|
|
93
|
+
const data = {};
|
|
94
|
+
data.headers = {};
|
|
95
|
+
data.method = arguments[0].method ? arguments[0].method : EMPTY_STRING;
|
|
96
|
+
data.path = parsedUrl.pathname ? parsedUrl.pathname : parsedUrl.path;
|
|
97
|
+
data.protocol = parsedUrl.protocol;
|
|
98
|
+
data.headers.host = parsedUrl.host ? parsedUrl.host : parsedUrl.hostname;
|
|
99
|
+
data.port = parsedUrl.port ? parsedUrl.port : parsedUrl.port;
|
|
100
|
+
|
|
101
|
+
shim.interceptedArgs = data;
|
|
102
|
+
if (request && !lodash.isEmpty(data.headers.host) && !lodash.isEmpty(data.path)) {
|
|
103
|
+
const appUUID = API.getSecAgent().applicationInfo.applicationUUID;
|
|
104
|
+
const traceObject = secUtils.getTraceObject(shim);
|
|
105
|
+
const secMetadata = securityMetaData.getSecurityMetaData(request, data, traceObject, secUtils.getExecutionId(), EVENT_TYPE.HTTP_REQUEST, EVENT_CATEGORY.HTTP)
|
|
106
|
+
this.secEvent = API.generateSecEvent(secMetadata);
|
|
107
|
+
API.sendEvent(this.secEvent);
|
|
108
|
+
|
|
109
|
+
let traceHeader = EMPTY_STRING;
|
|
110
|
+
if (request.headers['nr-csec-tracing-data']) {
|
|
111
|
+
traceHeader = request.headers['nr-csec-tracing-data'];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (arguments[1] instanceof Object) {
|
|
115
|
+
if (arguments[1] && arguments[1].headers && request.headers) {
|
|
116
|
+
arguments[1].headers[NRCSECTRACINGDATA] = traceHeader + appUUID + '/' + this.secEvent.apiId + '/' + this.secEvent.id + ';';
|
|
117
|
+
} else {
|
|
118
|
+
arguments[1].headers = {};
|
|
119
|
+
arguments[1].headers[NRCSECTRACINGDATA] = traceHeader + appUUID + '/' + this.secEvent.apiId + '/' + this.secEvent.id + ';';
|
|
120
|
+
}
|
|
121
|
+
if (request && request.headers[NR_CSEC_FUZZ_REQUEST_ID] && arguments[1].headers) {
|
|
122
|
+
arguments[1].headers[NR_CSEC_FUZZ_REQUEST_ID] = request.headers[NR_CSEC_FUZZ_REQUEST_ID];
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
} catch (error) {
|
|
127
|
+
logger.debug("Error while extracting undici fetch args:", error);
|
|
128
|
+
}
|
|
129
|
+
const result = fn.apply(this, arguments);
|
|
130
|
+
|
|
131
|
+
if (result && request && request.headers[NR_CSEC_FUZZ_REQUEST_ID]) {
|
|
132
|
+
API.generateExitEvent(this.secEvent);
|
|
133
|
+
delete this.secEvent
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
-
* SPDX-License-Identifier: New Relic
|
|
3
|
+
* SPDX-License-Identifier: New Relic Software License v1.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
const API = require('../nr-security-api');
|
|
@@ -190,9 +190,65 @@ newrelic.instrumentWebframework({
|
|
|
190
190
|
}
|
|
191
191
|
})
|
|
192
192
|
|
|
193
|
+
newrelic.instrumentWebframework({
|
|
194
|
+
moduleName: 'undici',
|
|
195
|
+
isEsm: true,
|
|
196
|
+
onRequire: require('./hooks/undici/nr-undici'),
|
|
197
|
+
onError: function intrumentErrorHandler(err) {
|
|
198
|
+
logger.error(err.message, err.stack)
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
|
|
193
202
|
|
|
203
|
+
newrelic.instrument({
|
|
204
|
+
type: 'conglomerate',
|
|
205
|
+
moduleName: '@grpc/grpc-js/build/src/server',
|
|
206
|
+
isEsm: true,
|
|
207
|
+
onRequire: require('./hooks/grpc-js/nr-grpc').wrapServer,
|
|
208
|
+
onError: function intrumentErrorHandler(err) {
|
|
209
|
+
logger.error(err.message, err.stack)
|
|
210
|
+
}
|
|
211
|
+
})
|
|
194
212
|
|
|
213
|
+
newrelic.instrument({
|
|
214
|
+
type: 'conglomerate',
|
|
215
|
+
moduleName: '@grpc/grpc-js/build/src/make-client',
|
|
216
|
+
isEsm: true,
|
|
217
|
+
onRequire: require('./hooks/grpc-js/nr-grpc').wrapMakeClient,
|
|
218
|
+
onError: function intrumentErrorHandler(err) {
|
|
219
|
+
logger.error(err.message, err.stack)
|
|
220
|
+
}
|
|
221
|
+
})
|
|
195
222
|
|
|
223
|
+
newrelic.instrument({
|
|
224
|
+
type: 'conglomerate',
|
|
225
|
+
moduleName: '@grpc/grpc-js/build/src/resolving-call',
|
|
226
|
+
isEsm: true,
|
|
227
|
+
onRequire: require('./hooks/grpc-js/nr-grpc').wrapStartResolve,
|
|
228
|
+
onError: function intrumentErrorHandler(err) {
|
|
229
|
+
logger.error(err.message, err.stack)
|
|
230
|
+
}
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
newrelic.instrument({
|
|
234
|
+
type: 'conglomerate',
|
|
235
|
+
moduleName: '@grpc/grpc-js/build/src/call-stream',
|
|
236
|
+
isEsm: true,
|
|
237
|
+
onRequire: require('./hooks/grpc-js/nr-grpc').wrapStartCall,
|
|
238
|
+
onError: function intrumentErrorHandler(err) {
|
|
239
|
+
logger.error(err.message, err.stack)
|
|
240
|
+
}
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
newrelic.instrument({
|
|
244
|
+
type: 'conglomerate',
|
|
245
|
+
moduleName: '@grpc/grpc-js',
|
|
246
|
+
isEsm: true,
|
|
247
|
+
onRequire: require('./hooks/grpc-js/nr-grpc').initialize,
|
|
248
|
+
onError: function intrumentErrorHandler(err) {
|
|
249
|
+
logger.error(err.message, err.stack)
|
|
250
|
+
}
|
|
251
|
+
})
|
|
196
252
|
|
|
197
253
|
|
|
198
254
|
|