@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,148 @@
1
+ /*
2
+ * Copyright 2023 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ // Access the workerData by requiring it.
7
+ const { parentPort, workerData } = require('worker_threads');
8
+ // we need to initialize logger first hand
9
+ const logs = require('./logging');
10
+ const { applicationInfo } = workerData;
11
+ const logger = logs.getLogger(applicationInfo.applicationUUID);
12
+
13
+ const { SecWebSocket, WSCallbacks, releaseWebSocket } = require('./connections/websocket');
14
+ const {
15
+ SetDefaultLogLevelHandler,
16
+ FuzzRequestHandler,
17
+ setLogger: setResponseHandlerLogger
18
+ } = require('./connections/websocket/response');
19
+ const { SERVER_COMMAND } = require('./sec-agent-constants');
20
+ const { WorkerMessage, WORKER_STATUS } = require('./worker-entities');
21
+ const { Agent } = require('./agent');
22
+ const statusUtils = require('./statusUtils');
23
+ const commonUtils = require('./commonUtils');
24
+
25
+
26
+ const MESSAGE = 'message';
27
+
28
+ const flushInitiatedMsg = new WorkerMessage(WorkerMessage.TYPE.FLUSH, { status: 'initiated' });
29
+ const flushFinishedMsg = new WorkerMessage(WorkerMessage.TYPE.FLUSH, { status: 'flushed' });
30
+
31
+ let connection;
32
+ // we would want to provide a custome on data
33
+ // handler as the some control comands might
34
+ // need change in current thread, and main thread
35
+ // as well.
36
+ const webSocketCallbacks = new WSCallbacks(null, function (data) {
37
+ try {
38
+ const json = JSON.parse(data);
39
+ if (!json.controlCommand) {
40
+ return;
41
+ }
42
+ // we need some updates in worker threads also
43
+ switch (json.controlCommand) {
44
+ case SERVER_COMMAND.SET_DEFAULT_LOG_LEVEL:
45
+ SetDefaultLogLevelHandler(json);
46
+ break;
47
+ case SERVER_COMMAND.FUZZ_REQUEST:
48
+ FuzzRequestHandler.handler(json);
49
+ // we would not want this to be duplicated
50
+ // in main thread, so we would return from here
51
+ return;
52
+ default:
53
+ }
54
+
55
+ // send the message to parent in non-blocking mode
56
+ setImmediate(function () {
57
+ parentPort.postMessage(new WorkerMessage(WorkerMessage.TYPE.MESSAGE, json));
58
+ });
59
+ } catch (err) {
60
+
61
+ }
62
+ }, null);
63
+
64
+ /**
65
+ * This would initiate the worker and bootstrap
66
+ * all the necessary configurations.
67
+ */
68
+ function initWorker () {
69
+ Agent.init(applicationInfo, logger, null, null);
70
+ setResponseHandlerLogger(logger);
71
+ logger.info('Creating websocket connection in worker thread');
72
+ const validatorService = commonUtils.getValidatorServiceEndpointURL();
73
+ connection = new SecWebSocket(validatorService, webSocketCallbacks, logger);
74
+ Agent.getAgent().setClient(connection);
75
+ // Main thread will pass the data you need
76
+ // through this event listener.
77
+ parentPort.on(MESSAGE, handleMessage);
78
+ // we would set the worker as initialized here
79
+ process.env.WS_WORKER_STATUS = WORKER_STATUS.RUNNING;
80
+ }
81
+
82
+ /**
83
+ * Makes the event queue flush
84
+ * when the websocket is initialized in
85
+ * worker, using the connection instance.
86
+ * This also triggers events to main to mark
87
+ * the flushing initiated or complete
88
+ */
89
+ async function flushEventQueueFromWorker () {
90
+ parentPort.postMessage(flushInitiatedMsg);
91
+ await connection.flushEventQueue();
92
+ parentPort.postMessage(flushFinishedMsg);
93
+ }
94
+
95
+ /**
96
+ * This handles any messages received from main
97
+ * if websocket worker is initialized
98
+ *
99
+ * @param {JSON} msg
100
+ */
101
+ function handleMessage (msg) {
102
+ const workerMsg = WorkerMessage.parseFromObject(msg);
103
+ if (logger.level && (logger.level.levelStr !== process.env.loglevel)) {
104
+ logger.level = process.env.loglevel;
105
+ }
106
+ switch (workerMsg.getType()) {
107
+ case WorkerMessage.TYPE.MESSAGE: {
108
+ connection.dispatch(workerMsg.getPayload());
109
+ releaseWebSocket();
110
+ break;
111
+ }
112
+ case WorkerMessage.TYPE.FLUSH: {
113
+ flushEventQueueFromWorker();
114
+ break;
115
+ }
116
+ case WorkerMessage.TYPE.UPDATE_APPLICATION_INFO:
117
+ Agent.getAgent().setApplicationInfo(workerMsg.getPayload());
118
+ break;
119
+ case WorkerMessage.TYPE.RECONNECT: {
120
+ connection.reconnect();
121
+ break;
122
+ }
123
+ case WorkerMessage.TYPE.OBEY_RECONNECT: {
124
+ connection.obeyReconnect();
125
+ break;
126
+ }
127
+ default:
128
+ }
129
+ }
130
+
131
+ setInterval(() => {
132
+ try {
133
+ const buffErrors = statusUtils.getRingBufferedErrors();
134
+ while (!buffErrors.isEmpty()) {
135
+ const err = buffErrors.deq();
136
+ parentPort.postMessage(new WorkerMessage(WorkerMessage.TYPE.ERROR, err));
137
+ }
138
+ } catch (error) {
139
+ }
140
+ }, 240000);
141
+
142
+ /**
143
+ * This would initiate the worker when the
144
+ * module is loaded.
145
+ */
146
+ (() => {
147
+ initWorker();
148
+ })();
@@ -0,0 +1,297 @@
1
+ /*
2
+ * Copyright 2023 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ const _ = require('lodash');
7
+ const { AllHtmlEntities } = require('html-entities');
8
+ const decode = require('unescape');
9
+ const querystring = require('querystring');
10
+
11
+ const { Agent } = require('./agent');
12
+
13
+ const entities = new AllHtmlEntities();
14
+
15
+ const tagNameRegex = /<([a-zA-Z_-]+[0-9]*|!--)/gmi;
16
+ const attribRegex = /([^(/\s<'">)]+?)(?:\s*)=\s*(('|")([\s\S]*?)(?:(?=(\\?))\5.)*?\3|.+?(?=\/>|>|\?>|\s|<\/|$))/gmi;
17
+ const ANGLE_END = '>';
18
+ const HTML_COMMENT_END = '-->';
19
+ const HTML_COMMENT_START = '!--';
20
+ const EQUALS = '=';
21
+ const SCRIPT_END = '</SCRIPT';
22
+ const ANGLE_END_CHAR = '>';
23
+ const FIVE_COLON = ':::::';
24
+ const EMPTY_STRING = '';
25
+ const ANGLE_START = '<';
26
+
27
+ /**
28
+ * returns detected xss construct if any
29
+ *
30
+ * @param {ContextEntity} csecRequest
31
+ * @param {Object} responseBody
32
+ * @param {Object} responseHeaders
33
+ * @returns
34
+ */
35
+ function checkForReflectedXSS (csecRequest, responseBody, responseHeaders) {
36
+ const combinedRequestData = decodeRequestData(csecRequest);
37
+ const combinedResponseData = decodeResponseData(responseBody, responseHeaders);
38
+
39
+ const combinedResponseDataString = [...combinedResponseData].join(FIVE_COLON);
40
+ let attackConstructs = isXSS(combinedRequestData);
41
+
42
+ // Agent.getAgent().logger.debug('attackConstructs:', attackConstructs);
43
+ attackConstructs = Array.from(attackConstructs);
44
+ for (let i = 0; i < attackConstructs.length; i++) {
45
+ if (combinedResponseDataString.toLowerCase().includes(attackConstructs[i].toLowerCase())) {
46
+ Agent.getAgent().logger.debug('construct found::', attackConstructs[i]);
47
+ return attackConstructs[i];
48
+ }
49
+ }
50
+ return EMPTY_STRING;
51
+ }
52
+
53
+ function decodeRequestData (csecRequest) {
54
+ const processedData = new Set();
55
+ if (csecRequest) {
56
+ const body = csecRequest.body;
57
+ const processedUrl = csecRequest.url;
58
+ let processedBody = body;
59
+ try {
60
+ for (const [key, value] of Object.entries(csecRequest.headers)) {
61
+ // For key
62
+ processURLEncodedDataForXSS(processedData, key);
63
+
64
+ // For Value
65
+ processURLEncodedDataForXSS(processedData, value);
66
+ }
67
+ if (csecRequest.parameterMap) {
68
+ for (const [key, value] of Object.entries(csecRequest.parameterMap)) {
69
+ if (key) {
70
+ processURLEncodedDataForXSS(processedData, key.toString());
71
+ }
72
+
73
+ if (value) {
74
+ processURLEncodedDataForXSS(processedData, value.toString());
75
+ }
76
+ }
77
+ }
78
+ const querystringObj = querystring.decode(processedUrl);
79
+ if (querystringObj) {
80
+ for (const [key, value] of Object.entries(querystringObj)) {
81
+ if (key) {
82
+ processURLEncodedDataForXSS(processedData, key.toString());
83
+ }
84
+
85
+ if (value) {
86
+ processURLEncodedDataForXSS(processedData, value.toString());
87
+ }
88
+ }
89
+ }
90
+
91
+ // For URL
92
+ processURLEncodedDataForXSS(processedData, processedUrl);
93
+
94
+ // For Body
95
+
96
+ if (processedBody) {
97
+ try {
98
+ const bodyObject = querystring.decode(processedBody);
99
+ if (bodyObject) {
100
+ for (const [k, v] of Object.entries(bodyObject)) {
101
+ processedData.add(v);
102
+ processedData.add(k);
103
+ }
104
+ }
105
+ } catch (error) {
106
+
107
+ }
108
+ processedData.add(processedBody);
109
+
110
+ const oldProcessedBody = processedBody;
111
+
112
+ processedBody = safeDecode(processedBody);
113
+ if (processedBody !== oldProcessedBody && processedBody.includes(ANGLE_START)) {
114
+ processedData.add(processedBody);
115
+ }
116
+ }
117
+ } catch (err) {
118
+ Agent.getAgent().logger.error('Exception occured while decoding request:', err);
119
+ }
120
+ }
121
+
122
+ return processedData;
123
+ }
124
+
125
+ function decodeResponseData (responseBody, responseHeaders) {
126
+ const processedData = new Set();
127
+ const processedBody = responseBody || '';
128
+
129
+ try {
130
+ processedData.add(processedBody);
131
+ } catch (err) {
132
+ Agent.getAgent().logger.error('Exception occured while decoding response:', err);
133
+ }
134
+
135
+ return processedData;
136
+ }
137
+
138
+ function isXSS (combinedData) {
139
+ const attackConstructs = new Set();
140
+ for (const data of combinedData) {
141
+ const constructs = getXSSConstructs(data);
142
+ constructs.forEach(attackConstructs.add, attackConstructs);
143
+ }
144
+ return attackConstructs;
145
+ }
146
+
147
+ function getXSSConstructs (data) {
148
+ const constructs = new Set();
149
+ let isAttackConstruct = false;
150
+ let currPos = 0;
151
+ let startPos = 0;
152
+ let tmpCurrPos = 0;
153
+ let tmpStartPos = 0;
154
+ let matcher;
155
+ let attribMatcher;
156
+ while (currPos < data.length) {
157
+ let tagName;
158
+
159
+ matcher = tagNameRegex.exec(data);
160
+ if (!matcher) {
161
+ return constructs;
162
+ }
163
+ if ((matcher) !== null) {
164
+ // This is necessary to avoid infinite loops with zero-width matches
165
+ if (matcher.index === tagNameRegex.lastIndex) {
166
+ tagNameRegex.lastIndex++;
167
+ }
168
+
169
+ tagName = matcher[1];
170
+
171
+ tagNameRegex.lastIndex = currPos;
172
+ if (!tagNameRegex.test(data)) {
173
+ return constructs;
174
+ }
175
+
176
+ if (_.isEmpty(tagName)) {
177
+ return constructs;
178
+ }
179
+
180
+ startPos = matcher.index;
181
+ currPos = tagNameRegex.lastIndex - 1;
182
+
183
+ if (HTML_COMMENT_START === tagName) {
184
+ tmpCurrPos = data.indexOf(HTML_COMMENT_END, startPos);
185
+ if (tmpCurrPos === -1) {
186
+ break;
187
+ } else {
188
+ currPos = tmpCurrPos;
189
+ continue;
190
+ }
191
+ }
192
+ tmpStartPos = tmpCurrPos = data.indexOf(ANGLE_END, startPos);
193
+ if (tmpCurrPos === -1) {
194
+ tmpStartPos = startPos;
195
+ }
196
+ }
197
+ attribRegex.lastIndex = currPos;
198
+ while ((attribMatcher = attribRegex.exec(data)) !== null) {
199
+ // This is necessary to avoid infinite loops with zero-width matches
200
+ if (attribMatcher.index === attribRegex.lastIndex) {
201
+ attribRegex.lastIndex++;
202
+ }
203
+
204
+ let attribData = _.trim(attribMatcher[0]);
205
+
206
+ currPos = attribRegex.lastIndex - 1;
207
+ tmpCurrPos = data.indexOf(ANGLE_END, tmpStartPos);
208
+
209
+ if ((tmpCurrPos === -1 || attribMatcher.index < tmpCurrPos)) {
210
+ tmpStartPos = tmpCurrPos = attribRegex.lastIndex - 1;
211
+ tmpStartPos++;
212
+ if (_.isEmpty(attribMatcher[3]) && attribRegex.lastIndex >= tmpCurrPos) {
213
+ tmpStartPos = tmpCurrPos = data.indexOf(ANGLE_END, attribMatcher.index);
214
+ if (tmpStartPos > -1) {
215
+ attribData = attribData.substring(0, tmpStartPos);
216
+ }
217
+ }
218
+ const key = attribData.split(EQUALS)[0];
219
+ const val = attribData.split(EQUALS)[1];
220
+ const upperCaseAttribKey = key.toUpperCase();
221
+
222
+ if (!_.isEmpty(key) && (upperCaseAttribKey.startsWith('ON') || upperCaseAttribKey === 'SRC' || upperCaseAttribKey === 'HREF' ||
223
+ upperCaseAttribKey === 'ACTION' || upperCaseAttribKey === 'FORMACTION' || upperCaseAttribKey === 'SRCDOC' ||
224
+ upperCaseAttribKey === 'DATA' || decode(val).toUpperCase().replace(/\s/g, '').includes('JAVASCRIPT:') ||
225
+ entities.decode(val).toUpperCase().replace(/\s/g, '').includes('JAVASCRIPT:'))) {
226
+ isAttackConstruct = true;
227
+ }
228
+ } else {
229
+ break;
230
+ }
231
+ }
232
+
233
+ if (tmpCurrPos > 0) {
234
+ currPos = tmpCurrPos;
235
+ }
236
+
237
+ if (data.charAt(currPos) !== ANGLE_END_CHAR) {
238
+ const tmp = data.indexOf(ANGLE_END, currPos);
239
+ if (tmp !== -1) {
240
+ currPos = tmp;
241
+ } else if (!isAttackConstruct) {
242
+ continue;
243
+ }
244
+ }
245
+ if (tagName && tagName.toUpperCase().trim() === 'SCRIPT') {
246
+ const locationOfEndTag = data.toUpperCase().indexOf(SCRIPT_END, currPos);
247
+ if (locationOfEndTag !== -1) {
248
+ const body = data.substring(currPos + 1, locationOfEndTag);
249
+ if (body) {
250
+ constructs.add(data.substring(startPos, currPos + 1) + body);
251
+ continue;
252
+ }
253
+ } else {
254
+ let body = data.substring(currPos + 1);
255
+ const tagEnd = body.indexOf(ANGLE_END);
256
+
257
+ if (!_.isEmpty(body) && tagEnd !== -1) {
258
+ body = data.substring(tagEnd);
259
+ constructs.add(data.substring(startPos, currPos + 1) + body);
260
+ break;
261
+ }
262
+ }
263
+ }
264
+
265
+ if (isAttackConstruct) {
266
+ constructs.add(data.substring(startPos, currPos + 1));
267
+ }
268
+ }
269
+
270
+ return constructs;
271
+ }
272
+
273
+ function processURLEncodedDataForXSS (processedData, data) {
274
+ let key = data;
275
+ let oldKey = String(key);
276
+ do {
277
+ if (key.includes(ANGLE_START)) {
278
+ processedData.add(key);
279
+ }
280
+ oldKey = key;
281
+ key = safeDecode(key);
282
+ } while (oldKey !== key);
283
+ }
284
+
285
+ function safeDecode (data) {
286
+ let decodedData = EMPTY_STRING;
287
+ try {
288
+ decodedData = decodeURIComponent(data);
289
+ } catch (err) {
290
+ decodedData = data;
291
+ }
292
+ return decodedData;
293
+ }
294
+
295
+ module.exports = {
296
+ checkForReflectedXSS
297
+ };
@@ -0,0 +1,12 @@
1
+ /*
2
+ * Copyright 2023 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ const CSEC_CALCULATING_APPLICATION_SHA = 'CSEC_CALCULATING_APPLICATION_SHA';
7
+ const CSEC_TASK_PAYLOAD_IDENTIFIER = 'CSEC_TASK_PAYLOAD';
8
+
9
+ module.exports = {
10
+ CSEC_TASK_PAYLOAD_IDENTIFIER,
11
+ CSEC_CALCULATING_APPLICATION_SHA
12
+ };
@@ -0,0 +1,15 @@
1
+ /*
2
+ * Copyright 2023 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ const { LambdaDelegatedTaskType } = require('./lambda-delegated-task-type');
7
+ const { LambdaDelegatedTaskBase } = require('./lambda-delegated-task-base');
8
+ const { LambdaDelegatedTaskShaCalculation } = require('./lambda-delegated-sha-calculation');
9
+ const CONST = require('./constants');
10
+ module.exports = {
11
+ LambdaDelegatedTaskType,
12
+ LambdaDelegatedTaskBase,
13
+ LambdaDelegatedTaskShaCalculation,
14
+ CONST
15
+ };
@@ -0,0 +1,37 @@
1
+ /*
2
+ * Copyright 2023 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ const { LambdaDelegatedTaskBase } = require('./lambda-delegated-task-base');
7
+ const ApplicationInfo = require('../../core/applicationinfo');
8
+ const { Agent } = require('../../core/agent');
9
+ const shaSizeUtil = require('../../core/sha-size-util');
10
+ const { CSEC_CALCULATING_APPLICATION_SHA } = require('./constants');
11
+ function LambdaDelegatedTaskShaCalculation (type, ...args) {
12
+ LambdaDelegatedTaskBase.call(this, type, ...args);
13
+ }
14
+
15
+ LambdaDelegatedTaskShaCalculation.prototype = LambdaDelegatedTaskBase.prototype;
16
+ LambdaDelegatedTaskShaCalculation.prototype.constructor = LambdaDelegatedTaskShaCalculation;
17
+
18
+ LambdaDelegatedTaskShaCalculation.prototype.handle = function handleShaCalculation () {
19
+ process.env[CSEC_CALCULATING_APPLICATION_SHA] = true;
20
+ const applicationInfo = ApplicationInfo.getInstance();
21
+ const deployedApplications = applicationInfo && applicationInfo.serverInfo && applicationInfo.serverInfo.deployedApplications;
22
+
23
+ // if there are no applications detected
24
+ if (!deployedApplications) return;
25
+
26
+ // calculate and add sha and size info
27
+ const [application] = deployedApplications;
28
+ const stat = shaSizeUtil.getApplicationSHAAndSizeSync(application.deployedPath, /.*\/(node_modules)\/.*/);
29
+ application.sha256 = stat.sha256;
30
+ application.size = stat.size;
31
+
32
+ Agent.getAgent().client.dispatcher(applicationInfo);
33
+ };
34
+
35
+ module.exports = {
36
+ LambdaDelegatedTaskShaCalculation
37
+ };
@@ -0,0 +1,50 @@
1
+ /*
2
+ * Copyright 2023 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ // eslint-disable-next-line no-unused-vars
7
+ const { LambdaDelegatedTaskType } = require('./lambda-delegated-task-type');
8
+ const { CSEC_TASK_PAYLOAD_IDENTIFIER } = require('./constants');
9
+
10
+ function LambdaDelegatedTaskBase (type, ...args) {
11
+ this.type = type;
12
+ this.args = args;
13
+ }
14
+
15
+ LambdaDelegatedTaskBase.prototype = Object.create(null);
16
+ LambdaDelegatedTaskBase.prototype.constructor = LambdaDelegatedTaskBase;
17
+
18
+ /**
19
+ * Returns type of delegated task
20
+ * @returns {LambdaDelegatedTaskType} type
21
+ */
22
+ LambdaDelegatedTaskBase.prototype.getType = function getType () {
23
+ return this.type;
24
+ };
25
+
26
+ /**
27
+ * Returns delegated task args
28
+ * @returns {Array} args
29
+ */
30
+ LambdaDelegatedTaskBase.prototype.getArgs = function getArgs () {
31
+ return this.args;
32
+ };
33
+
34
+ /**
35
+ * Adds task delegation details to payload
36
+ * @param {JSON} payload
37
+ */
38
+ LambdaDelegatedTaskBase.prototype.addToPayload = function addToPayload (payload = {}) {
39
+ payload[CSEC_TASK_PAYLOAD_IDENTIFIER] = {
40
+ type: this.type,
41
+ args: this.args
42
+ };
43
+ return payload;
44
+ };
45
+
46
+ LambdaDelegatedTaskBase.prototype.handle = function noop () {};
47
+
48
+ module.exports = {
49
+ LambdaDelegatedTaskBase
50
+ };
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright 2023 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ const SHA_CALCULATION = 'sha_calculation';
7
+
8
+ function LambdaDelegatedTaskType () {}
9
+
10
+ LambdaDelegatedTaskType.prototype = Object.create(null);
11
+ LambdaDelegatedTaskType.prototype.constructor = LambdaDelegatedTaskType;
12
+
13
+ LambdaDelegatedTaskType.SHA_CALCULATION = SHA_CALCULATION;
14
+
15
+ module.exports = {
16
+ LambdaDelegatedTaskType
17
+ };
@@ -0,0 +1,31 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
31
+ -----END CERTIFICATE-----
@@ -0,0 +1,19 @@
1
+ /*
2
+ * Copyright 2023 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ const path = require('path');
6
+
7
+ const AGENT_DIR = path.join(__dirname, '../../../');
8
+ const uuidv4 = require('uuid/v4');
9
+ process.env.applicationUUID = process.env.applicationUUID || uuidv4();
10
+
11
+ module.exports = {
12
+ AGENT_DIR,
13
+ ENV: process.env.CSEC_ENV,
14
+ APPLICATION_INFO_PUBLISH_MAX_WAIT: 10000, // milliseconds
15
+ HC_INTERVAL_MS: 300000, // milliseconds
16
+ MAX_PENDING_QUEUE_LENGTH: 1000,
17
+ MAX_EVENT_RATE: 1200, // EVENTS/sec
18
+ DEFAULT_LOG_CHANGETIME: 300000 // milliseconds
19
+ };
@@ -0,0 +1,36 @@
1
+ version: "DEFAULT"
2
+ logLevel: "INFO"
3
+ policyPull: true
4
+ policyPullInterval: 60
5
+ vulnerabilityScan:
6
+ enabled: false
7
+ cveScan:
8
+ enabled: false
9
+ enableEnvScan: false
10
+ cveDefinitionUpdateInterval: 360
11
+ iastScan:
12
+ enabled: false
13
+ probing:
14
+ interval: 1
15
+ batchSize: 17
16
+ protectionMode:
17
+ enabled: false
18
+ ipBlocking:
19
+ enabled: false
20
+ attackerIpBlocking: false
21
+ ipDetectViaXFF: false
22
+ timeout: 2
23
+ apiBlocking:
24
+ enabled: false
25
+ protectAllApis: false
26
+ protectKnownVulnerableApis: false
27
+ protectAttackedApis: false
28
+ sendCompleteStackTrace: false
29
+ enableHTTPRequestPrinting: false
30
+ policyParameters:
31
+ allowedIps: []
32
+ blockedIps: []
33
+ allowedApis: []
34
+ blockedApis: []
35
+ allowedRequests: []
36
+