@newrelic/security-agent 0.4.0 → 0.6.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 +29 -0
- package/README.md +1 -0
- package/THIRD_PARTY_NOTICES.md +17 -18
- package/lib/instrumentation-security/core/sec-utils.js +1 -0
- package/lib/instrumentation-security/hooks/@nestjs/nr-nestjs-core.js +63 -0
- package/lib/instrumentation-security/hooks/express/nr-express.js +2 -0
- package/lib/instrumentation-security/hooks/fastify/nr-fastify.js +1 -0
- package/lib/instrumentation-security/hooks/fs/nr-fs.js +18 -13
- package/lib/instrumentation-security/hooks/hapi/nr-hapi.js +2 -1
- package/lib/instrumentation-security/hooks/http/nr-http.js +31 -3
- package/lib/instrumentation-security/hooks/koa/@koa/nr-@koa-router.js +3 -1
- package/lib/instrumentation-security/hooks/ldap/nr-ldap.js +1 -0
- package/lib/instrumentation-security/hooks/mongodb/common.js +2 -0
- package/lib/instrumentation-security/hooks/mongodb/nr-mongodb.js +1 -1
- package/lib/instrumentation-security/hooks/mysql/nr-mysql.js +5 -2
- package/lib/instrumentation-security/hooks/native/nr-childProcess.js +3 -0
- package/lib/instrumentation-security/hooks/postgres/nr-postgres.js +1 -0
- package/lib/instrumentation-security/hooks/restify/nr-restify.js +3 -1
- package/lib/instrumentation-security/hooks/xpath/nr-xpath.js +4 -2
- package/lib/instrumentation-security/index.js +9 -0
- package/lib/nr-security-agent/index.js +9 -4
- package/lib/nr-security-agent/lib/core/Auth-headers.js +7 -0
- package/lib/nr-security-agent/lib/core/LogMessage.js +39 -14
- package/lib/nr-security-agent/lib/core/applicationinfo.js +1 -1
- package/lib/nr-security-agent/lib/core/commonUtils.js +28 -4
- package/lib/nr-security-agent/lib/core/connections/websocket/response/fuzz-request-handler.js +21 -6
- package/lib/nr-security-agent/lib/core/connections/websocket/response/index.js +5 -2
- package/lib/nr-security-agent/lib/core/connections/websocket/websocket.js +21 -2
- package/lib/nr-security-agent/lib/core/sec-agent-constants.js +3 -0
- package/lib/nr-security-agent/lib/core/sec-util.js +14 -6
- package/lib/nr-security-agent/lib/core/websocket-client.js +9 -8
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
### v0.6.0 (2024-01-03)
|
|
2
|
+
#### Features
|
|
3
|
+
* Added ws headers NR-CSEC-ENTITY-GUID and NR-CSEC-ENTITY-NAME
|
|
4
|
+
* Updated jsonVersion to 1.1.1 in security events
|
|
5
|
+
* Support to send important logs/errors to security engine
|
|
6
|
+
#### Bug fixes
|
|
7
|
+
* Added missing protocol in http request object
|
|
8
|
+
* Fix for honouring probing interval from policy
|
|
9
|
+
#### Miscellaneous chores
|
|
10
|
+
* Added nestjs test cases
|
|
11
|
+
* Additional logging for instrumented modules and methods
|
|
12
|
+
* Upgraded axios to v1.6.3
|
|
13
|
+
* Removed pinned version for axios and check-disk-space
|
|
14
|
+
* Update in lockfileVersion of package-lock.json
|
|
15
|
+
* Updated @babel/traverse, protobufjs, fast-xml-parser and @aws-sdk/credential-providers
|
|
16
|
+
* Updated Readme.md
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### v0.5.0 (2023-11-17)
|
|
20
|
+
#### Features
|
|
21
|
+
* IAST support for NestJS framework
|
|
22
|
+
#### Bug Fixes
|
|
23
|
+
* Fixed misspelled constant in fs.open() hook
|
|
24
|
+
* Minor fix in applicationInfo for pod properties
|
|
25
|
+
#### Miscellaneous chores
|
|
26
|
+
* Upgraded ws to v8.14.2 and updated initialization of websocket for v8.x.
|
|
27
|
+
* Upgraded check-disk-space to v3.4.0
|
|
28
|
+
* Upgraded @aws-sdk/client-lambda to v3.436.0
|
|
29
|
+
|
|
1
30
|
### v0.4.0 (2023-10-27)
|
|
2
31
|
#### Features
|
|
3
32
|
* Added event stats for RASP, IAST and exit events in healthcheck.
|
package/README.md
CHANGED
|
@@ -62,6 +62,7 @@ The [Developer docs](http://newrelic.github.io/node-newrelic/) for writing instr
|
|
|
62
62
|
- [fastify](https://www.npmjs.com/package/fastify)(2.x, 3.x and 4.x)
|
|
63
63
|
- [restify](https://www.npmjs.com/package/restify)(8.x, 9.x, 10.x and 11.x)
|
|
64
64
|
- [director](https://www.npmjs.com/package/director)(1.2.x)
|
|
65
|
+
- [@nestjs/core](https://www.npmjs.com/package/@nestjs/core)(8.x and above)
|
|
65
66
|
- [ldapjs](https://www.npmjs.com/package/ldapjs)(2.x and above)
|
|
66
67
|
- [ldapts](https://www.npmjs.com/package/ldapts)(2.x and above)
|
|
67
68
|
- [xpath](https://www.npmjs.com/package/xpath)(0.0.20 and above)
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -75,7 +75,7 @@ code, the source code can be found at [https://github.com/newrelic/csec-node-age
|
|
|
75
75
|
|
|
76
76
|
### @aws-sdk/client-lambda
|
|
77
77
|
|
|
78
|
-
This product includes source derived from [@aws-sdk/client-lambda](https://github.com/aws/aws-sdk-js-v3) ([v3.
|
|
78
|
+
This product includes source derived from [@aws-sdk/client-lambda](https://github.com/aws/aws-sdk-js-v3) ([v3.436.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.436.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.436.0/LICENSE):
|
|
79
79
|
|
|
80
80
|
```
|
|
81
81
|
Apache License
|
|
@@ -284,7 +284,7 @@ This product includes source derived from [@aws-sdk/client-lambda](https://githu
|
|
|
284
284
|
|
|
285
285
|
### axios
|
|
286
286
|
|
|
287
|
-
This product includes source derived from [axios](https://github.com/axios/axios) ([v1.6.
|
|
287
|
+
This product includes source derived from [axios](https://github.com/axios/axios) ([v1.6.3](https://github.com/axios/axios/tree/v1.6.3)), distributed under the [MIT License](https://github.com/axios/axios/blob/v1.6.3/LICENSE):
|
|
288
288
|
|
|
289
289
|
```
|
|
290
290
|
# Copyright (c) 2014-present Matt Zabriskie & Collaborators
|
|
@@ -299,7 +299,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
299
299
|
|
|
300
300
|
### check-disk-space
|
|
301
301
|
|
|
302
|
-
This product includes source derived from [check-disk-space](https://github.com/Alex-D/check-disk-space) ([v3.
|
|
302
|
+
This product includes source derived from [check-disk-space](https://github.com/Alex-D/check-disk-space) ([v3.4.0](https://github.com/Alex-D/check-disk-space/tree/v3.4.0)), distributed under the [MIT License](https://github.com/Alex-D/check-disk-space/blob/v3.4.0/LICENSE):
|
|
303
303
|
|
|
304
304
|
```
|
|
305
305
|
MIT License
|
|
@@ -795,30 +795,29 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
795
795
|
|
|
796
796
|
### ws
|
|
797
797
|
|
|
798
|
-
This product includes source derived from [ws](https://github.com/websockets/ws) ([
|
|
798
|
+
This product includes source derived from [ws](https://github.com/websockets/ws) ([v8.14.2](https://github.com/websockets/ws/tree/v8.14.2)), distributed under the [MIT License](https://github.com/websockets/ws/blob/v8.14.2/LICENSE):
|
|
799
799
|
|
|
800
800
|
```
|
|
801
|
-
The MIT License (MIT)
|
|
802
|
-
|
|
803
801
|
Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com>
|
|
802
|
+
Copyright (c) 2013 Arnout Kazemier and contributors
|
|
803
|
+
Copyright (c) 2016 Luigi Pinca and contributors
|
|
804
804
|
|
|
805
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
805
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
806
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
807
|
+
the Software without restriction, including without limitation the rights to
|
|
808
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
809
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
810
|
+
subject to the following conditions:
|
|
811
811
|
|
|
812
812
|
The above copyright notice and this permission notice shall be included in all
|
|
813
813
|
copies or substantial portions of the Software.
|
|
814
814
|
|
|
815
815
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
816
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
SOFTWARE.
|
|
816
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
817
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
818
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
819
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
820
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
822
821
|
|
|
823
822
|
```
|
|
824
823
|
|
|
@@ -172,6 +172,7 @@ function addRequestData(shim, request) {
|
|
|
172
172
|
const data = Object.assign({});
|
|
173
173
|
const segment = shim.getActiveSegment();
|
|
174
174
|
if (segment && segment.transaction) {
|
|
175
|
+
data.protocol = (request.connection && request.connection.encrypted) ? 'https' : 'http';
|
|
175
176
|
data.body = null;
|
|
176
177
|
data.headers = request.headers;
|
|
177
178
|
data.url = request.url;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: New Relic Pre-Release
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
const secUtils = require('../../core/sec-utils');
|
|
9
|
+
const { ATTHERATE, DOUBLE_DOLLAR, EMPTY_STR } = require('../../core/constants');
|
|
10
|
+
const routeManager = require('../../core/route-manager');
|
|
11
|
+
const API = require("../../../nr-security-api");
|
|
12
|
+
const logger = API.getLogger();
|
|
13
|
+
const semver = require('semver')
|
|
14
|
+
|
|
15
|
+
const RequestMethods = {
|
|
16
|
+
"0": "GET",
|
|
17
|
+
"1": "POST",
|
|
18
|
+
"2": "PUT",
|
|
19
|
+
"3": "DELETE",
|
|
20
|
+
"4": "PATCH",
|
|
21
|
+
"5": "ALL",
|
|
22
|
+
"6": "OPTIONS",
|
|
23
|
+
"7": "HEAD",
|
|
24
|
+
"8": "SEARCH",
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = function initialize(shim) {
|
|
28
|
+
const nestJsVersion = shim.require('./package.json').version
|
|
29
|
+
logger.info("Instrumenting nestjs", nestJsVersion)
|
|
30
|
+
if (semver.lt(nestJsVersion, '8.0.0')) {
|
|
31
|
+
logger.debug(
|
|
32
|
+
`Not instrumenting Nest.js version ${nestJsVersion}; minimum instrumentable version is 8.0.0`
|
|
33
|
+
)
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const routerExplorer = shim.require("./router/router-explorer").RouterExplorer;
|
|
38
|
+
|
|
39
|
+
shim.wrap(routerExplorer.prototype, 'applyCallbackToRouter', function wrapApplyCallbackToRouter(shim, fn) {
|
|
40
|
+
if (!shim.isFunction(fn)) {
|
|
41
|
+
return fn
|
|
42
|
+
}
|
|
43
|
+
logger.debug(`Instrumenting routerExplorer.prototype.applyCallbackToRouter`)
|
|
44
|
+
return function wrappedApplyCallbackToRouter() {
|
|
45
|
+
try {
|
|
46
|
+
const stakTrace = secUtils.traceElementForRoute();
|
|
47
|
+
const splittedStack = stakTrace[0].split(DOUBLE_DOLLAR);
|
|
48
|
+
const verb = RequestMethods[arguments[1].requestMethod];
|
|
49
|
+
const path = (arguments[4].ctrlPath) + (arguments[1].path[0] == '/' ? EMPTY_STR : arguments[1].path[0]);
|
|
50
|
+
const key = verb + ATTHERATE + path;
|
|
51
|
+
routeManager.setRoute(key, splittedStack[0]);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
}
|
|
54
|
+
return fn.apply(this, arguments);
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
@@ -42,6 +42,7 @@ function wrapExpress4(shim, express) {
|
|
|
42
42
|
if (!shim.isFunction(fn)) {
|
|
43
43
|
return fn
|
|
44
44
|
}
|
|
45
|
+
logger.debug('Instrumenting express.Router.route');
|
|
45
46
|
return function wrappedRoute() {
|
|
46
47
|
try {
|
|
47
48
|
const stakTrace = secUtils.traceElementForRoute();
|
|
@@ -62,6 +63,7 @@ function wrapExpress4(shim, express) {
|
|
|
62
63
|
if (!shim.isFunction(fn)) {
|
|
63
64
|
return fn
|
|
64
65
|
}
|
|
66
|
+
logger.debug('Instrumenting express.Router.process_params')
|
|
65
67
|
return function wrappedParam() {
|
|
66
68
|
extractParams(shim, arguments[2]);
|
|
67
69
|
const route = fn.apply(this, arguments)
|
|
@@ -94,8 +94,8 @@ const promiseFunctionProbableToFI = [
|
|
|
94
94
|
*/
|
|
95
95
|
function initialize(shim, mod, moduleName) {
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
logger.info(
|
|
97
|
+
|
|
98
|
+
logger.info(`Instrumenting ${moduleName}`);
|
|
99
99
|
requireHook.initialize(shim)
|
|
100
100
|
const binding = process.binding("fs");
|
|
101
101
|
openHook(shim, binding, moduleName);
|
|
@@ -116,6 +116,7 @@ function initialize(shim, mod, moduleName) {
|
|
|
116
116
|
*/
|
|
117
117
|
function openHook(shim, mod, moduleName) {
|
|
118
118
|
shim.wrap(mod, "open", function makeOpenWrapper(shim, fn) {
|
|
119
|
+
logger.debug(`Instrumenting ${moduleName}.open`);
|
|
119
120
|
return function openWrapper() {
|
|
120
121
|
const parameters = Array.prototype.slice.apply(arguments);
|
|
121
122
|
const interceptedArgs = [arguments[0]];
|
|
@@ -128,7 +129,7 @@ function openHook(shim, mod, moduleName) {
|
|
|
128
129
|
parameters[0] = arguments[0];
|
|
129
130
|
}
|
|
130
131
|
}
|
|
131
|
-
if (request && typeof parameters[0] === STRING && !lodash.isEmpty(parameters[0])
|
|
132
|
+
if (request && typeof parameters[0] === STRING && !lodash.isEmpty(parameters[0])) {
|
|
132
133
|
const policy = API.getPolicy();
|
|
133
134
|
const dynamicScanningFlag = policy.data ? policy.data.vulnerabilityScan.iastScan.enabled : false;
|
|
134
135
|
const url = request.url;
|
|
@@ -136,7 +137,7 @@ function openHook(shim, mod, moduleName) {
|
|
|
136
137
|
const trimedURL = url.split(QUESTIONMARK)[0];
|
|
137
138
|
if (!trimedURL.includes(path.basename(parameters[0])) || decodedURL.includes(DOTDOTSLASH) || dynamicScanningFlag) {
|
|
138
139
|
try {
|
|
139
|
-
if (parameters[0].startsWith(
|
|
140
|
+
if (parameters[0].startsWith(DOTDOTSLASH)) {
|
|
140
141
|
parameters[0] = agentModule.applicationInfo.serverInfo.deployedApplications[0].deployedPath + SLASH + parameters[0];
|
|
141
142
|
} else if (parameters[0].startsWith(SLASHDOTDOT)) {
|
|
142
143
|
parameters[0] = agentModule.applicationInfo.serverInfo.deployedApplications[0].deployedPath + parameters[0];
|
|
@@ -151,14 +152,14 @@ function openHook(shim, mod, moduleName) {
|
|
|
151
152
|
this.secEvent = API.generateSecEvent(secMetadata);
|
|
152
153
|
API.sendEvent(this.secEvent);
|
|
153
154
|
const callbackFlag = isCallback(arguments);
|
|
154
|
-
if (callbackFlag &&
|
|
155
|
+
if (callbackFlag && request.headers[NR_CSEC_FUZZ_REQUEST_ID]) {
|
|
155
156
|
callbackHook(shim, arguments[3], 'oncomplete', this.secEvent);
|
|
156
157
|
}
|
|
157
158
|
}
|
|
158
159
|
|
|
159
160
|
}
|
|
160
161
|
const result = fn.apply(this, arguments);
|
|
161
|
-
if(result>0 && request && request.headers[NR_CSEC_FUZZ_REQUEST_ID]){
|
|
162
|
+
if (result > 0 && request && request.headers[NR_CSEC_FUZZ_REQUEST_ID]) {
|
|
162
163
|
//here generate exit event.
|
|
163
164
|
API.generateExitEvent(this.secEvent);
|
|
164
165
|
delete this.secEvent;
|
|
@@ -177,18 +178,19 @@ function openHook(shim, mod, moduleName) {
|
|
|
177
178
|
function probableToFAHooks(shim, mod, moduleName) {
|
|
178
179
|
functionsProbableToFA.forEach(function (fun) {
|
|
179
180
|
shim.wrap(mod, fun, function makeFAWrapper(shim, fn) {
|
|
181
|
+
logger.debug(`Instrumenting ${moduleName}.${fun}`);
|
|
180
182
|
return function FAWrapper() {
|
|
181
183
|
const interceptedArgs = [arguments[0]];
|
|
182
184
|
shim.interceptedArgs = interceptedArgs;
|
|
183
185
|
const request = requestManager.getRequest(shim);
|
|
184
|
-
if (request && typeof arguments[0] === STRING
|
|
186
|
+
if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
|
|
185
187
|
const traceObject = secUtils.getTraceObject(shim);
|
|
186
188
|
const secMetadata = securityMetaData.getSecurityMetaData(request, interceptedArgs, traceObject, secUtils.getExecutionId(), EVENT_TYPE.FILE_OPERATION, EVENT_CATEGORY.FILE)
|
|
187
189
|
this.secEvent = API.generateSecEvent(secMetadata);
|
|
188
190
|
API.sendEvent(this.secEvent);
|
|
189
191
|
const callbackFlag = isCallback(arguments);
|
|
190
|
-
if (callbackFlag &&
|
|
191
|
-
callbackHook(shim, arguments, arguments.length-1, this.secEvent);
|
|
192
|
+
if (callbackFlag && request.headers[NR_CSEC_FUZZ_REQUEST_ID]) {
|
|
193
|
+
callbackHook(shim, arguments, arguments.length - 1, this.secEvent);
|
|
192
194
|
}
|
|
193
195
|
}
|
|
194
196
|
return fn.apply(this, arguments);
|
|
@@ -206,11 +208,12 @@ function probableToFAHooks(shim, mod, moduleName) {
|
|
|
206
208
|
function probableToFIHooks(shim, mod, moduleName) {
|
|
207
209
|
functionProbableToFI.forEach(function (fun) {
|
|
208
210
|
shim.wrap(mod, fun, function makeFIWrapper(shim, fn) {
|
|
211
|
+
logger.debug(`Instrumenting ${moduleName}.${fun}`);
|
|
209
212
|
return function FIWrapper() {
|
|
210
213
|
const interceptedArgs = [arguments[0]];
|
|
211
214
|
shim.interceptedArgs = interceptedArgs;
|
|
212
215
|
const request = requestManager.getRequest(shim);
|
|
213
|
-
if (request && typeof arguments[0] === STRING
|
|
216
|
+
if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
|
|
214
217
|
const traceObject = secUtils.getTraceObject(shim);
|
|
215
218
|
if (fun === COPY_FILE || fun === RENAME) {
|
|
216
219
|
const secMetadata = securityMetaData.getSecurityMetaData(request, arguments[1], traceObject, secUtils.getExecutionId(), getCase(arguments[1]), EVENT_CATEGORY.FILE)
|
|
@@ -222,7 +225,7 @@ function probableToFIHooks(shim, mod, moduleName) {
|
|
|
222
225
|
API.sendEvent(this.secEvent);
|
|
223
226
|
const callbackFlag = isCallback(arguments);
|
|
224
227
|
if (callbackFlag && request.headers[NR_CSEC_FUZZ_REQUEST_ID]) {
|
|
225
|
-
callbackHook(shim, arguments, arguments.length-1, this.secEvent);
|
|
228
|
+
callbackHook(shim, arguments, arguments.length - 1, this.secEvent);
|
|
226
229
|
}
|
|
227
230
|
}
|
|
228
231
|
return fn.apply(this, arguments);
|
|
@@ -239,12 +242,13 @@ function probableToFIHooks(shim, mod, moduleName) {
|
|
|
239
242
|
*/
|
|
240
243
|
function probablePromiseToFAHooks(shim, mod, moduleName) {
|
|
241
244
|
promiseFunctionsProbableToFA.forEach(function (fun) {
|
|
245
|
+
logger.debug(`Instrumenting Promise ${moduleName}.${fun}`);
|
|
242
246
|
shim.wrap(mod, fun, function makeFAWrapper(shim, fn) {
|
|
243
247
|
return function FAWrapper() {
|
|
244
248
|
const interceptedArgs = [arguments[0]];
|
|
245
249
|
shim.interceptedArgs = interceptedArgs;
|
|
246
250
|
const request = requestManager.getRequest(shim);
|
|
247
|
-
if (request && typeof arguments[0] === STRING
|
|
251
|
+
if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
|
|
248
252
|
const traceObject = secUtils.getTraceObject(shim);
|
|
249
253
|
const secMetadata = securityMetaData.getSecurityMetaData(request, interceptedArgs, traceObject, secUtils.getExecutionId(), EVENT_TYPE.FILE_OPERATION, EVENT_CATEGORY.FILE)
|
|
250
254
|
this.secEvent = API.generateSecEvent(secMetadata);
|
|
@@ -264,12 +268,13 @@ function probablePromiseToFAHooks(shim, mod, moduleName) {
|
|
|
264
268
|
*/
|
|
265
269
|
function probablePromiseToFIHooks(shim, mod, moduleName) {
|
|
266
270
|
promiseFunctionProbableToFI.forEach(function (fun) {
|
|
271
|
+
logger.debug(`Instrumenting Promise ${moduleName}.${fun}`);
|
|
267
272
|
shim.wrap(mod, fun, function makeFIWrapper(shim, fn) {
|
|
268
273
|
return function FIWrapper() {
|
|
269
274
|
const interceptedArgs = [arguments[0]];
|
|
270
275
|
shim.interceptedArgs = interceptedArgs;
|
|
271
276
|
const request = requestManager.getRequest(shim);
|
|
272
|
-
if (request && typeof arguments[0] === STRING
|
|
277
|
+
if (request && typeof arguments[0] === STRING && !lodash.isEmpty(arguments[0])) {
|
|
273
278
|
const traceObject = secUtils.getTraceObject(shim);
|
|
274
279
|
if (fun === COPY_FILE || fun === RENAME) {
|
|
275
280
|
const secMetadata = securityMetaData.getSecurityMetaData(request, arguments[1], traceObject, secUtils.getExecutionId(), getCase(arguments[1]), EVENT_CATEGORY.FILE)
|
|
@@ -25,7 +25,7 @@ module.exports = function initialize(shim, hapi, moduleName) {
|
|
|
25
25
|
return
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
logger.info(
|
|
28
|
+
logger.info(`Instrumenting ${moduleName}`);
|
|
29
29
|
// 'Server' and 'server' both point to the same export,
|
|
30
30
|
// but we can't make any assumption about which will be used.
|
|
31
31
|
// Since we wrap the prototype, the second wrap should exit early.
|
|
@@ -49,6 +49,7 @@ function serverPostConstructor(shim) {
|
|
|
49
49
|
*/
|
|
50
50
|
function wrapProtoRoute(shim, proto) {
|
|
51
51
|
shim.wrap(proto, 'route', function wrapRoute(shim, original) {
|
|
52
|
+
logger.debug(`Instrumenting ${proto}.route`);
|
|
52
53
|
return function wrappedRoute() {
|
|
53
54
|
const args = shim.argsToArray.apply(shim, arguments)
|
|
54
55
|
if (!shim.isObject(args[0])) {
|
|
@@ -46,7 +46,7 @@ const CSEC_HOME_TMP = `${CSEC_HOME}/nr-security-home/tmp/language-agent/${proces
|
|
|
46
46
|
* @param {*} moduleName
|
|
47
47
|
*/
|
|
48
48
|
function initialize(shim, mod, moduleName) {
|
|
49
|
-
logger.info(
|
|
49
|
+
logger.info(`Instrumenting ${moduleName}`);
|
|
50
50
|
emitHook(shim, mod, moduleName);
|
|
51
51
|
createServerHook(shim, mod, moduleName);
|
|
52
52
|
outboundHook(shim, mod, 'request', moduleName);
|
|
@@ -87,7 +87,11 @@ function setupRequestMapCleanup() {
|
|
|
87
87
|
* @param {*} moduleName
|
|
88
88
|
*/
|
|
89
89
|
function outboundHook(shim, mod, method, moduleName) {
|
|
90
|
+
logger.debug(`Instrumenting ${moduleName}.${method}`);
|
|
90
91
|
shim.wrap(mod, method, function makeRequestWrapper(shim, fn) {
|
|
92
|
+
if (!shim.isFunction(fn)) {
|
|
93
|
+
return fn
|
|
94
|
+
}
|
|
91
95
|
return function requestWrapper() {
|
|
92
96
|
const request = requestManager.getRequest(shim);
|
|
93
97
|
const data = {};
|
|
@@ -206,6 +210,7 @@ function addRequestData(shim, request) {
|
|
|
206
210
|
const data = Object.assign({});
|
|
207
211
|
const segment = shim.getActiveSegment();
|
|
208
212
|
if (segment && segment.transaction) {
|
|
213
|
+
data.protocol = (request.connection && request.connection.encrypted) ? 'https' : 'http';
|
|
209
214
|
data.body = null;
|
|
210
215
|
data.headers = request.headers;
|
|
211
216
|
data.url = request.url;
|
|
@@ -255,6 +260,10 @@ function addRequestData(shim, request) {
|
|
|
255
260
|
*/
|
|
256
261
|
function emitHook(shim, mod, moduleName) {
|
|
257
262
|
shim.wrap(mod && mod.Server && mod.Server.prototype, 'emit', function makeEmitWrapper(shim, fn) {
|
|
263
|
+
logger.debug(`Instrumenting ${moduleName}.Server.prototype.emit`);
|
|
264
|
+
if (!shim.isFunction(fn)) {
|
|
265
|
+
return fn
|
|
266
|
+
}
|
|
258
267
|
return function emitWrapper() {
|
|
259
268
|
const req = arguments[1];
|
|
260
269
|
const resp = arguments[2];
|
|
@@ -263,8 +272,11 @@ function emitHook(shim, mod, moduleName) {
|
|
|
263
272
|
if (NRAgent && NRAgent.config.security.detection.rxss.enabled) {
|
|
264
273
|
responseHook(resp, req, shim);
|
|
265
274
|
}
|
|
266
|
-
|
|
275
|
+
|
|
267
276
|
shim.wrap(req, 'on', function makeOnWrapper(shim, fn) {
|
|
277
|
+
if (!shim.isFunction(fn)) {
|
|
278
|
+
return fn
|
|
279
|
+
}
|
|
268
280
|
return function OnWrapper() {
|
|
269
281
|
if (!requestManager.getRequest(shim)) {
|
|
270
282
|
addRequestData(shim, req);
|
|
@@ -292,10 +304,17 @@ function emitHook(shim, mod, moduleName) {
|
|
|
292
304
|
* @param {*} shim
|
|
293
305
|
* @param {*} mod
|
|
294
306
|
*/
|
|
295
|
-
function createServerHook(shim, mod) {
|
|
307
|
+
function createServerHook(shim, mod, moduleName) {
|
|
296
308
|
shim.wrap(mod, 'createServer', function createServerWrapper(shim, fn) {
|
|
309
|
+
logger.debug(`Instrumenting ${moduleName}.createServer`);
|
|
310
|
+
if (!shim.isFunction(fn)) {
|
|
311
|
+
return fn
|
|
312
|
+
}
|
|
297
313
|
return function wrappedCreateServer() {
|
|
298
314
|
shim.wrap(arguments, '0', function appWrapper(shim, fn) {
|
|
315
|
+
if (!shim.isFunction(fn)) {
|
|
316
|
+
return fn
|
|
317
|
+
}
|
|
299
318
|
return function wrappedApp() {
|
|
300
319
|
let req = arguments[0];
|
|
301
320
|
if (!requestManager.getRequest(shim)) {
|
|
@@ -316,6 +335,9 @@ function createServerHook(shim, mod) {
|
|
|
316
335
|
*/
|
|
317
336
|
function onDataHook(shim, mod) {
|
|
318
337
|
shim.wrap(mod, '1', function makeOnDataWrapper(shim, fn) {
|
|
338
|
+
if (!shim.isFunction(fn)) {
|
|
339
|
+
return fn
|
|
340
|
+
}
|
|
319
341
|
return function onDataWrapper() {
|
|
320
342
|
const chunk = arguments[0];
|
|
321
343
|
const chunkType = typeof chunk;
|
|
@@ -347,6 +369,9 @@ function responseHook(resp, req, shim) {
|
|
|
347
369
|
resp.res.body = EMPTY_STRING;
|
|
348
370
|
|
|
349
371
|
shim.wrap(resp, 'write', function makeWriteWrapper(shim, fn) {
|
|
372
|
+
if (!shim.isFunction(fn)) {
|
|
373
|
+
return fn
|
|
374
|
+
}
|
|
350
375
|
return function wrappedWrite() {
|
|
351
376
|
const response = this;
|
|
352
377
|
responseBodyCompute(response, arguments);
|
|
@@ -355,6 +380,9 @@ function responseHook(resp, req, shim) {
|
|
|
355
380
|
})
|
|
356
381
|
// wrapper for response.end()
|
|
357
382
|
shim.wrap(resp, 'end', function makeEndWrapper(shim, fn) {
|
|
383
|
+
if (!shim.isFunction(fn)) {
|
|
384
|
+
return fn
|
|
385
|
+
}
|
|
358
386
|
return function wrappedEnd() {
|
|
359
387
|
const response = this;
|
|
360
388
|
responseBodyCompute(response, arguments);
|
|
@@ -20,7 +20,7 @@ const logger = API.getLogger();
|
|
|
20
20
|
* @param {*} moduleName
|
|
21
21
|
*/
|
|
22
22
|
function initialize(shim, mod, moduleName) {
|
|
23
|
-
logger.info(
|
|
23
|
+
logger.info(`Instrumenting ${moduleName}`);
|
|
24
24
|
const VerbMethods = ['all', 'delete', 'get', 'head', 'opts', 'post', 'put', 'patch'];
|
|
25
25
|
|
|
26
26
|
// RouteMap hooks
|
|
@@ -29,6 +29,7 @@ function initialize(shim, mod, moduleName) {
|
|
|
29
29
|
if (!shim.isFunction(fn)) {
|
|
30
30
|
return fn
|
|
31
31
|
}
|
|
32
|
+
logger.debug(`Instrumenting ${moduleName}.prototype.${fun}`);
|
|
32
33
|
return function wrappedRoute() {
|
|
33
34
|
try {
|
|
34
35
|
const stakTrace = secUtils.traceElementForRoute();
|
|
@@ -59,6 +60,7 @@ function initialize(shim, mod, moduleName) {
|
|
|
59
60
|
*/
|
|
60
61
|
function paramHook(shim, mod, moduleName) {
|
|
61
62
|
shim.wrap(mod && mod.prototype, 'params', function wrapMatch(shim, fn) {
|
|
63
|
+
logger.debug(`Instrumenting ${moduleName}.prototype.params`);
|
|
62
64
|
return function wrappedMatch() {
|
|
63
65
|
const segment = shim.getActiveSegment();
|
|
64
66
|
if (segment && segment.transaction) {
|
|
@@ -35,6 +35,7 @@ function initialize(shim, mod, moduleName){
|
|
|
35
35
|
*/
|
|
36
36
|
function ldapHooks(shim, mod, methodName, moduleName){
|
|
37
37
|
shim.wrap(mod, methodName, function makeWrapper(shim,fn){
|
|
38
|
+
logger.debug(`Instrumenting ${moduleName}.${methodName}`);
|
|
38
39
|
return function wrapper(){
|
|
39
40
|
const param = {};
|
|
40
41
|
param.name = arguments[0];
|
|
@@ -55,6 +55,7 @@ function payloadType(obj) {
|
|
|
55
55
|
|
|
56
56
|
function queryHook(shim, mod, method) {
|
|
57
57
|
shim.wrap(mod, method, function makeQueryWrapper(shim, fn) {
|
|
58
|
+
logger.debug(`Instrumenting mongodb.${method}`);
|
|
58
59
|
return function queryWrapper() {
|
|
59
60
|
const request = requestManager.getRequest(shim);
|
|
60
61
|
if (CURSOR_OPS.includes(method)) {
|
|
@@ -194,6 +195,7 @@ function callbackHook(shim, mod, fun, secEvent) {
|
|
|
194
195
|
|
|
195
196
|
common.queryHookV2 = function queryHookV2(shim, mod, method) {
|
|
196
197
|
shim.wrap(mod, method, function makeQueryWrapper(shim, fn) {
|
|
198
|
+
logger.debug(`Instrumenting mongodb.${method}`);
|
|
197
199
|
return function queryWrapper() {
|
|
198
200
|
const request = requestManager.getRequest(shim);
|
|
199
201
|
if (CURSOR_OPS.includes(method)) {
|
|
@@ -18,7 +18,7 @@ const symbols = {
|
|
|
18
18
|
createPoolCluster: Symbol('createPoolCluster'),
|
|
19
19
|
wrappedPoolConnection: Symbol('wrappedPoolConnection')
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
let modName = '';
|
|
22
22
|
module.exports = initialize;
|
|
23
23
|
|
|
24
24
|
/**
|
|
@@ -28,6 +28,7 @@ module.exports = initialize;
|
|
|
28
28
|
* @param {*} moduleName
|
|
29
29
|
*/
|
|
30
30
|
function initialize(shim, mysql, moduleName) {
|
|
31
|
+
modName = moduleName;
|
|
31
32
|
logger.info("Instrumenting", moduleName);
|
|
32
33
|
if (shim._moduleRoot.includes("mysql2")) {
|
|
33
34
|
promiseInitialize(shim, mysql, moduleName);
|
|
@@ -119,6 +120,7 @@ function wrapGetConnection(shim, connectable) {
|
|
|
119
120
|
|
|
120
121
|
const proto = Object.getPrototypeOf(connectable);
|
|
121
122
|
shim.wrap(proto, "getConnection", function doWrapGetConnection(shim, fn) {
|
|
123
|
+
logger.debug(`Instrumenting ${modName}.getConnection`);
|
|
122
124
|
return function wrappedGetConnection() {
|
|
123
125
|
const args = shim.toArray(arguments);
|
|
124
126
|
const cbIdx = args.length - 1;
|
|
@@ -208,7 +210,7 @@ function extractQueryArgs(shim, args) {
|
|
|
208
210
|
// query(opts [, values], callback)
|
|
209
211
|
rawQuery = args[0].sql;
|
|
210
212
|
try {
|
|
211
|
-
if (args[0].values && typeof args[0].values
|
|
213
|
+
if (args[0].values && typeof args[0].values == 'object') {
|
|
212
214
|
param = Object.values(args[0].values)
|
|
213
215
|
}
|
|
214
216
|
} catch (error) {
|
|
@@ -240,6 +242,7 @@ function extractQueryArgs(shim, args) {
|
|
|
240
242
|
*/
|
|
241
243
|
function queryHook(shim, mod, method, isPoolQuery) {
|
|
242
244
|
shim.wrap(mod, method, function makeQueryWrapper(shim, fn) {
|
|
245
|
+
logger.debug(`Instrumenting ${modName}.${method}`);
|
|
243
246
|
return function queryWrapper() {
|
|
244
247
|
const parameters = extractQueryArgs(shim, arguments);
|
|
245
248
|
shim.interceptedArgs = parameters;
|
|
@@ -26,6 +26,7 @@ function initialize(shim, childProcess, moduleName) {
|
|
|
26
26
|
*/
|
|
27
27
|
function execFileHook(shim, childProcess, moduleName) {
|
|
28
28
|
shim.wrap(childProcess, "execFile", function makeWrapper(shim, fn) {
|
|
29
|
+
logger.debug(`Instrumenting ${moduleName}.execFile`);
|
|
29
30
|
return function wrapper() {
|
|
30
31
|
const interceptedArgs = [arguments[0]];
|
|
31
32
|
shim.interceptedArgs = interceptedArgs;
|
|
@@ -54,6 +55,7 @@ function execFileHook(shim, childProcess, moduleName) {
|
|
|
54
55
|
*/
|
|
55
56
|
function spawnSyncHook(shim, childProcess, moduleName) {
|
|
56
57
|
shim.wrap(childProcess, "spawn", function makeWrapper(shim, fn) {
|
|
58
|
+
logger.debug(`Instrumenting ${moduleName}.spawnSync`);
|
|
57
59
|
return function wrapper() {
|
|
58
60
|
const interceptedArgs = arguments[0].args;
|
|
59
61
|
shim.interceptedArgs = interceptedArgs;
|
|
@@ -83,6 +85,7 @@ function spawnSyncHook(shim, childProcess, moduleName) {
|
|
|
83
85
|
*/
|
|
84
86
|
function spawnHook(shim, childProcess, moduleName) {
|
|
85
87
|
shim.wrap(childProcess, "spawn", function makeWrapper(shim, fn) {
|
|
88
|
+
logger.debug(`Instrumenting ${moduleName}.spawn`);
|
|
86
89
|
return function wrapper() {
|
|
87
90
|
let param = [];
|
|
88
91
|
param.push(arguments[0]);
|
|
@@ -66,6 +66,7 @@ module.exports = function initialize(shim, pgsql, moduleName) {
|
|
|
66
66
|
|
|
67
67
|
function queryHook(shim, mod, method){
|
|
68
68
|
shim.wrap(mod, method, function makeQueryWrapper(shim, fn){
|
|
69
|
+
logger.debug(`Instrumenting pg.${method}`);
|
|
69
70
|
return function queryWrapper(){
|
|
70
71
|
const request = requestManager.getRequest(shim);
|
|
71
72
|
const sqlArgs = [];
|
|
@@ -21,12 +21,13 @@ const logger = API.getLogger();
|
|
|
21
21
|
* @param {*} moduleName
|
|
22
22
|
*/
|
|
23
23
|
function initialize(shim, mod, moduleName) {
|
|
24
|
-
logger.info(
|
|
24
|
+
logger.info(`Instrumenting ${moduleName}`);
|
|
25
25
|
try {
|
|
26
26
|
const registryRadix = shim.require("./lib/routerRegistryRadix");
|
|
27
27
|
|
|
28
28
|
//routerRadix hook
|
|
29
29
|
shim.wrap(registryRadix && registryRadix.prototype, 'add', function makeWrapper(shim, fn) {
|
|
30
|
+
logger.info(`Instrumenting registryRadix.prototype.add`);
|
|
30
31
|
return function wrapper() {
|
|
31
32
|
if (arguments[0]) {
|
|
32
33
|
try {
|
|
@@ -47,6 +48,7 @@ function initialize(shim, mod, moduleName) {
|
|
|
47
48
|
const router = shim.require("./lib/router");
|
|
48
49
|
|
|
49
50
|
shim.wrap(router && router.prototype, 'lookup', function lookupWrapper(shim, fn) {
|
|
51
|
+
logger.info(`Instrumenting router.prototype.lookup`);
|
|
50
52
|
return function wrappedLookup() {
|
|
51
53
|
const result = fn.apply(this, arguments);
|
|
52
54
|
extractParams(shim, arguments[0]);
|
|
@@ -27,7 +27,7 @@ function initialize(shim, mod, moduleName){
|
|
|
27
27
|
xpathHooks(shim, mod, 'useNamespaces', moduleName);
|
|
28
28
|
}
|
|
29
29
|
else if(moduleName==='xpath.js'){
|
|
30
|
-
wrappedXPathDotJS(shim, mod);
|
|
30
|
+
wrappedXPathDotJS(shim, mod, moduleName);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
}
|
|
@@ -40,6 +40,7 @@ function initialize(shim, mod, moduleName){
|
|
|
40
40
|
*/
|
|
41
41
|
function xpathHooks(shim, mod, methodName, moduleName){
|
|
42
42
|
shim.wrap(mod, methodName, function makeWrapper(shim,fn){
|
|
43
|
+
logger.debug(`Instrumenting ${moduleName}.${methodName}`);
|
|
43
44
|
return function wrapper(){
|
|
44
45
|
const interceptedArgs = [arguments[0]];
|
|
45
46
|
shim.interceptedArgs = interceptedArgs;
|
|
@@ -67,8 +68,9 @@ function xpathHooks(shim, mod, methodName, moduleName){
|
|
|
67
68
|
* @param {*} shim
|
|
68
69
|
* @param {*} mod
|
|
69
70
|
*/
|
|
70
|
-
function wrappedXPathDotJS(shim, mod){
|
|
71
|
+
function wrappedXPathDotJS(shim, mod, moduleName){
|
|
71
72
|
const wrappedExport = shim.wrapExport(mod, function wrapXpathJSModule(shim, fn) {
|
|
73
|
+
logger.debug(`Instrumenting ${moduleName}`);
|
|
72
74
|
return function wrappedXpathJSModule() {
|
|
73
75
|
const interceptedArgs = [arguments[1]];
|
|
74
76
|
shim.interceptedArgs = interceptedArgs;
|
|
@@ -181,6 +181,15 @@ newrelic.instrumentWebframework({
|
|
|
181
181
|
}
|
|
182
182
|
})
|
|
183
183
|
|
|
184
|
+
newrelic.instrumentWebframework({
|
|
185
|
+
moduleName: '@nestjs/core',
|
|
186
|
+
isEsm: true,
|
|
187
|
+
onRequire: require('./hooks/@nestjs/nr-nestjs-core'),
|
|
188
|
+
onError: function intrumentErrorHandler(err) {
|
|
189
|
+
logger.error(err.message, err.stack)
|
|
190
|
+
}
|
|
191
|
+
})
|
|
192
|
+
|
|
184
193
|
|
|
185
194
|
|
|
186
195
|
|
|
@@ -14,6 +14,9 @@ const agentConfig = require('./resources/config');
|
|
|
14
14
|
const shaSizeUtil = require('./lib/core/sha-size-util');
|
|
15
15
|
const njsAgentConstants = require('./lib/core/sec-agent-constants');
|
|
16
16
|
|
|
17
|
+
const NRLogger = API.newrelic.shim.logger.child({ component: 'security-agent' });
|
|
18
|
+
NRLogger.info("Starting New Relic Node.js Security Agent ");
|
|
19
|
+
|
|
17
20
|
const {
|
|
18
21
|
IS_LAMBDA_ENV,
|
|
19
22
|
AWS_LAMBDA_FUNCTION_NAME_ENV_IDENTIFIER,
|
|
@@ -106,6 +109,7 @@ function initialize() {
|
|
|
106
109
|
initLogger.info("[STEP-3] => Gathering information about the application :", JSON.stringify(applicationInfo));
|
|
107
110
|
if (NRAgent) {
|
|
108
111
|
NRAgent.on('started', () => {
|
|
112
|
+
NRLogger.info("Started New Relic Node.js Security Agent");
|
|
109
113
|
if (NRAgent.config.security.enabled || !NRAgent.config.high_security) {
|
|
110
114
|
wsClient.initialize();
|
|
111
115
|
logger.info('NR Agent started with agent_run_id:', NRAgent.config.run_id, NRAgent.config.account_id);
|
|
@@ -113,7 +117,8 @@ function initialize() {
|
|
|
113
117
|
Agent.setNRAgent(NRAgent);
|
|
114
118
|
}
|
|
115
119
|
else {
|
|
116
|
-
logger.
|
|
120
|
+
logger.warn("security.enabled flag is set to false");
|
|
121
|
+
NRLogger.warn("Failed to Start New Relic Node.js Security Agent. Please check security.enabled and high_security flags");
|
|
117
122
|
}
|
|
118
123
|
});
|
|
119
124
|
}
|
|
@@ -131,9 +136,9 @@ function initialize() {
|
|
|
131
136
|
}
|
|
132
137
|
}
|
|
133
138
|
logger.info(LOG_MESSAGES.AGENT_INFO, applicationInfo.collectorVersion, applicationInfo.jsonVersion, applicationInfo.buildNumber);
|
|
134
|
-
|
|
139
|
+
|
|
135
140
|
applicationInfoModule.addProperty('serverInfo.deployedApplications', applications);
|
|
136
|
-
|
|
141
|
+
|
|
137
142
|
shaSizeUtil.setLogger(logger);
|
|
138
143
|
|
|
139
144
|
// Initialize Agent Status
|
|
@@ -159,7 +164,7 @@ function getProcCMDLineSanitized(applicationInfoModule) {
|
|
|
159
164
|
}
|
|
160
165
|
|
|
161
166
|
(() => {
|
|
162
|
-
if(!NRAgent.config.security.enabled){
|
|
167
|
+
if (!NRAgent.config.security.enabled) {
|
|
163
168
|
logger.warn("security.enabled flag is set to false");
|
|
164
169
|
return;
|
|
165
170
|
}
|
|
@@ -9,6 +9,8 @@ const appInfo = require('./applicationinfo').getInstance();
|
|
|
9
9
|
const logs = require('./logging');
|
|
10
10
|
const logger = logs.getLogger();
|
|
11
11
|
const initLogger = logs.getInitLogger();
|
|
12
|
+
const LinkingMetaData = require('./LinkingMetadata');
|
|
13
|
+
const LogMessage = require('./LogMessage');
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
/* eslint-disable camelcase */
|
|
@@ -20,6 +22,7 @@ function AuthHeaders() {
|
|
|
20
22
|
try {
|
|
21
23
|
const NRAgent = API.getNRAgent();
|
|
22
24
|
authHeaders = {}
|
|
25
|
+
const metadata = LinkingMetaData.getLinkingMetadata();
|
|
23
26
|
authHeaders['NR-CSEC-CONNECTION-TYPE'] = 'LANGUAGE_COLLECTOR';
|
|
24
27
|
authHeaders['NR-AGENT-RUN-TOKEN'] = NRAgent.config.run_id;
|
|
25
28
|
const COLLECTOR_VERSION = appInfo.collectorVersion || '';
|
|
@@ -32,8 +35,12 @@ function AuthHeaders() {
|
|
|
32
35
|
authHeaders['NR-ACCOUNT-ID'] = NRAgent.config.account_id;
|
|
33
36
|
authHeaders['NR-LICENSE-KEY'] = NRAgent ? NRAgent.config.license_key : '';
|
|
34
37
|
authHeaders["NR-CSEC-IAST-DATA-TRANSFER-MODE"] = "PULL";
|
|
38
|
+
authHeaders['NR-CSEC-ENTITY-NAME'] = metadata['entity.name'] ? metadata['entity.name'] : '';
|
|
39
|
+
authHeaders['NR-CSEC-ENTITY-GUID'] = metadata['entity.guid'] ? metadata['entity.guid'] : '';
|
|
35
40
|
} catch (error) {
|
|
36
41
|
logger.error("Exception in preparing auth headers:", error);
|
|
42
|
+
const logMessage = new LogMessage.logMessage("SEVERE", 'Exception in preparing auth headers', __filename, error);
|
|
43
|
+
commonUtils.addLogEventtoBuffer(logMessage);
|
|
37
44
|
}
|
|
38
45
|
|
|
39
46
|
return authHeaders;
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
const LinkingMetaData = require('./LinkingMetadata');
|
|
7
7
|
const API = require('../../../nr-security-api');
|
|
8
8
|
const NRAgent = API.getNRAgent();
|
|
9
|
+
const { BasicInfo } = require('./event');
|
|
10
|
+
const applicationInfo = require('./applicationinfo').getInstance();
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* constructor function to create LogMessageException object
|
|
@@ -13,10 +15,22 @@ const NRAgent = API.getNRAgent();
|
|
|
13
15
|
* @param {*} cause
|
|
14
16
|
* @param {*} stacktrace
|
|
15
17
|
*/
|
|
16
|
-
function logMessageException
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
function logMessageException(exception) {
|
|
19
|
+
let exceptionObject = {};
|
|
20
|
+
try {
|
|
21
|
+
exceptionObject.message = exception.message ? exception.message : '';
|
|
22
|
+
exceptionObject.cause = exception.cause ? exception.cause : '';
|
|
23
|
+
if (exception.stack) {
|
|
24
|
+
let stacktraceInList = exception.stack.split('\n');
|
|
25
|
+
stacktraceInList = stacktraceInList.slice(1);
|
|
26
|
+
exceptionObject.stacktrace = stacktraceInList;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
} catch (error) {
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return exceptionObject;
|
|
20
34
|
}
|
|
21
35
|
|
|
22
36
|
/**
|
|
@@ -28,17 +42,28 @@ function logMessageException (exception) {
|
|
|
28
42
|
* @param {*} exception
|
|
29
43
|
* @param {*} linkingMetadata
|
|
30
44
|
*/
|
|
31
|
-
function logMessage
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
this.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
this.
|
|
45
|
+
function logMessage(level, message, caller, exception) {
|
|
46
|
+
try {
|
|
47
|
+
BasicInfo.call(this);
|
|
48
|
+
this.jsonVersion = applicationInfo.jsonVersion;
|
|
49
|
+
this.jsonName = 'log-message';
|
|
50
|
+
this.applicationUUID = applicationInfo.applicationUUID;
|
|
51
|
+
this.groupName = applicationInfo.groupName;
|
|
52
|
+
this.policyVersion = applicationInfo.policyVersion;
|
|
53
|
+
this.timestamp = Date.now();
|
|
54
|
+
this.level = level ? level : 'SEVERE';
|
|
55
|
+
this.message = message;
|
|
56
|
+
this.caller = caller;
|
|
57
|
+
if (exception) {
|
|
58
|
+
this.exception = logMessageException(exception);
|
|
59
|
+
}
|
|
60
|
+
if (NRAgent) {
|
|
61
|
+
this.linkingMetadata = LinkingMetaData.getLinkingMetadata();
|
|
62
|
+
}
|
|
63
|
+
} catch (error) {
|
|
64
|
+
|
|
41
65
|
}
|
|
66
|
+
|
|
42
67
|
}
|
|
43
68
|
|
|
44
69
|
module.exports = {
|
|
@@ -589,7 +589,7 @@ function setPodProperties (identifier, containerProp) {
|
|
|
589
589
|
podProp.namespace = getPodNameSpace();
|
|
590
590
|
podProp.name = getHostName();
|
|
591
591
|
podProp.creationTimestamp = new Date().getTime();
|
|
592
|
-
podProp.
|
|
592
|
+
podProp.containerProperties.push(containerProp);
|
|
593
593
|
logger.debug("podProp:", podProp);
|
|
594
594
|
} catch (e) {
|
|
595
595
|
logger.error(e);
|
|
@@ -12,16 +12,18 @@ const OS = require('os');
|
|
|
12
12
|
const path = require('path');
|
|
13
13
|
const checkDiskSpace = require('check-disk-space').default;
|
|
14
14
|
const AgentStatus = require('../core/agent-status');
|
|
15
|
-
const {
|
|
15
|
+
const { CSEC_HOME, SLASH } = require('./sec-agent-constants');
|
|
16
16
|
|
|
17
|
-
const prettyBytes = require('pretty-bytes');
|
|
18
17
|
const njsAgentConstants = require('./sec-agent-constants');
|
|
19
|
-
const LinkingMetaData = require('./LinkingMetadata');
|
|
20
18
|
const API = require('../../../nr-security-api');
|
|
21
19
|
const NRAgent = API.getNRAgent();
|
|
22
20
|
const lodash = require('lodash')
|
|
23
21
|
const backupLogFileRegex = /.log.\d/gm;
|
|
24
22
|
let websocketHealth;
|
|
23
|
+
|
|
24
|
+
const ringBuffer = require('ringbufferjs');
|
|
25
|
+
const bufferedLogEvents = new ringBuffer(10);
|
|
26
|
+
|
|
25
27
|
/**
|
|
26
28
|
* Utility to generate UUID
|
|
27
29
|
* @returns UUID
|
|
@@ -417,6 +419,26 @@ function getWSHealthStatus() {
|
|
|
417
419
|
}
|
|
418
420
|
}
|
|
419
421
|
|
|
422
|
+
/**
|
|
423
|
+
* return buffered Log Event instance.
|
|
424
|
+
*/
|
|
425
|
+
function getLogEvents() {
|
|
426
|
+
return bufferedLogEvents;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Utility to add error object in error buffer
|
|
432
|
+
* @param {*} error
|
|
433
|
+
*/
|
|
434
|
+
function addLogEventtoBuffer(logMessage) {
|
|
435
|
+
try {
|
|
436
|
+
bufferedLogEvents.enq(logMessage);
|
|
437
|
+
} catch (error) {
|
|
438
|
+
logger.debug(error);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
420
442
|
module.exports = {
|
|
421
443
|
getUUID,
|
|
422
444
|
getKindIdPair,
|
|
@@ -438,5 +460,7 @@ module.exports = {
|
|
|
438
460
|
getCSECmode,
|
|
439
461
|
getPathOfCACert,
|
|
440
462
|
getWSHealthStatus,
|
|
441
|
-
setWSHealthStatus
|
|
463
|
+
setWSHealthStatus,
|
|
464
|
+
addLogEventtoBuffer,
|
|
465
|
+
getLogEvents
|
|
442
466
|
};
|
package/lib/nr-security-agent/lib/core/connections/websocket/response/fuzz-request-handler.js
CHANGED
|
@@ -9,14 +9,16 @@ const stringify = require('fast-safe-stringify');
|
|
|
9
9
|
const restClient = require('../../restclient');
|
|
10
10
|
const { Agent } = require('../../../agent');
|
|
11
11
|
const { FuzzFailEvent } = require('../../../FuzzFailEvent');
|
|
12
|
-
const { CSEC_HOME_TMP, COLON, NR_CSEC_FUZZ_REQUEST_ID, SLASH, CSEC_SEP } = require('../../../sec-agent-constants');
|
|
12
|
+
const { CSEC_HOME_TMP, COLON, NR_CSEC_FUZZ_REQUEST_ID, SLASH, CSEC_SEP, SEVERE } = require('../../../sec-agent-constants');
|
|
13
13
|
const LOCALHOST = 'localhost';
|
|
14
14
|
const COLON_SLASH_SLASH = '://';
|
|
15
15
|
const http = require('http');
|
|
16
16
|
const https = require('https');
|
|
17
17
|
const IASTUtil = require('./IASTUtils');
|
|
18
|
+
const LogMessage = require('../../../LogMessage');
|
|
18
19
|
|
|
19
20
|
require('dns').setDefaultResultOrder('ipv4first')
|
|
21
|
+
const PolicyManager = require('../../../Policy');
|
|
20
22
|
|
|
21
23
|
const {
|
|
22
24
|
IS_LAMBDA_ENV,
|
|
@@ -42,6 +44,16 @@ function startIASTSchedular() {
|
|
|
42
44
|
if (iastIntervalConst) {
|
|
43
45
|
clearInterval(iastIntervalConst);
|
|
44
46
|
}
|
|
47
|
+
let probingInterval = 5;
|
|
48
|
+
|
|
49
|
+
const policyInstance = PolicyManager.getInstance();
|
|
50
|
+
if (policyInstance.data) {
|
|
51
|
+
probingInterval = policyInstance.data.vulnerabilityScan.iastScan.probing.interval;
|
|
52
|
+
}
|
|
53
|
+
if (isNaN(probingInterval)) {
|
|
54
|
+
probingInterval = 5;
|
|
55
|
+
}
|
|
56
|
+
|
|
45
57
|
iastIntervalConst = setInterval(() => {
|
|
46
58
|
let data = IASTUtil.generateIASTDataRequest();
|
|
47
59
|
let currentTime = Date.now();
|
|
@@ -55,7 +67,7 @@ function startIASTSchedular() {
|
|
|
55
67
|
if (timeDiffInSeconds > 5 && additionalCoolDownTime == 0) {
|
|
56
68
|
Agent.getAgent().client.dispatcher(data);
|
|
57
69
|
}
|
|
58
|
-
},
|
|
70
|
+
}, probingInterval * 1000);
|
|
59
71
|
}
|
|
60
72
|
|
|
61
73
|
/**
|
|
@@ -65,7 +77,7 @@ function startIASTSchedular() {
|
|
|
65
77
|
function logScannedApiId(fuzzHeader, requestURL) {
|
|
66
78
|
try {
|
|
67
79
|
let apiId = fuzzHeader.split(CSEC_SEP)[0]
|
|
68
|
-
if (apiId && !fuzzedApiIDSet.has(apiId)
|
|
80
|
+
if (apiId && !fuzzedApiIDSet.has(apiId)) {
|
|
69
81
|
fuzzedApiIDSet.add(apiId);
|
|
70
82
|
logger.info("IAST Scan for API %s with ID : %s started.", requestURL, apiId);
|
|
71
83
|
}
|
|
@@ -87,6 +99,9 @@ function handler(json) {
|
|
|
87
99
|
IASTUtil.addPendingRequestId(json.id);
|
|
88
100
|
} catch (error) {
|
|
89
101
|
logger.error('Parsing exeception in fuzz request: ', error);
|
|
102
|
+
|
|
103
|
+
const logMessage = new LogMessage.logMessage(SEVERE, 'Parsing exeception in fuzz request', __filename, error);
|
|
104
|
+
commonUtils.addLogEventtoBuffer(logMessage);
|
|
90
105
|
}
|
|
91
106
|
if (!fuzzRequest) {
|
|
92
107
|
return;
|
|
@@ -132,10 +147,10 @@ function handleFuzzRequest(fuzzDetails) {
|
|
|
132
147
|
|
|
133
148
|
IASTUtil.completedRequestsMapInit(fuzzRequest.id);
|
|
134
149
|
|
|
135
|
-
if(fuzzRequest.headers && fuzzRequest.headers[NR_CSEC_FUZZ_REQUEST_ID]){
|
|
150
|
+
if (fuzzRequest.headers && fuzzRequest.headers[NR_CSEC_FUZZ_REQUEST_ID]) {
|
|
136
151
|
logScannedApiId(fuzzRequest.headers[NR_CSEC_FUZZ_REQUEST_ID], fuzzRequest.requestURI)
|
|
137
152
|
}
|
|
138
|
-
|
|
153
|
+
|
|
139
154
|
|
|
140
155
|
logger.info('Firing http request:: URL: ' + config.url);
|
|
141
156
|
|
|
@@ -181,7 +196,7 @@ function handleFuzzResponse(response, fuzzDetails) {
|
|
|
181
196
|
function parseAxiosHttpRequestToFuzz(requestObject) {
|
|
182
197
|
let serverName = requestObject.serverName ? requestObject.serverName : LOCALHOST;
|
|
183
198
|
let host = serverName + COLON + requestObject.serverPort;
|
|
184
|
-
if(requestObject.headers && requestObject.headers['content-length']){
|
|
199
|
+
if (requestObject.headers && requestObject.headers['content-length']) {
|
|
185
200
|
delete requestObject.headers['content-length'];
|
|
186
201
|
}
|
|
187
202
|
return {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
const _ = require('lodash');
|
|
7
7
|
|
|
8
|
-
const { SERVER_COMMAND } = require('../../../sec-agent-constants');
|
|
8
|
+
const { SERVER_COMMAND, SEVERE } = require('../../../sec-agent-constants');
|
|
9
9
|
const UnsupportedAgentHandler = require('./unsupported-agent-handler');
|
|
10
10
|
const StartupHandshakeHandler = require('./startup-handshake-handler');
|
|
11
11
|
const FuzzRequestHandler = require('./fuzz-request-handler');
|
|
@@ -17,6 +17,7 @@ const coolDown = require('./iast-cool-down');
|
|
|
17
17
|
const recordDeletion = require('./iast-record-deletion');
|
|
18
18
|
const logs = require('../../../logging');
|
|
19
19
|
let logger = logs.getLogger();
|
|
20
|
+
const LogMessage = require('../../../LogMessage');
|
|
20
21
|
|
|
21
22
|
const commandHandlerMap = {
|
|
22
23
|
[SERVER_COMMAND.STARTUP_WELCOME_MSG]: StartupHandshakeHandler,
|
|
@@ -38,7 +39,9 @@ const handle = function handle (json) {
|
|
|
38
39
|
NoOpHandler.handler.call(this, json);
|
|
39
40
|
}
|
|
40
41
|
} catch (error) {
|
|
41
|
-
logger.error("Error in handling Control
|
|
42
|
+
logger.error("Error in handling Control Command",error);
|
|
43
|
+
const logMessage = new LogMessage.logMessage(SEVERE, 'Error in handling Control Command', __filename, error);
|
|
44
|
+
commonUtils.addLogEventtoBuffer(logMessage);
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
};
|
|
@@ -17,10 +17,11 @@ const hc = require('../../health-check');
|
|
|
17
17
|
const fs = require('fs');
|
|
18
18
|
const { promisify } = require('../../sec-util');
|
|
19
19
|
const ResponseHandler = require('./response');
|
|
20
|
-
const { EMPTY_APPLICATION_UUID, LOG_MESSAGES, CSEC_SEP, NR_CSEC_FUZZ_REQUEST_ID, EXITEVENT, JSON_NAME, RASP } = require('../../sec-agent-constants');
|
|
20
|
+
const { EMPTY_APPLICATION_UUID, LOG_MESSAGES, CSEC_SEP, NR_CSEC_FUZZ_REQUEST_ID, EXITEVENT, JSON_NAME, RASP, SEVERE } = require('../../sec-agent-constants');
|
|
21
21
|
const statusUtils = require('../../statusUtils');
|
|
22
22
|
const commonUtils = require('../../commonUtils');
|
|
23
23
|
const IASTUtil = require('../websocket/response/IASTUtils');
|
|
24
|
+
const LogMessage = require('../../LogMessage');
|
|
24
25
|
|
|
25
26
|
const BUSY = 'busy';
|
|
26
27
|
const IDLE = 'idle';
|
|
@@ -109,9 +110,12 @@ SecWebSocket.prototype.init = function init() {
|
|
|
109
110
|
cert = fs.readFileSync(certPath, 'utf8');
|
|
110
111
|
} catch (error) {
|
|
111
112
|
logger.error("Error in reading certificate:", error);
|
|
113
|
+
const logMessage = new LogMessage.logMessage(SEVERE, 'Error in reading certificate for websocket', __filename, error);
|
|
114
|
+
commonUtils.addLogEventtoBuffer(logMessage);
|
|
115
|
+
|
|
112
116
|
}
|
|
113
117
|
|
|
114
|
-
webSocket = new WebSocket(validatorService,
|
|
118
|
+
webSocket = new WebSocket(validatorService, { headers: authHeaders, cert: cert, handshakeTimeout: 10000 });
|
|
115
119
|
|
|
116
120
|
webSocket.on(WS_ON_OPEN, this.openCB);
|
|
117
121
|
webSocket.on(WS_ON_MSG, this.msgCB);
|
|
@@ -120,6 +124,17 @@ SecWebSocket.prototype.init = function init() {
|
|
|
120
124
|
lastPongtime = Date.now();
|
|
121
125
|
commonUtils.setWSHealthStatus('OK');
|
|
122
126
|
logger.debug("Pong received from Validator");
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
let logBuffer = commonUtils.getLogEvents();
|
|
130
|
+
while (logBuffer.size() > 0) {
|
|
131
|
+
let logEvent = logBuffer.deq();
|
|
132
|
+
this.dispatch(logEvent);
|
|
133
|
+
}
|
|
134
|
+
} catch (error) {
|
|
135
|
+
logger.error("Error while sending log events", error);
|
|
136
|
+
}
|
|
137
|
+
|
|
123
138
|
})
|
|
124
139
|
webSocket.on('close', () => {
|
|
125
140
|
logger.warn("WS connection closed");
|
|
@@ -172,6 +187,7 @@ SecWebSocket.prototype.obeyReconnect = function obeyReconnect() {
|
|
|
172
187
|
SecWebSocket.prototype.pingWS = async function pingWS() {
|
|
173
188
|
const self = this;
|
|
174
189
|
let currentTime = Date.now();
|
|
190
|
+
|
|
175
191
|
let timeDiffInPing = (currentTime - lastPongtime) / 1000;
|
|
176
192
|
if (timeDiffInPing > 40 && lastPongtime != 0) {
|
|
177
193
|
self.obeyReconnect();
|
|
@@ -193,6 +209,7 @@ SecWebSocket.prototype.pingWS = async function pingWS() {
|
|
|
193
209
|
commonUtils.setWSHealthStatus('Error');
|
|
194
210
|
return;
|
|
195
211
|
}
|
|
212
|
+
|
|
196
213
|
}
|
|
197
214
|
|
|
198
215
|
/**
|
|
@@ -412,6 +429,8 @@ const defaultOnErrCB = () => function onClose(error) {
|
|
|
412
429
|
statusUtils.addErrortoBuffer(error);
|
|
413
430
|
const self = this;
|
|
414
431
|
logger.error("Error while connecting to validator:", error.message)
|
|
432
|
+
const logMessage = new LogMessage.logMessage(SEVERE, 'Error while connecting to validator', __filename, error);
|
|
433
|
+
commonUtils.addLogEventtoBuffer(logMessage);
|
|
415
434
|
logger.warn("Security Agent INACTIVE!!!")
|
|
416
435
|
if (error && error.code && (error.code === 'ECONNREFUSED' || error.code === 'EPIPE' || error.code === 'ECONNRESET')) {
|
|
417
436
|
logger.debug("WS Client Error callback called:", error);
|
|
@@ -108,6 +108,9 @@ module.exports = {
|
|
|
108
108
|
CSEC_SEP: ':IAST:',
|
|
109
109
|
RASP: 'RASP',
|
|
110
110
|
IAST: 'IAST',
|
|
111
|
+
SEVERE: 'SEVERE',
|
|
112
|
+
HIGH: 'HIGH',
|
|
113
|
+
CRITICAL: 'CRITICAL',
|
|
111
114
|
|
|
112
115
|
LOG_MESSAGES: {
|
|
113
116
|
LOADED_CSEC_ENVS_MSG: '[STEP-1][COMPLETE][env] Environment Information Gathering Done.',
|
|
@@ -9,10 +9,12 @@ const { SecEvent } = require('./event');
|
|
|
9
9
|
const logs = require('./logging');
|
|
10
10
|
const { Agent } = require('./agent');
|
|
11
11
|
const shaUtil = require('./sha-size-util');
|
|
12
|
-
const { LOG_MESSAGES, NR_CSEC_FUZZ_REQUEST_ID, COLON, VULNERABLE, EXITEVENT, EMPTY_STR, RASP } = require('./sec-agent-constants');
|
|
12
|
+
const { LOG_MESSAGES, NR_CSEC_FUZZ_REQUEST_ID, COLON, VULNERABLE, EXITEVENT, EMPTY_STR, RASP, SEVERE } = require('./sec-agent-constants');
|
|
13
13
|
const API = require('../../../nr-security-api');
|
|
14
14
|
const NRAgent = API.getNRAgent();
|
|
15
15
|
const HC = require('./health-check');
|
|
16
|
+
const LogMessage = require('./LogMessage');
|
|
17
|
+
const commonUtils = require('./commonUtils');
|
|
16
18
|
|
|
17
19
|
const statusUtils = require('./statusUtils');
|
|
18
20
|
|
|
@@ -67,10 +69,10 @@ function generateSecEvent(securityMetadata) {
|
|
|
67
69
|
const traceObject = securityMetadata.traceObject;
|
|
68
70
|
const request = securityMetadata.request;
|
|
69
71
|
|
|
70
|
-
if(request && request.headers[NR_CSEC_FUZZ_REQUEST_ID]){
|
|
72
|
+
if (request && request.headers[NR_CSEC_FUZZ_REQUEST_ID]) {
|
|
71
73
|
HC.getInstance().iastEventStats.processed++;
|
|
72
74
|
}
|
|
73
|
-
else{
|
|
75
|
+
else {
|
|
74
76
|
HC.getInstance().raspEventStats.processed++;
|
|
75
77
|
}
|
|
76
78
|
try {
|
|
@@ -102,11 +104,14 @@ function generateSecEvent(securityMetadata) {
|
|
|
102
104
|
} catch (e) {
|
|
103
105
|
statusUtils.addErrortoBuffer(e);
|
|
104
106
|
logger.error("Error in generating event:", e);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
+
|
|
108
|
+
const logMessage = new LogMessage.logMessage(SEVERE, 'Error while generating event', __filename, e);
|
|
109
|
+
commonUtils.addLogEventtoBuffer(logMessage);
|
|
110
|
+
|
|
111
|
+
if (request && request.headers[NR_CSEC_FUZZ_REQUEST_ID]) {
|
|
107
112
|
HC.getInstance().iastEventStats.errorCount++;
|
|
108
113
|
}
|
|
109
|
-
else{
|
|
114
|
+
else {
|
|
110
115
|
HC.getInstance().raspEventStats.errorCount++;
|
|
111
116
|
}
|
|
112
117
|
}
|
|
@@ -141,6 +146,9 @@ function generateExitEvent(secEvent) {
|
|
|
141
146
|
}
|
|
142
147
|
} catch (error) {
|
|
143
148
|
logger.error('Error in generating exit event', error);
|
|
149
|
+
|
|
150
|
+
const logMessage = new LogMessage.logMessage(SEVERE, 'Error in generating exit event', __filename, error);
|
|
151
|
+
commonUtils.addLogEventtoBuffer(logMessage);
|
|
144
152
|
HC.getInstance().exitEventStats.errorCount++;
|
|
145
153
|
}
|
|
146
154
|
}
|
|
@@ -140,17 +140,18 @@ const sendHC = async function () {
|
|
|
140
140
|
* @param {JSON} eventJson
|
|
141
141
|
*/
|
|
142
142
|
function getDispatcherAndSendEvent(eventJson) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
143
|
+
if (eventJson) {
|
|
144
|
+
const eventType = eventJson.jsonName;
|
|
145
|
+
if (eventType === JSON_NAME.EVENT || eventType === EXITEVENT) {
|
|
146
|
+
hc.getInstance().registerEventProcessed();
|
|
147
|
+
}
|
|
147
148
|
|
|
148
|
-
|
|
149
|
+
dispatcher(eventJson);
|
|
149
150
|
|
|
150
|
-
|
|
151
|
-
|
|
151
|
+
if (eventType === JSON_NAME.EVENT || eventType === EXITEVENT) {
|
|
152
|
+
hc.getInstance().registerEventSent();
|
|
153
|
+
}
|
|
152
154
|
}
|
|
153
|
-
|
|
154
155
|
}
|
|
155
156
|
|
|
156
157
|
/**
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@newrelic/security-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "New Relic Security Agent for Node.js",
|
|
5
5
|
"main": "index.js",
|
|
6
|
-
"jsonVersion": "1.1.
|
|
6
|
+
"jsonVersion": "1.1.1",
|
|
7
7
|
"contributors": [
|
|
8
8
|
{
|
|
9
9
|
"name": "Sumit Suthar",
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"url": "https://github.com/newrelic/csec-node-agent.git"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@aws-sdk/client-lambda": "^3.
|
|
39
|
-
"axios": "1.6.
|
|
40
|
-
"check-disk-space": "3.
|
|
38
|
+
"@aws-sdk/client-lambda": "^3.436.0",
|
|
39
|
+
"axios": "^1.6.3",
|
|
40
|
+
"check-disk-space": "^3.4.0",
|
|
41
41
|
"content-type": "^1.0.5",
|
|
42
42
|
"fast-safe-stringify": "^2.1.1",
|
|
43
43
|
"find-package-json": "^1.2.0",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"unescape": "^1.0.1",
|
|
57
57
|
"unescape-js": "^1.1.4",
|
|
58
58
|
"uuid": "^9.0.1",
|
|
59
|
-
"ws": "^
|
|
59
|
+
"ws": "^8.14.2"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@hapi/hapi": "^21.3.0",
|