@newrelic/security-agent 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ### v0.4.0 (2023-10-27)
2
+ #### Features
3
+ * Added event stats for RASP, IAST and exit events in healthcheck.
4
+ #### Miscellaneous chores
5
+ * Deps: Updated uuid to v9.0.1 and @aws-sdk/client-lambda to v3.405.0
6
+ * Upgraded axios to 1.6.0 to resolve CVE-2023-45857
7
+ #### Continuous integration
8
+ * Removed Node.js 14.x from CI.
9
+ * Added should_skip flag to skip CI based on label.
10
+
1
11
  ### v0.3.0 (2023-09-25)
2
12
  #### Features
3
13
  * Last leg acknowledgement in IAST scanning.
@@ -75,7 +75,7 @@ code, the source code can be found at [https://github.com/newrelic/csec-node-age
75
75
 
76
76
  ### @aws-sdk/client-lambda
77
77
 
78
- This product includes source derived from [@aws-sdk/client-lambda](https://github.com/aws/aws-sdk-js-v3) ([v3.379.1](https://github.com/aws/aws-sdk-js-v3/tree/v3.379.1)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.379.1/LICENSE):
78
+ This product includes source derived from [@aws-sdk/client-lambda](https://github.com/aws/aws-sdk-js-v3) ([v3.435.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.435.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.435.0/LICENSE):
79
79
 
80
80
  ```
81
81
  Apache License
@@ -284,28 +284,16 @@ This product includes source derived from [@aws-sdk/client-lambda](https://githu
284
284
 
285
285
  ### axios
286
286
 
287
- This product includes source derived from [axios](https://github.com/axios/axios) ([v0.21.4](https://github.com/axios/axios/tree/v0.21.4)), distributed under the [MIT License](https://github.com/axios/axios/blob/v0.21.4/LICENSE):
287
+ This product includes source derived from [axios](https://github.com/axios/axios) ([v1.6.0](https://github.com/axios/axios/tree/v1.6.0)), distributed under the [MIT License](https://github.com/axios/axios/blob/v1.6.0/LICENSE):
288
288
 
289
289
  ```
290
- Copyright (c) 2014-present Matt Zabriskie
290
+ # Copyright (c) 2014-present Matt Zabriskie & Collaborators
291
291
 
292
- Permission is hereby granted, free of charge, to any person obtaining a copy
293
- of this software and associated documentation files (the "Software"), to deal
294
- in the Software without restriction, including without limitation the rights
295
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
296
- copies of the Software, and to permit persons to whom the Software is
297
- furnished to do so, subject to the following conditions:
292
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
298
293
 
299
- The above copyright notice and this permission notice shall be included in
300
- all copies or substantial portions of the Software.
294
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
301
295
 
302
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
303
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
304
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
305
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
306
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
307
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
308
- THE SOFTWARE.
296
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
309
297
 
310
298
  ```
311
299
 
@@ -790,7 +778,7 @@ THE SOFTWARE.
790
778
 
791
779
  ### uuid
792
780
 
793
- This product includes source derived from [uuid](https://github.com/uuidjs/uuid) ([v9.0.0](https://github.com/uuidjs/uuid/tree/v9.0.0)), distributed under the [MIT License](https://github.com/uuidjs/uuid/blob/v9.0.0/LICENSE.md):
781
+ This product includes source derived from [uuid](https://github.com/uuidjs/uuid) ([v9.0.1](https://github.com/uuidjs/uuid/tree/v9.0.1)), distributed under the [MIT License](https://github.com/uuidjs/uuid/blob/v9.0.1/LICENSE.md):
794
782
 
795
783
  ```
796
784
  The MIT License (MIT)
@@ -180,7 +180,10 @@ function handleFuzzResponse(response, fuzzDetails) {
180
180
  */
181
181
  function parseAxiosHttpRequestToFuzz(requestObject) {
182
182
  let serverName = requestObject.serverName ? requestObject.serverName : LOCALHOST;
183
- let host = serverName + COLON + requestObject.serverPort
183
+ let host = serverName + COLON + requestObject.serverPort;
184
+ if(requestObject.headers && requestObject.headers['content-length']){
185
+ delete requestObject.headers['content-length'];
186
+ }
184
187
  return {
185
188
  url: requestObject.protocol + COLON_SLASH_SLASH + host + requestObject.url,
186
189
  method: requestObject.method,
@@ -17,7 +17,7 @@ const hc = require('../../health-check');
17
17
  const fs = require('fs');
18
18
  const { promisify } = require('../../sec-util');
19
19
  const ResponseHandler = require('./response');
20
- const { EMPTY_APPLICATION_UUID, LOG_MESSAGES, CSEC_SEP, NR_CSEC_FUZZ_REQUEST_ID, EXITEVENT,JSON_NAME, RASP } = require('../../sec-agent-constants');
20
+ const { EMPTY_APPLICATION_UUID, LOG_MESSAGES, CSEC_SEP, NR_CSEC_FUZZ_REQUEST_ID, EXITEVENT, JSON_NAME, RASP } = require('../../sec-agent-constants');
21
21
  const statusUtils = require('../../statusUtils');
22
22
  const commonUtils = require('../../commonUtils');
23
23
  const IASTUtil = require('../websocket/response/IASTUtils');
@@ -228,12 +228,14 @@ SecWebSocket.prototype.dispatch = async function dispatch(event) {
228
228
  await promisify(this.instance, this.instance.send)(eventStr, { mask: true }, () => {
229
229
  logger.debug(LOG_MESSAGES.EVENT_SENT + eventStr);
230
230
  if (event.jsonName == JSON_NAME.EVENT) {
231
- if (NRAgent.config.security.mode == RASP) {
232
- hc.getInstance().raspEventStats.sent++;
231
+
232
+ if (event.httpRequest && event.httpRequest.headers[NR_CSEC_FUZZ_REQUEST_ID]) {
233
+ hc.getInstance().iastEventStats.sent++;
233
234
  }
234
235
  else {
235
- hc.getInstance().iastEventStats.sent++;
236
+ hc.getInstance().raspEventStats.sent++;
236
237
  }
238
+
237
239
  }
238
240
  if (event.jsonName == EXITEVENT) {
239
241
  hc.getInstance().exitEventStats.sent++;
@@ -318,12 +320,13 @@ const handleDispatchFailure = (self, event, eventStr) => {
318
320
  // so feeding an old applicationinfo JSON would be incorrect
319
321
  if (eventStr && event.jsonName !== APPLICATION_INFO_JSON_NAME) {
320
322
  hc.getInstance().registerEventDrop();
321
- if (NRAgent.config.security.mode == "RASP") {
322
- hc.getInstance().raspEventStats.errorCount++;
323
+ if (event.httpRequest && event.httpRequest.headers[NR_CSEC_FUZZ_REQUEST_ID]) {
324
+ hc.getInstance().iastEventStats.errorCount++;
323
325
  }
324
326
  else {
325
- hc.getInstance().iastEventStats.errorCount++;
327
+ hc.getInstance().raspEventStats.errorCount++;
326
328
  }
329
+
327
330
  }
328
331
  };
329
332
 
@@ -66,13 +66,13 @@ const sleep = (timeout) => new Promise((resolve) => {
66
66
  function generateSecEvent(securityMetadata) {
67
67
  const traceObject = securityMetadata.traceObject;
68
68
  const request = securityMetadata.request;
69
- if (NRAgent.config.security.mode == RASP) {
70
- HC.getInstance().raspEventStats.processed++;
71
- }
72
- else {
69
+
70
+ if(request && request.headers[NR_CSEC_FUZZ_REQUEST_ID]){
73
71
  HC.getInstance().iastEventStats.processed++;
74
72
  }
75
-
73
+ else{
74
+ HC.getInstance().raspEventStats.processed++;
75
+ }
76
76
  try {
77
77
  let stakTrace = traceObject.stacktrace;
78
78
  let uri = EMPTY_STR;
@@ -102,12 +102,13 @@ function generateSecEvent(securityMetadata) {
102
102
  } catch (e) {
103
103
  statusUtils.addErrortoBuffer(e);
104
104
  logger.error("Error in generating event:", e);
105
- if (NRAgent.config.security.mode == RASP) {
106
- HC.getInstance().raspEventStats.errorCount++;
107
- }
108
- else {
105
+
106
+ if(request && request.headers[NR_CSEC_FUZZ_REQUEST_ID]){
109
107
  HC.getInstance().iastEventStats.errorCount++;
110
108
  }
109
+ else{
110
+ HC.getInstance().raspEventStats.errorCount++;
111
+ }
111
112
  }
112
113
 
113
114
  }
@@ -23,7 +23,7 @@ const {
23
23
  }
24
24
  } = require('./connections/websocket');
25
25
  const { HC_INTERVAL_MS } = require('../../resources/config');
26
- const { LOG_DIR } = require('./sec-agent-constants');
26
+ const { LOG_DIR, EXITEVENT, JSON_NAME } = require('./sec-agent-constants');
27
27
  const statusUtils = require('./statusUtils');
28
28
  const njsAgentConstants = require('./sec-agent-constants');
29
29
 
@@ -100,6 +100,7 @@ const sendHC = async function () {
100
100
  json = JSON.parse(json);
101
101
  json.policyVersion = applicationInfo.policyVersion;
102
102
  json.entityGuid = applicationInfo.entityGuid;
103
+
103
104
  try {
104
105
  json.stats = await commonUtils.getHCStats();
105
106
  } catch (error) {
@@ -114,6 +115,12 @@ const sendHC = async function () {
114
115
  json.serviceStatus.agentActiveStat = commonUtils.isAgentActiveState();
115
116
  json.serviceStatus.iastRestClient = commonUtils.iastRestClientStatus();
116
117
 
118
+ json.exitEventSentCount = json.exitEventStats.sent;
119
+ json.eventRejectionCount = json.raspEventStats.rejected + json.iastEventStats.rejected;
120
+ json.eventProcessingErrorCount = json.raspEventStats.errorCount + json.iastEventStats.errorCount;
121
+ json.eventSendRejectionCount = json.eventRejectionCount;
122
+ json.eventSendErrorCount = json.eventProcessingErrorCount;
123
+
117
124
  hc.getInstance().resetDropCount();
118
125
  hc.getInstance().resetProcessedCount();
119
126
  hc.getInstance().resetEventSentCount();
@@ -134,13 +141,13 @@ const sendHC = async function () {
134
141
  */
135
142
  function getDispatcherAndSendEvent(eventJson) {
136
143
  const eventType = eventJson.jsonName;
137
- if (eventType === 'Event') {
144
+ if (eventType === JSON_NAME.EVENT || eventType === EXITEVENT) {
138
145
  hc.getInstance().registerEventProcessed();
139
146
  }
140
147
 
141
148
  dispatcher(eventJson);
142
149
 
143
- if (eventType === 'Event') {
150
+ if (eventType === JSON_NAME.EVENT || eventType === EXITEVENT) {
144
151
  hc.getInstance().registerEventSent();
145
152
  }
146
153
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newrelic/security-agent",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "New Relic Security Agent for Node.js",
5
5
  "main": "index.js",
6
6
  "jsonVersion": "1.1.0",
@@ -35,8 +35,8 @@
35
35
  "url": "https://github.com/newrelic/csec-node-agent.git"
36
36
  },
37
37
  "dependencies": {
38
- "@aws-sdk/client-lambda": "^3.363.0",
39
- "axios": "0.21.4",
38
+ "@aws-sdk/client-lambda": "^3.405.0",
39
+ "axios": "1.6.0",
40
40
  "check-disk-space": "3.3.1",
41
41
  "content-type": "^1.0.5",
42
42
  "fast-safe-stringify": "^2.1.1",
@@ -55,7 +55,7 @@
55
55
  "sync-request": "^6.1.0",
56
56
  "unescape": "^1.0.1",
57
57
  "unescape-js": "^1.1.4",
58
- "uuid": "^9.0.0",
58
+ "uuid": "^9.0.1",
59
59
  "ws": "^7.5.9"
60
60
  },
61
61
  "devDependencies": {