@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.
Files changed (87) hide show
  1. package/CHANGELOG.md +0 -0
  2. package/CONTRIBUTING.md +23 -0
  3. package/LICENSE +43 -0
  4. package/README.md +98 -0
  5. package/THIRD_PARTY_NOTICES.md +2909 -0
  6. package/index.js +24 -0
  7. package/lib/instrumentation-security/core/constants.js +66 -0
  8. package/lib/instrumentation-security/core/event-constants.js +49 -0
  9. package/lib/instrumentation-security/core/request-manager.js +73 -0
  10. package/lib/instrumentation-security/core/route-manager.js +30 -0
  11. package/lib/instrumentation-security/core/sec-trace.js +134 -0
  12. package/lib/instrumentation-security/core/sec-utils.js +212 -0
  13. package/lib/instrumentation-security/core/security-metadata.js +34 -0
  14. package/lib/instrumentation-security/core/stack-trace.js +156 -0
  15. package/lib/instrumentation-security/hooks/director/nr-director.js +98 -0
  16. package/lib/instrumentation-security/hooks/express/nr-express.js +106 -0
  17. package/lib/instrumentation-security/hooks/fastify/nr-fastify.js +155 -0
  18. package/lib/instrumentation-security/hooks/fs/nr-fs.js +391 -0
  19. package/lib/instrumentation-security/hooks/hapi/nr-hapi.js +131 -0
  20. package/lib/instrumentation-security/hooks/http/nr-http.js +461 -0
  21. package/lib/instrumentation-security/hooks/koa/@koa/nr-@koa-router.js +110 -0
  22. package/lib/instrumentation-security/hooks/ldap/nr-ldap.js +81 -0
  23. package/lib/instrumentation-security/hooks/mongodb/common.js +239 -0
  24. package/lib/instrumentation-security/hooks/mongodb/constants.js +91 -0
  25. package/lib/instrumentation-security/hooks/mongodb/nr-mongodb.js +49 -0
  26. package/lib/instrumentation-security/hooks/mongodb/v2-mongo.js +91 -0
  27. package/lib/instrumentation-security/hooks/mongodb/v3-mongo.js +36 -0
  28. package/lib/instrumentation-security/hooks/mongodb/v4-mongo.js +17 -0
  29. package/lib/instrumentation-security/hooks/mysql/nr-mysql.js +232 -0
  30. package/lib/instrumentation-security/hooks/native/nr-childProcess.js +131 -0
  31. package/lib/instrumentation-security/hooks/postgres/nr-postgres.js +131 -0
  32. package/lib/instrumentation-security/hooks/require/nr-require.js +93 -0
  33. package/lib/instrumentation-security/hooks/restify/nr-restify.js +104 -0
  34. package/lib/instrumentation-security/hooks/xpath/nr-xpath.js +91 -0
  35. package/lib/instrumentation-security/index.js +171 -0
  36. package/lib/nr-security-agent/index.js +170 -0
  37. package/lib/nr-security-agent/lib/core/Auth-headers.js +58 -0
  38. package/lib/nr-security-agent/lib/core/ContainerProperties.js +42 -0
  39. package/lib/nr-security-agent/lib/core/ECSProperties.js +34 -0
  40. package/lib/nr-security-agent/lib/core/FuzzFailEvent.js +27 -0
  41. package/lib/nr-security-agent/lib/core/LinkingMetadata.js +21 -0
  42. package/lib/nr-security-agent/lib/core/LogMessage.js +47 -0
  43. package/lib/nr-security-agent/lib/core/PodProperties.js +36 -0
  44. package/lib/nr-security-agent/lib/core/Policy.js +105 -0
  45. package/lib/nr-security-agent/lib/core/agent-status.js +56 -0
  46. package/lib/nr-security-agent/lib/core/agent.js +146 -0
  47. package/lib/nr-security-agent/lib/core/applicationinfo.js +634 -0
  48. package/lib/nr-security-agent/lib/core/commonUtils.js +411 -0
  49. package/lib/nr-security-agent/lib/core/connections/aws-lambda-client.js +55 -0
  50. package/lib/nr-security-agent/lib/core/connections/restclient.js +20 -0
  51. package/lib/nr-security-agent/lib/core/connections/websocket/index.js +25 -0
  52. package/lib/nr-security-agent/lib/core/connections/websocket/response/collecotor-policy-error-handler.js +18 -0
  53. package/lib/nr-security-agent/lib/core/connections/websocket/response/collector-policy-handler.js +20 -0
  54. package/lib/nr-security-agent/lib/core/connections/websocket/response/fuzz-request-handler.js +171 -0
  55. package/lib/nr-security-agent/lib/core/connections/websocket/response/index.js +47 -0
  56. package/lib/nr-security-agent/lib/core/connections/websocket/response/no-op-handler.js +12 -0
  57. package/lib/nr-security-agent/lib/core/connections/websocket/response/startup-handshake-handler.js +27 -0
  58. package/lib/nr-security-agent/lib/core/connections/websocket/response/unsupported-agent-handler.js +18 -0
  59. package/lib/nr-security-agent/lib/core/connections/websocket/response/ws-reconnect.js +14 -0
  60. package/lib/nr-security-agent/lib/core/connections/websocket/websocket.js +443 -0
  61. package/lib/nr-security-agent/lib/core/event.js +186 -0
  62. package/lib/nr-security-agent/lib/core/health-check.js +159 -0
  63. package/lib/nr-security-agent/lib/core/json-file-handler.js +66 -0
  64. package/lib/nr-security-agent/lib/core/jsonValidator.js +149 -0
  65. package/lib/nr-security-agent/lib/core/lambda-delegated-task-service.js +90 -0
  66. package/lib/nr-security-agent/lib/core/logging.js +176 -0
  67. package/lib/nr-security-agent/lib/core/sec-agent-constants.js +173 -0
  68. package/lib/nr-security-agent/lib/core/sec-util.js +166 -0
  69. package/lib/nr-security-agent/lib/core/sha-size-util.js +338 -0
  70. package/lib/nr-security-agent/lib/core/sha_worker.js +24 -0
  71. package/lib/nr-security-agent/lib/core/startup-config.js +29 -0
  72. package/lib/nr-security-agent/lib/core/statusUtils.js +157 -0
  73. package/lib/nr-security-agent/lib/core/timeunit.js +44 -0
  74. package/lib/nr-security-agent/lib/core/websocket-client.js +335 -0
  75. package/lib/nr-security-agent/lib/core/worker-entities.js +82 -0
  76. package/lib/nr-security-agent/lib/core/worker.js +148 -0
  77. package/lib/nr-security-agent/lib/core/xss-utils.js +297 -0
  78. package/lib/nr-security-agent/lib/models/lambda-delegated-task/constants.js +12 -0
  79. package/lib/nr-security-agent/lib/models/lambda-delegated-task/index.js +15 -0
  80. package/lib/nr-security-agent/lib/models/lambda-delegated-task/lambda-delegated-sha-calculation.js +37 -0
  81. package/lib/nr-security-agent/lib/models/lambda-delegated-task/lambda-delegated-task-base.js +50 -0
  82. package/lib/nr-security-agent/lib/models/lambda-delegated-task/lambda-delegated-task-type.js +17 -0
  83. package/lib/nr-security-agent/resources/cert.pem +31 -0
  84. package/lib/nr-security-agent/resources/config.js +19 -0
  85. package/lib/nr-security-agent/resources/default-policy.yaml +36 -0
  86. package/lib/nr-security-api/index.js +111 -0
  87. 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 };
@@ -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 };
@@ -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 };