@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,171 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* eslint-disable no-unused-vars */
|
|
7
|
+
const stringify = require('fast-safe-stringify');
|
|
8
|
+
|
|
9
|
+
const restClient = require('../../restclient');
|
|
10
|
+
const { Agent } = require('../../../agent');
|
|
11
|
+
const { FuzzFailEvent } = require('../../../FuzzFailEvent');
|
|
12
|
+
const { hasWorker: isWorkerSupported } = require('../../../commonUtils');
|
|
13
|
+
const { CSEC_HOME_TMP, COLON, NR_CSEC_FUZZ_REQUEST_ID } = require('../../../sec-agent-constants');
|
|
14
|
+
const LOCALHOST = '127.0.0.1';
|
|
15
|
+
const COLON_SLASH_SLASH = '://';
|
|
16
|
+
const http = require('http');
|
|
17
|
+
const https = require('https');
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
IS_LAMBDA_ENV,
|
|
21
|
+
AWS_LAMBDA_FUNCTION_VERSION_ENV_IDENTIFIER,
|
|
22
|
+
CSEC_LAST_FUZZ_REQUEST_TIME
|
|
23
|
+
} = require('../../../sec-agent-constants');
|
|
24
|
+
const statusUtils = require('../../../statusUtils');
|
|
25
|
+
|
|
26
|
+
const find = '/{{NR_CSEC_VALIDATOR_HOME_TMP}}';
|
|
27
|
+
const CSEC_HOME_TMP_CONST = new RegExp(find, 'g');
|
|
28
|
+
|
|
29
|
+
let logger;
|
|
30
|
+
let lastFuzzEventTime = 0;
|
|
31
|
+
|
|
32
|
+
// handler function to parse fuzz event and prepare fuzz request
|
|
33
|
+
function handler (json) {
|
|
34
|
+
setLastFuzzEnventTime();
|
|
35
|
+
let rawFuzzRequest = json.arguments[0];
|
|
36
|
+
logger.debug('Fuzz request received::' + rawFuzzRequest);
|
|
37
|
+
rawFuzzRequest = rawFuzzRequest.replace(CSEC_HOME_TMP_CONST, CSEC_HOME_TMP);
|
|
38
|
+
let fuzzRequest;
|
|
39
|
+
try {
|
|
40
|
+
fuzzRequest = JSON.parse(rawFuzzRequest);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
logger.error('Parsing exeception in fuzz request: ', error);
|
|
43
|
+
}
|
|
44
|
+
if (!fuzzRequest) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
logger.info('Fuzz request:: Method: ' + fuzzRequest.method);
|
|
49
|
+
logger.info('Fuzz request:: Headers: ' + stringify(fuzzRequest.headers));
|
|
50
|
+
logger.info('Fuzz request:: Data: ' + fuzzRequest.body);
|
|
51
|
+
|
|
52
|
+
const fuzzDetails = { fuzzRequest, rawFuzzRequest };
|
|
53
|
+
lastFuzzEventTime = Date.now();
|
|
54
|
+
handleFuzzRequest(fuzzDetails);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Handles the fuzz request logic after
|
|
59
|
+
* initial parsing
|
|
60
|
+
*
|
|
61
|
+
* @param {Object} fuzzDetails
|
|
62
|
+
*/
|
|
63
|
+
function handleFuzzRequest (fuzzDetails) {
|
|
64
|
+
const { fuzzRequest } = fuzzDetails;
|
|
65
|
+
try {
|
|
66
|
+
if (IS_LAMBDA_ENV) {
|
|
67
|
+
const qualifiedARN = Agent.getAgent().applicationInfo.applicationUUID;
|
|
68
|
+
const splitArn = String.prototype.split.call(qualifiedARN, ':');
|
|
69
|
+
const arn = splitArn.slice(0, splitArn.length - 1).join(':');
|
|
70
|
+
const ver = process.env[AWS_LAMBDA_FUNCTION_VERSION_ENV_IDENTIFIER];
|
|
71
|
+
logger.info('Invoking Lambda:: ARN: ' + arn);
|
|
72
|
+
logger.info('Invoking Lambda:: Version: ' + ver);
|
|
73
|
+
|
|
74
|
+
} else {
|
|
75
|
+
const config = parseAxiosHttpRequestToFuzz(fuzzRequest);
|
|
76
|
+
const type = config.headers['content-type'];
|
|
77
|
+
if (type) {
|
|
78
|
+
const splitted = type.split(';');
|
|
79
|
+
if (splitted[0]) {
|
|
80
|
+
config.headers['content-type'] = splitted[0];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
logger.info('Firing http request:: URL: ' + config.url);
|
|
84
|
+
|
|
85
|
+
const request = restClient.fireRequest(config);
|
|
86
|
+
handleFuzzResponse(request, fuzzDetails);
|
|
87
|
+
}
|
|
88
|
+
} catch (err) {
|
|
89
|
+
statusUtils.addErrortoBuffer(err);
|
|
90
|
+
const fuzzFailEvent = new FuzzFailEvent(fuzzRequest.headers[NR_CSEC_FUZZ_REQUEST_ID]);
|
|
91
|
+
logger.error(stringify(fuzzFailEvent));
|
|
92
|
+
try {
|
|
93
|
+
Agent.getAgent().client.dispatcher(fuzzFailEvent);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
logger.debug('Error in sending fuzz request:', error.stack);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Handles the fuzz response Promise.
|
|
102
|
+
*
|
|
103
|
+
* @param {Promise} request
|
|
104
|
+
* @param {Object} fuzzDetails
|
|
105
|
+
*/
|
|
106
|
+
function handleFuzzResponse (request, fuzzDetails) {
|
|
107
|
+
const { rawFuzzRequest, fuzzRequest } = fuzzDetails;
|
|
108
|
+
if (request) {
|
|
109
|
+
request.then(() => {
|
|
110
|
+
logger.info('Fuzz success: ' + rawFuzzRequest);
|
|
111
|
+
}).catch(() => {
|
|
112
|
+
logger.debug('Error occured:', fuzzRequest.url, fuzzRequest);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Parses the passed fuzz request object to
|
|
119
|
+
* Axios config.
|
|
120
|
+
*
|
|
121
|
+
* @param {JSON} requestObject
|
|
122
|
+
*/
|
|
123
|
+
function parseAxiosHttpRequestToFuzz (requestObject) {
|
|
124
|
+
const serverName = requestObject.serverName ? requestObject.serverName : LOCALHOST;
|
|
125
|
+
return {
|
|
126
|
+
url: requestObject.protocol + COLON_SLASH_SLASH + serverName + COLON + requestObject.serverPort + requestObject.url,
|
|
127
|
+
method: requestObject.method,
|
|
128
|
+
data: requestObject.body,
|
|
129
|
+
headers: requestObject.headers,
|
|
130
|
+
timeout: 5000,
|
|
131
|
+
httpAgent: new http.Agent({ keepAlive: true }),
|
|
132
|
+
httpsAgent: new https.Agent({ keepAlive: true, rejectUnauthorized: false })
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* set the handler logger
|
|
140
|
+
* @param {*} l
|
|
141
|
+
*/
|
|
142
|
+
function setLogger (l) {
|
|
143
|
+
logger = l;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Sets the last fuzz event time epoch
|
|
148
|
+
* @param {Number} time
|
|
149
|
+
*/
|
|
150
|
+
function setLastFuzzEnventTime (time = Date.now()) {
|
|
151
|
+
if (isWorkerSupported()) {
|
|
152
|
+
process.env[CSEC_LAST_FUZZ_REQUEST_TIME] = time;
|
|
153
|
+
} else {
|
|
154
|
+
lastFuzzEventTime = time;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Returns last fuzz event time epoch
|
|
160
|
+
* @returns {Number} lastFuzzEventTime
|
|
161
|
+
*/
|
|
162
|
+
function getLastFuzzEnventTime () {
|
|
163
|
+
return isWorkerSupported() ? Number.parseInt(process.env[CSEC_LAST_FUZZ_REQUEST_TIME]) : lastFuzzEventTime;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
module.exports = {
|
|
167
|
+
handler,
|
|
168
|
+
setLogger,
|
|
169
|
+
setLastFuzzEnventTime,
|
|
170
|
+
getLastFuzzEnventTime
|
|
171
|
+
};
|
|
@@ -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 _ = require('lodash');
|
|
7
|
+
|
|
8
|
+
const { SERVER_COMMAND } = require('../../../sec-agent-constants');
|
|
9
|
+
const UnsupportedAgentHandler = require('./unsupported-agent-handler');
|
|
10
|
+
const StartupHandshakeHandler = require('./startup-handshake-handler');
|
|
11
|
+
const FuzzRequestHandler = require('./fuzz-request-handler');
|
|
12
|
+
const CollectorPolicyHandler = require('./collector-policy-handler');
|
|
13
|
+
const CollectorPolicyErrorHandler = require('./collecotor-policy-error-handler');
|
|
14
|
+
const NoOpHandler = require('./no-op-handler');
|
|
15
|
+
const WSReconnect = require('./ws-reconnect');
|
|
16
|
+
|
|
17
|
+
const commandHandlerMap = {
|
|
18
|
+
[SERVER_COMMAND.STARTUP_WELCOME_MSG]: StartupHandshakeHandler,
|
|
19
|
+
[SERVER_COMMAND.UNSUPPORTED_AGENT]: UnsupportedAgentHandler,
|
|
20
|
+
[SERVER_COMMAND.FUZZ_REQUEST]: FuzzRequestHandler,
|
|
21
|
+
[SERVER_COMMAND.COLLECTOR_CONFIG]: CollectorPolicyHandler,
|
|
22
|
+
[SERVER_COMMAND.POLICY_ERROR]: CollectorPolicyErrorHandler,
|
|
23
|
+
[SERVER_COMMAND.OBEY_WS_RECONNECT]: WSReconnect
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const handle = function handle (json) {
|
|
27
|
+
if (json && json.controlCommand && json.arguments && commandHandlerMap[json.controlCommand]) {
|
|
28
|
+
commandHandlerMap[json.controlCommand].handler.call(this, json);
|
|
29
|
+
} else {
|
|
30
|
+
NoOpHandler.handler.call(this, json);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const setLogger = function setLogger (logger) {
|
|
35
|
+
_.forEach(commandHandlerMap, (handler) => {
|
|
36
|
+
handler.setLogger(logger);
|
|
37
|
+
});
|
|
38
|
+
NoOpHandler.setLogger(logger);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
module.exports = {
|
|
42
|
+
StartupHandshakeHandler,
|
|
43
|
+
FuzzRequestHandler,
|
|
44
|
+
UnsupportedAgentHandler,
|
|
45
|
+
handle,
|
|
46
|
+
setLogger
|
|
47
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
let logger;
|
|
7
|
+
|
|
8
|
+
module.exports.handler = function handler (json) {
|
|
9
|
+
logger.error('unsupported control command received:', json);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
module.exports.setLogger = l => { logger = l };
|
package/lib/nr-security-agent/lib/core/connections/websocket/response/startup-handshake-handler.js
ADDED
|
@@ -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 StartupConfig = require('../../../startup-config');
|
|
7
|
+
const logs = require('../../../logging');
|
|
8
|
+
let logger = logs.getLogger();
|
|
9
|
+
const initLogger = logs.getInitLogger();
|
|
10
|
+
const LOG_MESSAGES = require('../../../sec-agent-constants').LOG_MESSAGES;
|
|
11
|
+
const applicationInfoModule = require('../../../applicationinfo');
|
|
12
|
+
|
|
13
|
+
module.exports.handler = function handler(json) {
|
|
14
|
+
try {
|
|
15
|
+
const startupConfig = StartupConfig.getInstance();
|
|
16
|
+
startupConfig.config = json.data;
|
|
17
|
+
|
|
18
|
+
initLogger.info(LOG_MESSAGES.COLLECTOR_INIT_WITH_PROP, JSON.stringify(startupConfig.config));
|
|
19
|
+
initLogger.info('Collector is now ACTIVE for', applicationInfoModule.getInstance().applicationUUID);
|
|
20
|
+
|
|
21
|
+
} catch (error) {
|
|
22
|
+
logger.error(LOG_MESSAGES.PARSING_EXP_WELCOME_MSG, error);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// eslint-disable-next-line no-unused-vars
|
|
27
|
+
module.exports.setLogger = l => { logger = l };
|
package/lib/nr-security-agent/lib/core/connections/websocket/response/unsupported-agent-handler.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const agentStatus = require('../../../agent-status');
|
|
7
|
+
|
|
8
|
+
let logger;
|
|
9
|
+
module.exports.handler = function handler (json) {
|
|
10
|
+
const message = json.arguments[0];
|
|
11
|
+
logger.error(message);
|
|
12
|
+
const status = agentStatus.getInstance();
|
|
13
|
+
const statusCode = 'DISABLED';
|
|
14
|
+
status.setStatus(agentStatus.CSECAgentStatus.codes[statusCode]);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// eslint-disable-next-line no-unused-vars
|
|
18
|
+
module.exports.setLogger = l => { logger = l };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
let logger;
|
|
7
|
+
module.exports.handler = function handler (json) {
|
|
8
|
+
logger.info('WS reconnect received', json);
|
|
9
|
+
const { Agent } = require('../../../agent');
|
|
10
|
+
const wsClient = Agent.getAgent().client;
|
|
11
|
+
wsClient.obeyReconnect();
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
module.exports.setLogger = l => { logger = l };
|