@newrelic/security-agent 0.0.1
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 +0 -0
- package/CONTRIBUTING.md +23 -0
- package/LICENSE +43 -0
- package/README.md +98 -0
- package/THIRD_PARTY_NOTICES.md +2909 -0
- package/index.js +24 -0
- package/lib/instrumentation-security/core/constants.js +66 -0
- package/lib/instrumentation-security/core/event-constants.js +49 -0
- package/lib/instrumentation-security/core/request-manager.js +73 -0
- package/lib/instrumentation-security/core/route-manager.js +30 -0
- package/lib/instrumentation-security/core/sec-trace.js +134 -0
- package/lib/instrumentation-security/core/sec-utils.js +212 -0
- package/lib/instrumentation-security/core/security-metadata.js +34 -0
- package/lib/instrumentation-security/core/stack-trace.js +156 -0
- package/lib/instrumentation-security/hooks/director/nr-director.js +98 -0
- package/lib/instrumentation-security/hooks/express/nr-express.js +106 -0
- package/lib/instrumentation-security/hooks/fastify/nr-fastify.js +155 -0
- package/lib/instrumentation-security/hooks/fs/nr-fs.js +391 -0
- package/lib/instrumentation-security/hooks/hapi/nr-hapi.js +131 -0
- package/lib/instrumentation-security/hooks/http/nr-http.js +461 -0
- package/lib/instrumentation-security/hooks/koa/@koa/nr-@koa-router.js +110 -0
- package/lib/instrumentation-security/hooks/ldap/nr-ldap.js +81 -0
- package/lib/instrumentation-security/hooks/mongodb/common.js +239 -0
- package/lib/instrumentation-security/hooks/mongodb/constants.js +91 -0
- package/lib/instrumentation-security/hooks/mongodb/nr-mongodb.js +49 -0
- package/lib/instrumentation-security/hooks/mongodb/v2-mongo.js +91 -0
- package/lib/instrumentation-security/hooks/mongodb/v3-mongo.js +36 -0
- package/lib/instrumentation-security/hooks/mongodb/v4-mongo.js +17 -0
- package/lib/instrumentation-security/hooks/mysql/nr-mysql.js +232 -0
- package/lib/instrumentation-security/hooks/native/nr-childProcess.js +131 -0
- package/lib/instrumentation-security/hooks/postgres/nr-postgres.js +131 -0
- package/lib/instrumentation-security/hooks/require/nr-require.js +93 -0
- package/lib/instrumentation-security/hooks/restify/nr-restify.js +104 -0
- package/lib/instrumentation-security/hooks/xpath/nr-xpath.js +91 -0
- package/lib/instrumentation-security/index.js +171 -0
- package/lib/nr-security-agent/index.js +170 -0
- package/lib/nr-security-agent/lib/core/Auth-headers.js +58 -0
- package/lib/nr-security-agent/lib/core/ContainerProperties.js +42 -0
- package/lib/nr-security-agent/lib/core/ECSProperties.js +34 -0
- package/lib/nr-security-agent/lib/core/FuzzFailEvent.js +27 -0
- package/lib/nr-security-agent/lib/core/LinkingMetadata.js +21 -0
- package/lib/nr-security-agent/lib/core/LogMessage.js +47 -0
- package/lib/nr-security-agent/lib/core/PodProperties.js +36 -0
- package/lib/nr-security-agent/lib/core/Policy.js +105 -0
- package/lib/nr-security-agent/lib/core/agent-status.js +56 -0
- package/lib/nr-security-agent/lib/core/agent.js +146 -0
- package/lib/nr-security-agent/lib/core/applicationinfo.js +634 -0
- package/lib/nr-security-agent/lib/core/commonUtils.js +411 -0
- package/lib/nr-security-agent/lib/core/connections/aws-lambda-client.js +55 -0
- package/lib/nr-security-agent/lib/core/connections/restclient.js +20 -0
- package/lib/nr-security-agent/lib/core/connections/websocket/index.js +25 -0
- package/lib/nr-security-agent/lib/core/connections/websocket/response/collecotor-policy-error-handler.js +18 -0
- package/lib/nr-security-agent/lib/core/connections/websocket/response/collector-policy-handler.js +20 -0
- package/lib/nr-security-agent/lib/core/connections/websocket/response/fuzz-request-handler.js +171 -0
- package/lib/nr-security-agent/lib/core/connections/websocket/response/index.js +47 -0
- package/lib/nr-security-agent/lib/core/connections/websocket/response/no-op-handler.js +12 -0
- package/lib/nr-security-agent/lib/core/connections/websocket/response/startup-handshake-handler.js +27 -0
- package/lib/nr-security-agent/lib/core/connections/websocket/response/unsupported-agent-handler.js +18 -0
- package/lib/nr-security-agent/lib/core/connections/websocket/response/ws-reconnect.js +14 -0
- package/lib/nr-security-agent/lib/core/connections/websocket/websocket.js +443 -0
- package/lib/nr-security-agent/lib/core/event.js +186 -0
- package/lib/nr-security-agent/lib/core/health-check.js +159 -0
- package/lib/nr-security-agent/lib/core/json-file-handler.js +66 -0
- package/lib/nr-security-agent/lib/core/jsonValidator.js +149 -0
- package/lib/nr-security-agent/lib/core/lambda-delegated-task-service.js +90 -0
- package/lib/nr-security-agent/lib/core/logging.js +176 -0
- package/lib/nr-security-agent/lib/core/sec-agent-constants.js +173 -0
- package/lib/nr-security-agent/lib/core/sec-util.js +166 -0
- package/lib/nr-security-agent/lib/core/sha-size-util.js +338 -0
- package/lib/nr-security-agent/lib/core/sha_worker.js +24 -0
- package/lib/nr-security-agent/lib/core/startup-config.js +29 -0
- package/lib/nr-security-agent/lib/core/statusUtils.js +157 -0
- package/lib/nr-security-agent/lib/core/timeunit.js +44 -0
- package/lib/nr-security-agent/lib/core/websocket-client.js +335 -0
- package/lib/nr-security-agent/lib/core/worker-entities.js +82 -0
- package/lib/nr-security-agent/lib/core/worker.js +148 -0
- package/lib/nr-security-agent/lib/core/xss-utils.js +297 -0
- package/lib/nr-security-agent/lib/models/lambda-delegated-task/constants.js +12 -0
- package/lib/nr-security-agent/lib/models/lambda-delegated-task/index.js +15 -0
- package/lib/nr-security-agent/lib/models/lambda-delegated-task/lambda-delegated-sha-calculation.js +37 -0
- package/lib/nr-security-agent/lib/models/lambda-delegated-task/lambda-delegated-task-base.js +50 -0
- package/lib/nr-security-agent/lib/models/lambda-delegated-task/lambda-delegated-task-type.js +17 -0
- package/lib/nr-security-agent/resources/cert.pem +31 -0
- package/lib/nr-security-agent/resources/config.js +19 -0
- package/lib/nr-security-agent/resources/default-policy.yaml +36 -0
- package/lib/nr-security-api/index.js +111 -0
- package/package.json +95 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
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 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
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Entry point for xpath module hook
|
|
17
|
+
* @param {*} shim
|
|
18
|
+
* @param {*} mod
|
|
19
|
+
* @param {*} moduleName
|
|
20
|
+
*/
|
|
21
|
+
function initialize(shim, mod, moduleName){
|
|
22
|
+
logger.info('Instrumenting '+ moduleName)
|
|
23
|
+
|
|
24
|
+
if(moduleName==='xpath'){
|
|
25
|
+
xpathHooks(shim, mod, 'evaluate', moduleName);
|
|
26
|
+
xpathHooks(shim, mod, 'selectWithResolver', moduleName);
|
|
27
|
+
xpathHooks(shim, mod, 'useNamespaces', moduleName);
|
|
28
|
+
}
|
|
29
|
+
else if(moduleName==='xpath.js'){
|
|
30
|
+
wrappedXPathDotJS(shim, mod);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* wrapper to hook xpath module
|
|
36
|
+
* @param {*} shim
|
|
37
|
+
* @param {*} mod
|
|
38
|
+
* @param {*} methodName
|
|
39
|
+
* @param {*} moduleName
|
|
40
|
+
*/
|
|
41
|
+
function xpathHooks(shim, mod, methodName, moduleName){
|
|
42
|
+
shim.wrap(mod, methodName, function makeWrapper(shim,fn){
|
|
43
|
+
return function wrapper(){
|
|
44
|
+
const interceptedArgs = [arguments[0]];
|
|
45
|
+
shim.interceptedArgs = interceptedArgs;
|
|
46
|
+
const request = requestManager.getRequest(shim);
|
|
47
|
+
if(request){
|
|
48
|
+
const traceObject = secUtils.getTraceObject(shim);
|
|
49
|
+
const secMetadata = securityMetaData.getSecurityMetaData(request, interceptedArgs, traceObject, secUtils.getExecutionId(), EVENT_TYPE.XPATH, EVENT_CATEGORY.XPATH)
|
|
50
|
+
const secEvent = API.generateSecEvent(secMetadata);
|
|
51
|
+
this.secEvent = secEvent;
|
|
52
|
+
API.sendEvent(this.secEvent);
|
|
53
|
+
}
|
|
54
|
+
const result = fn.apply(this, arguments);
|
|
55
|
+
|
|
56
|
+
if(result && request && request.headers[NR_CSEC_FUZZ_REQUEST_ID]){
|
|
57
|
+
API.generateExitEvent(this.secEvent);
|
|
58
|
+
delete this.secEvent
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Function Wrapper for xpath.js module
|
|
67
|
+
* @param {*} shim
|
|
68
|
+
* @param {*} mod
|
|
69
|
+
*/
|
|
70
|
+
function wrappedXPathDotJS(shim, mod){
|
|
71
|
+
const wrappedExport = shim.wrapExport(mod, function wrapXpathJSModule(shim, fn) {
|
|
72
|
+
return function wrappedXpathJSModule() {
|
|
73
|
+
const interceptedArgs = [arguments[1]];
|
|
74
|
+
shim.interceptedArgs = interceptedArgs;
|
|
75
|
+
const request = requestManager.getRequest(shim);
|
|
76
|
+
if(request){
|
|
77
|
+
const traceObject = secUtils.getTraceObject(shim);
|
|
78
|
+
const secMetadata = securityMetaData.getSecurityMetaData(request, interceptedArgs, traceObject, secUtils.getExecutionId(), EVENT_TYPE.XPATH, EVENT_CATEGORY.XPATH)
|
|
79
|
+
const secEvent = API.generateSecEvent(secMetadata);
|
|
80
|
+
this.secEvent = secEvent;
|
|
81
|
+
API.sendEvent(this.secEvent);
|
|
82
|
+
}
|
|
83
|
+
const xpathJSForWrapping = fn.apply(this, arguments);
|
|
84
|
+
if(xpathJSForWrapping && request && request.headers[NR_CSEC_FUZZ_REQUEST_ID]){
|
|
85
|
+
API.generateExitEvent(this.secEvent);
|
|
86
|
+
delete this.secEvent
|
|
87
|
+
}
|
|
88
|
+
return xpathJSForWrapping
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const API = require('../nr-security-api');
|
|
7
|
+
const newrelic = API.newrelic;
|
|
8
|
+
const logger = API.getLogger();
|
|
9
|
+
|
|
10
|
+
logger.info("Started instrumentation using shimmer module");
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
newrelic.instrument({
|
|
14
|
+
moduleName: 'child_process',
|
|
15
|
+
onRequire: require('./hooks/native/nr-childProcess'),
|
|
16
|
+
onError: function intrumentErrorHandler(err) {
|
|
17
|
+
logger.error(err.message, err.stack)
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
newrelic.instrument({
|
|
21
|
+
moduleName: 'http',
|
|
22
|
+
onRequire: require('./hooks/http/nr-http'),
|
|
23
|
+
onError: function intrumentErrorHandler(err) {
|
|
24
|
+
logger.error(err.message, err.stack)
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
newrelic.instrument({
|
|
29
|
+
moduleName: 'https',
|
|
30
|
+
onRequire: require('./hooks/http/nr-http'),
|
|
31
|
+
onError: function intrumentErrorHandler(err) {
|
|
32
|
+
logger.error(err.message, err.stack)
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
newrelic.instrument({
|
|
37
|
+
moduleName: 'fs',
|
|
38
|
+
onRequire: require('./hooks/fs/nr-fs'),
|
|
39
|
+
onError: function intrumentErrorHandler(err) {
|
|
40
|
+
logger.error(err.message, err.stack)
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
newrelic.instrumentWebframework({
|
|
45
|
+
moduleName: 'express',
|
|
46
|
+
onRequire: require('./hooks/express/nr-express'),
|
|
47
|
+
onError: function intrumentErrorHandler(err) {
|
|
48
|
+
logger.error(err.message, err.stack)
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
newrelic.instrumentDatastore({
|
|
53
|
+
moduleName: 'mysql',
|
|
54
|
+
onRequire: require('./hooks/mysql/nr-mysql'),
|
|
55
|
+
onError: function intrumentErrorHandler(err) {
|
|
56
|
+
logger.error(err.message, err.stack)
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
newrelic.instrumentDatastore({
|
|
61
|
+
moduleName: 'mysql2',
|
|
62
|
+
onRequire: require('./hooks/mysql/nr-mysql'),
|
|
63
|
+
onError: function intrumentErrorHandler(err) {
|
|
64
|
+
logger.error(err.message, err.stack)
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
newrelic.instrumentDatastore({
|
|
69
|
+
moduleName: 'mongodb',
|
|
70
|
+
onRequire: require('./hooks/mongodb/nr-mongodb'),
|
|
71
|
+
onError: function intrumentErrorHandler(err) {
|
|
72
|
+
logger.error(err.message, err.stack)
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
newrelic.instrument({
|
|
77
|
+
moduleName: 'ldapjs',
|
|
78
|
+
onRequire: require('./hooks/ldap/nr-ldap'),
|
|
79
|
+
onError: function intrumentErrorHandler(err) {
|
|
80
|
+
logger.error(err.message, err.stack)
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
newrelic.instrument({
|
|
85
|
+
moduleName: 'ldapts',
|
|
86
|
+
onRequire: require('./hooks/ldap/nr-ldap'),
|
|
87
|
+
onError: function intrumentErrorHandler(err) {
|
|
88
|
+
logger.error(err.message, err.stack)
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
newrelic.instrument({
|
|
94
|
+
moduleName: 'xpath',
|
|
95
|
+
onRequire: require('./hooks/xpath/nr-xpath'),
|
|
96
|
+
onError: function intrumentErrorHandler(err) {
|
|
97
|
+
logger.error(err.message, err.stack)
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
newrelic.instrument({
|
|
101
|
+
moduleName: 'xpath.js',
|
|
102
|
+
onRequire: require('./hooks/xpath/nr-xpath'),
|
|
103
|
+
onError: function intrumentErrorHandler(err) {
|
|
104
|
+
logger.error(err.message, err.stack)
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
newrelic.instrumentDatastore({
|
|
109
|
+
moduleName: 'pg',
|
|
110
|
+
onRequire: require('./hooks/postgres/nr-postgres'),
|
|
111
|
+
onError: function intrumentErrorHandler(err) {
|
|
112
|
+
logger.error(err.message, err.stack)
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
newrelic.instrumentWebframework({
|
|
117
|
+
moduleName: 'fastify',
|
|
118
|
+
onRequire: require('./hooks/fastify/nr-fastify'),
|
|
119
|
+
onError: function intrumentErrorHandler(err) {
|
|
120
|
+
logger.error(err.message, err.stack)
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
newrelic.instrumentWebframework({
|
|
126
|
+
moduleName: 'restify',
|
|
127
|
+
onRequire: require('./hooks/restify/nr-restify'),
|
|
128
|
+
onError: function intrumentErrorHandler(err) {
|
|
129
|
+
logger.error(err.message, err.stack)
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
newrelic.instrumentWebframework({
|
|
134
|
+
moduleName: '@koa/router',
|
|
135
|
+
onRequire: require('./hooks/koa/@koa/nr-@koa-router'),
|
|
136
|
+
onError: function intrumentErrorHandler(err) {
|
|
137
|
+
logger.error(err.message, err.stack)
|
|
138
|
+
}
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
newrelic.instrumentWebframework({
|
|
142
|
+
moduleName: 'koa-router',
|
|
143
|
+
onRequire: require('./hooks/koa/@koa/nr-@koa-router'),
|
|
144
|
+
onError: function intrumentErrorHandler(err) {
|
|
145
|
+
logger.error(err.message, err.stack)
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
newrelic.instrumentWebframework({
|
|
150
|
+
moduleName: '@hapi/hapi',
|
|
151
|
+
onRequire: require('./hooks/hapi/nr-hapi'),
|
|
152
|
+
onError: function intrumentErrorHandler(err) {
|
|
153
|
+
logger.error(err.message, err.stack)
|
|
154
|
+
}
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
newrelic.instrumentWebframework({
|
|
158
|
+
moduleName: 'director',
|
|
159
|
+
onRequire: require('./hooks/director/nr-director'),
|
|
160
|
+
onError: function intrumentErrorHandler(err) {
|
|
161
|
+
logger.error(err.message, err.stack)
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
const API = require('../nr-security-api');
|
|
6
|
+
const NRAgent = API.getNRAgent();
|
|
7
|
+
|
|
8
|
+
const logs = require('./lib/core/logging');
|
|
9
|
+
const logger = logs.getLogger();
|
|
10
|
+
const initLogger = logs.getInitLogger();
|
|
11
|
+
const { Agent } = require('./lib/core/agent');
|
|
12
|
+
|
|
13
|
+
const agentConfig = require('./resources/config');
|
|
14
|
+
const shaSizeUtil = require('./lib/core/sha-size-util');
|
|
15
|
+
const njsAgentConstants = require('./lib/core/sec-agent-constants');
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
IS_LAMBDA_ENV,
|
|
19
|
+
AWS_LAMBDA_FUNCTION_NAME_ENV_IDENTIFIER,
|
|
20
|
+
LAMBDA_TASK_ROOT_ENV_IDENTIFIER,
|
|
21
|
+
LOG_MESSAGES } = njsAgentConstants;
|
|
22
|
+
const commonUtils = require('./lib/core/commonUtils');
|
|
23
|
+
|
|
24
|
+
const { AGENT_DIR } = agentConfig;
|
|
25
|
+
// eslint-disable-next-line no-unused-vars
|
|
26
|
+
const DIR_IDENTIFIER = '/';
|
|
27
|
+
const SPACE_CHARACTER = ' ';
|
|
28
|
+
// eslint-disable-next-line no-control-regex
|
|
29
|
+
const NULL_CHAR_REGEX = /\u0000/g;
|
|
30
|
+
|
|
31
|
+
const wsClient = require('./lib/core/websocket-client');
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
function extractApplicationDefForLambda(applications) {
|
|
35
|
+
const application = {
|
|
36
|
+
deployedPath: process.env[LAMBDA_TASK_ROOT_ENV_IDENTIFIER],
|
|
37
|
+
appName: process.env[AWS_LAMBDA_FUNCTION_NAME_ENV_IDENTIFIER],
|
|
38
|
+
contextPath: '/'
|
|
39
|
+
};
|
|
40
|
+
applications.push(application);
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Extracts application path and name from exec args
|
|
46
|
+
*
|
|
47
|
+
* @param {*} execArgs
|
|
48
|
+
* @param {*} applications
|
|
49
|
+
*/
|
|
50
|
+
function extractApplicationDef(execArgs, applications) {
|
|
51
|
+
initLogger.info(LOG_MESSAGES.DEP_APP_GATHERING_STARTED);
|
|
52
|
+
if (IS_LAMBDA_ENV) {
|
|
53
|
+
return extractApplicationDefForLambda(applications);
|
|
54
|
+
}
|
|
55
|
+
if (!(Array.isArray(execArgs) && Array.isArray(applications))) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const entryFile = process.argv[1];
|
|
60
|
+
if (entryFile) {
|
|
61
|
+
execArgs = [];
|
|
62
|
+
const absolutePath = require('path').resolve(entryFile);
|
|
63
|
+
execArgs.push(absolutePath);
|
|
64
|
+
}
|
|
65
|
+
for (const arg of execArgs) {
|
|
66
|
+
const application = {};
|
|
67
|
+
const fileList = arg.split(DIR_IDENTIFIER);
|
|
68
|
+
if (fileList.length >= 2) {
|
|
69
|
+
const scriptName = fileList.pop();
|
|
70
|
+
const appPath = fileList.join(DIR_IDENTIFIER);
|
|
71
|
+
application.deployedPath = appPath;
|
|
72
|
+
const appName = fileList.pop();
|
|
73
|
+
const finder = require('find-package-json');
|
|
74
|
+
const find = finder(appPath);
|
|
75
|
+
const obj = find.next().value;
|
|
76
|
+
if (obj && obj.__path) {
|
|
77
|
+
const onlyPath = require('path').dirname(obj.__path);
|
|
78
|
+
application.deployedPath = onlyPath;
|
|
79
|
+
application.contextPath = '/';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
application.appName = appName.concat(DIR_IDENTIFIER, scriptName);
|
|
83
|
+
applications.push(application);
|
|
84
|
+
break;
|
|
85
|
+
} else {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Initialize the Agent.
|
|
94
|
+
*/
|
|
95
|
+
function initialize() {
|
|
96
|
+
const policyManager = require('./lib/core/Policy');
|
|
97
|
+
policyManager.setDefaultPolicy();
|
|
98
|
+
commonUtils.initialSetup();
|
|
99
|
+
|
|
100
|
+
const applicationInfoModule = require('./lib/core/applicationinfo');
|
|
101
|
+
const agentStatus = require('./lib/core/agent-status');
|
|
102
|
+
const applications = [];
|
|
103
|
+
// Initialize ApplicationInfo
|
|
104
|
+
const applicationInfo = applicationInfoModule.getInstance();
|
|
105
|
+
applicationInfoModule.setBuildDetails(AGENT_DIR, applicationInfo);
|
|
106
|
+
|
|
107
|
+
if (NRAgent) {
|
|
108
|
+
NRAgent.on('started', () => {
|
|
109
|
+
if (NRAgent.config.security.enabled) {
|
|
110
|
+
wsClient.initialize();
|
|
111
|
+
logger.info('NR Agent started with agent_run_id:', NRAgent.config.run_id, NRAgent.config.account_id);
|
|
112
|
+
Agent.getAgent().status.setStatus('active');
|
|
113
|
+
Agent.setNRAgent(NRAgent);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
logger.info("security.enabled flag is set to false")
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
initLogger.info(LOG_MESSAGES.APP_INFO_GATHERING_STARTED);
|
|
122
|
+
|
|
123
|
+
// Fallback extract with process.argv in case application is not detected using proc cmdline
|
|
124
|
+
if ((extractApplicationDef(getProcCMDLineSanitized(applicationInfoModule), applications) || extractApplicationDef(process.argv, applications)) &&
|
|
125
|
+
applications.length > 0) {
|
|
126
|
+
|
|
127
|
+
if (applicationInfo && applicationInfo.runCommand) {
|
|
128
|
+
const fileList = applicationInfo.runCommand.split(SPACE_CHARACTER);
|
|
129
|
+
const scriptName = fileList.pop();
|
|
130
|
+
if (scriptName.includes(AGENT_DIR)) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
initLogger.info(LOG_MESSAGES.COLLECTOR_INFO, applicationInfo.collectorVersion, applicationInfo.jsonVersion, applicationInfo.buildNumber);
|
|
135
|
+
applicationInfoModule.addProperty('serverInfo.deployedApplications', applications);
|
|
136
|
+
initLogger.info(LOG_MESSAGES.APP_INFO_DEP_APP, JSON.stringify(applications));
|
|
137
|
+
|
|
138
|
+
shaSizeUtil.setLogger(logger);
|
|
139
|
+
|
|
140
|
+
// Initialize Agent Status
|
|
141
|
+
const status = agentStatus.getInstance();
|
|
142
|
+
|
|
143
|
+
// Initialize Collector config
|
|
144
|
+
|
|
145
|
+
// Initialize
|
|
146
|
+
Agent.init(applicationInfo, logger, wsClient, status);
|
|
147
|
+
initLogger.info(LOG_MESSAGES.AGENT_INIT_SUCCESSFUL, applicationInfo.pid, applicationInfo.applicationUUID);
|
|
148
|
+
initLogger.info(LOG_MESSAGES.AGENT_INIT_SUCCESSFUL_COMPLETE, applicationInfo.pid, applicationInfo.applicationUUID);
|
|
149
|
+
logger.info('Security Agent attached with application, with applicationUUID: %s', applicationInfo.applicationUUID);
|
|
150
|
+
} else {
|
|
151
|
+
// Do not load the agent.
|
|
152
|
+
logger.error('Security Agent not loaded with this application: Skipped.');
|
|
153
|
+
initLogger.error(LOG_MESSAGES.AGENT_INIT_FAILED);
|
|
154
|
+
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function getProcCMDLineSanitized(applicationInfoModule) {
|
|
162
|
+
const proc = (applicationInfoModule.getCmdLine() || '').replace(NULL_CHAR_REGEX, SPACE_CHARACTER).trim();
|
|
163
|
+
return (proc && proc.length > 0) ? proc.split(/\s/g) : process.argv;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
(() => {
|
|
167
|
+
if (initialize()) {
|
|
168
|
+
require('../instrumentation-security');
|
|
169
|
+
}
|
|
170
|
+
})();
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const API = require('../../../nr-security-api');
|
|
7
|
+
const commonUtils = require('./commonUtils');
|
|
8
|
+
const appInfo = require('./applicationinfo').getInstance();
|
|
9
|
+
const logs = require('./logging');
|
|
10
|
+
const logger = logs.getLogger();
|
|
11
|
+
const initLogger = logs.getInitLogger();
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/* eslint-disable camelcase */
|
|
15
|
+
let authHeaders;
|
|
16
|
+
/**
|
|
17
|
+
* constructor to create Authentication Headers
|
|
18
|
+
*/
|
|
19
|
+
function AuthHeaders() {
|
|
20
|
+
try {
|
|
21
|
+
const NRAgent = API.getNRAgent();
|
|
22
|
+
authHeaders = {}
|
|
23
|
+
authHeaders['NR-CSEC-CONNECTION-TYPE'] = 'LANGUAGE_COLLECTOR';
|
|
24
|
+
authHeaders['NR-AGENT-RUN-TOKEN'] = process.env.agent_run_id || NRAgent.config.run_id;
|
|
25
|
+
const COLLECTOR_VERSION = process.env.collectorVersion || appInfo.collectorVersion || '';
|
|
26
|
+
authHeaders['NR-CSEC-VERSION'] = COLLECTOR_VERSION.trim();
|
|
27
|
+
authHeaders['NR-CSEC-COLLECTOR-TYPE'] = 'NODE';
|
|
28
|
+
authHeaders['NR-CSEC-MODE'] = commonUtils.getCSECmode();
|
|
29
|
+
authHeaders['NR-CSEC-APP-UUID'] = commonUtils.getUUID();
|
|
30
|
+
authHeaders['NR-CSEC-JSON-VERSION'] = process.env.jsonVersion || appInfo.jsonVersion;
|
|
31
|
+
authHeaders['NR-CSEC-BUILD-NUMBER'] = process.env.buildNumber || appInfo.buildNumber;
|
|
32
|
+
authHeaders['NR-ACCOUNT-ID'] = process.env.account_id || NRAgent.config.account_id;
|
|
33
|
+
authHeaders['NR-LICENSE-KEY'] = NRAgent ? NRAgent.config.license_key : '';
|
|
34
|
+
} catch (error) {
|
|
35
|
+
logger.error("Exception in preparing auth headers:", error);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return authHeaders;
|
|
39
|
+
}
|
|
40
|
+
AuthHeaders.prototype.constructor = AuthHeaders;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Returns the current instanceof AuthHeaders,
|
|
44
|
+
* creates one if not already created.
|
|
45
|
+
*
|
|
46
|
+
* @returns {AuthHeaders} instance
|
|
47
|
+
*/
|
|
48
|
+
function getInstance() {
|
|
49
|
+
if (!authHeaders) {
|
|
50
|
+
authHeaders = new AuthHeaders();
|
|
51
|
+
initLogger.info("[STEP-2][BEGIN][Auth-Headers]: Authentication Headers Created Successfully");
|
|
52
|
+
}
|
|
53
|
+
return authHeaders;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = {
|
|
57
|
+
getInstance
|
|
58
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
let containerProperties = undefined;
|
|
7
|
+
function ContainerProperties(){
|
|
8
|
+
|
|
9
|
+
}
|
|
10
|
+
ContainerProperties.prototype.constructor = ContainerProperties;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Returns the current instanceof ContainerProperties,
|
|
14
|
+
* creates one if not already created.
|
|
15
|
+
*
|
|
16
|
+
* @returns {ContainerProperties} instance
|
|
17
|
+
*/
|
|
18
|
+
function getInstance() {
|
|
19
|
+
if (!containerProperties) {
|
|
20
|
+
containerProperties = new ContainerProperties();
|
|
21
|
+
containerProperties.name = "";
|
|
22
|
+
containerProperties.isPrivileged = "";
|
|
23
|
+
containerProperties.imageId = "";
|
|
24
|
+
containerProperties.imageName = "";
|
|
25
|
+
containerProperties.entrypoint = "";
|
|
26
|
+
containerProperties.creationTimestamp = "";
|
|
27
|
+
containerProperties.portBindings = new Map();
|
|
28
|
+
containerProperties.mounts = [];
|
|
29
|
+
containerProperties.state = "";
|
|
30
|
+
containerProperties.processInfos = [];
|
|
31
|
+
containerProperties.capAdd = [];
|
|
32
|
+
containerProperties.capDrop = [];
|
|
33
|
+
containerProperties.cpuUsage = "";
|
|
34
|
+
containerProperties.ipAddress = "";
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
return containerProperties;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = {
|
|
41
|
+
getInstance
|
|
42
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
let ecsProperties;
|
|
7
|
+
function ECSProperties () {
|
|
8
|
+
|
|
9
|
+
}
|
|
10
|
+
ECSProperties.prototype.constructor = ECSProperties;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Returns the current instanceof ECSProperties,
|
|
14
|
+
* creates one if not already created.
|
|
15
|
+
*
|
|
16
|
+
* @returns {ECSProperties} instance
|
|
17
|
+
*/
|
|
18
|
+
function getInstance () {
|
|
19
|
+
if (!ecsProperties) {
|
|
20
|
+
ecsProperties = new ECSProperties();
|
|
21
|
+
ecsProperties.imageName = '';
|
|
22
|
+
ecsProperties.imageId = '';
|
|
23
|
+
ecsProperties.containerName = '';
|
|
24
|
+
ecsProperties.containerId = '';
|
|
25
|
+
ecsProperties.ecsTaskDefinition = '';
|
|
26
|
+
ecsProperties.ipAddress = '';
|
|
27
|
+
ecsProperties.creationTimestamp = '';
|
|
28
|
+
}
|
|
29
|
+
return ecsProperties;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = {
|
|
33
|
+
getInstance
|
|
34
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { BasicInfo } = require('./event');
|
|
7
|
+
const applicationInfo = require('./applicationinfo').getInstance();
|
|
8
|
+
/**
|
|
9
|
+
* Function Constructor to create object of FuzzFail event
|
|
10
|
+
* @param {*} fuzzHeader
|
|
11
|
+
*/
|
|
12
|
+
function FuzzFailEvent (fuzzHeader) {
|
|
13
|
+
BasicInfo.call(this);
|
|
14
|
+
this.jsonVersion = applicationInfo.jsonVersion;
|
|
15
|
+
this.jsonName = 'fuzzfail';
|
|
16
|
+
this.applicationUUID = applicationInfo.applicationUUID;
|
|
17
|
+
this.groupName = applicationInfo.groupName;
|
|
18
|
+
this.nodeId = applicationInfo.nodeId;
|
|
19
|
+
this.policyVersion = applicationInfo.policyVersion;
|
|
20
|
+
this.fuzzHeader = fuzzHeader;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
FuzzFailEvent.prototype.constructor = FuzzFailEvent;
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
FuzzFailEvent
|
|
27
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const API = require('../../../nr-security-api');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Returns the linkingMetadata,
|
|
11
|
+
* creates one if not already created.
|
|
12
|
+
*
|
|
13
|
+
* @returns {LinkingMetadata} instance
|
|
14
|
+
*/
|
|
15
|
+
function getLinkingMetadata () {
|
|
16
|
+
return API.newrelic.getLinkingMetadata();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = {
|
|
20
|
+
getLinkingMetadata,
|
|
21
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const LinkingMetaData = require('./LinkingMetadata');
|
|
7
|
+
const API = require('../../../nr-security-api');
|
|
8
|
+
const NRAgent = API.getNRAgent();
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* constructor function to create LogMessageException object
|
|
12
|
+
* @param {*} message
|
|
13
|
+
* @param {*} cause
|
|
14
|
+
* @param {*} stacktrace
|
|
15
|
+
*/
|
|
16
|
+
function logMessageException (exception) {
|
|
17
|
+
this.message = exception.message;
|
|
18
|
+
this.cause = exception.cause ? exception.cause : '';
|
|
19
|
+
this.stacktrace = exception.stack;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* constructor function to create logMessage object;
|
|
24
|
+
* @param {*} timestamp
|
|
25
|
+
* @param {*} level
|
|
26
|
+
* @param {*} message
|
|
27
|
+
* @param {*} caller
|
|
28
|
+
* @param {*} exception
|
|
29
|
+
* @param {*} linkingMetadata
|
|
30
|
+
*/
|
|
31
|
+
function logMessage (level, message, caller, exception) {
|
|
32
|
+
this.timestamp = Date.now();
|
|
33
|
+
this.level = level;
|
|
34
|
+
this.message = message;
|
|
35
|
+
this.caller = caller;
|
|
36
|
+
if (exception) {
|
|
37
|
+
this.exception = logMessageException(exception);
|
|
38
|
+
}
|
|
39
|
+
if (NRAgent) {
|
|
40
|
+
this.linkingMetadata = LinkingMetaData.getLinkingMetadata();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = {
|
|
45
|
+
logMessage,
|
|
46
|
+
logMessageException
|
|
47
|
+
};
|