@contrast/agent 4.20.2 → 4.21.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.
@@ -28,7 +28,7 @@ class HapiAssessSources {
28
28
  * Handles emitting of all assess source events
29
29
  */
30
30
  registerSourcesHandler() {
31
- agentEmitter.on(EVENTS.HAPI_PRE_HANDLER, ({ request }) => {
31
+ agentEmitter.on(EVENTS.HAPI_POST_AUTH, ({ request }) => {
32
32
  emitWatchableObjects(request);
33
33
  });
34
34
  }
@@ -1000,6 +1000,12 @@
1000
1000
  "methodName": "isCreditCard",
1001
1001
  "isModule": true
1002
1002
  },
1003
+ "validator.isDate": {
1004
+ "moduleName": "validator",
1005
+ "version": ">=13.0.0",
1006
+ "methodName": "isDecimal",
1007
+ "isModule": true
1008
+ },
1003
1009
  "validator.isDecimal": {
1004
1010
  "moduleName": "validator",
1005
1011
  "version": ">=13.0.0",
@@ -1018,6 +1024,12 @@
1018
1024
  "methodName": "isEAN",
1019
1025
  "isModule": true
1020
1026
  },
1027
+ "validator.isEmail": {
1028
+ "moduleName": "validator",
1029
+ "version": ">=13.0.0",
1030
+ "methodName": "isEmail",
1031
+ "isModule": true
1032
+ },
1021
1033
  "validator.isEthereumAddress": {
1022
1034
  "moduleName": "validator",
1023
1035
  "version": ">=13.0.0",
@@ -39,11 +39,11 @@ const agent = require('../../../agent');
39
39
  * https://docs.google.com/spreadsheets/d/17p5C6NOISNuWi8D-07d8gNg8byQytuwjtgBgzGpfU_w/edit#gid=0
40
40
  *
41
41
  */
42
- module.exports.handle = function() {
42
+ module.exports.handle = function () {
43
43
  const {
44
44
  validators,
45
45
  untrackers,
46
- sanitizers
46
+ sanitizers,
47
47
  } = require('./validator-methods.js');
48
48
 
49
49
  const patchType = PATCH_TYPES.ASSESS_PROPAGATOR;
@@ -62,7 +62,7 @@ module.exports.handle = function() {
62
62
  const patched = patcher.patch(obj, {
63
63
  name,
64
64
  patchType,
65
- post
65
+ post,
66
66
  });
67
67
  // babel adds a self-referential default property so if present in the unpatched
68
68
  // object update the patched object
@@ -89,7 +89,12 @@ module.exports.handle = function() {
89
89
  { name: 'validator', file: `lib/${validator}` },
90
90
  (index, meta) => {
91
91
  function post(data) {
92
- if (data.result && (validator !== 'matches' || (validator === 'matches' && agent.config.assess.trust_custom_validators))) {
92
+ if (
93
+ data.result &&
94
+ (validator !== 'matches' ||
95
+ (validator === 'matches' &&
96
+ agent.config.assess.trust_custom_validators))
97
+ ) {
93
98
  const trackingData = tracker.getData(data.args[0]);
94
99
  if (trackingData) {
95
100
  tagRangeUtil.addInPlace(
@@ -104,7 +109,7 @@ module.exports.handle = function() {
104
109
  signature,
105
110
  tagRanges: trackingData.tagRanges,
106
111
  source: 'O',
107
- target: 'R'
112
+ target: 'R',
108
113
  });
109
114
 
110
115
  event.parents.push(trackingData.event);
@@ -210,4 +215,38 @@ module.exports.handle = function() {
210
215
  }
211
216
  );
212
217
  }
218
+
219
+ moduleHook.resolve({ name: 'validator', file: 'lib/isEmail' }, (isEmail) => {
220
+ const signature = new Signature('validator.isEmail');
221
+
222
+ function post(data) {
223
+ const trackingData = tracker.getData(data.args[0]);
224
+ // The default options for the two fields of interest are:
225
+ // `{ allow_display_name: false, require_display_name: false }`
226
+ // so we can use an empty object as it will also yield
227
+ // falsy values for these two fields
228
+ const options = data.args[1] ? data.args[1] : {};
229
+ if (data.result && trackingData && !options.allow_display_name && !options.require_display_name) {
230
+ tagRangeUtil.addInPlace(
231
+ trackingData.tagRanges,
232
+ new TagRange(0, data.args[0].length - 1, 'limited-chars')
233
+ );
234
+ tagRangeUtil.removeInPlace(trackingData.tagRanges, ['untrusted']);
235
+
236
+ const context = new CallContext(data);
237
+ const event = new PropagationEvent({
238
+ context,
239
+ signature,
240
+ tagRanges: trackingData.tagRanges,
241
+ source: 'O',
242
+ target: 'R',
243
+ });
244
+
245
+ event.parents.push(trackingData.event);
246
+ trackingData.event = event;
247
+ }
248
+ }
249
+
250
+ return patch(isEmail, 'isEmail', post);
251
+ });
213
252
  };
@@ -32,6 +32,7 @@ module.exports = {
32
32
  isBoolean: 'limited-chars',
33
33
  isBtcAddress: 'alphanum-space-hyphen',
34
34
  isCreditCard: 'limited-chars',
35
+ isDate: 'limited-chars',
35
36
  isDecimal: 'limited-chars',
36
37
  // calls toFloat() which calls isFloat() so no need to hook.
37
38
  //isDivisibleBy: 'limited-chars',
@@ -88,5 +89,10 @@ module.exports = {
88
89
  escape: 'html-encoded'
89
90
  // toFloat uses isFloat which is hooked, so no need to do so again
90
91
  // toFloat: 'limited-chars'
92
+ },
93
+ customLogic: {
94
+ // this value is not used and it's added just for storing the information
95
+ // about what's patched in one place
96
+ isEmail: 'limited-chars'
91
97
  }
92
98
  };
@@ -42,6 +42,7 @@ const constants = {
42
42
  HAPI_ROUTES: 'hapi-routes', // used to instrument registered routes
43
43
  HAPI_ADD_ROUTE: 'hapi-add-route', // used to instrument adding a route
44
44
  HAPI_PRE_AUTH: 'hapi-pre-auth', // used to implement hapi onPreAuth hooks
45
+ HAPI_POST_AUTH: 'hapi-post-auth', // uses to implement hapi onPostAuth hooks
45
46
  HAPI_PRE_HANDLER: 'hapi-pre-handler', // used to implement hapi onPreHandler hooks
46
47
  HAPI_FINISHED: 'hapi-response-finished', // used to implement when hapi response is finished
47
48
  HAPI_PRE_RES: 'hapi-pre-response', // used to implement hapi onPreResponse hooks
@@ -162,12 +163,13 @@ class HapiCore {
162
163
  return h.continue;
163
164
  });
164
165
 
165
- server.ext('onPreHandler', function onPreHandler(request, h) {
166
- agentEmitter.emit(constants.EVENTS.HAPI_PRE_HANDLER, {
166
+ server.ext('onPostAuth', function onPostAuth(request, h) {
167
+ agentEmitter.emit(constants.EVENTS.HAPI_POST_AUTH, {
167
168
  request,
168
169
  h,
169
170
  server
170
171
  });
172
+
171
173
  // Update the domain's model of the request with body and params since it has been
172
174
  // fully parsed and validated
173
175
  decorateRequest({
@@ -176,6 +178,17 @@ class HapiCore {
176
178
  parameters: request.params,
177
179
  query: request.query
178
180
  });
181
+
182
+ return h.continue;
183
+ });
184
+
185
+ server.ext('onPreHandler', function onPreHandler(request, h) {
186
+ agentEmitter.emit(constants.EVENTS.HAPI_PRE_HANDLER, {
187
+ request,
188
+ h,
189
+ server
190
+ });
191
+
179
192
  return h.continue;
180
193
  });
181
194
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/agent",
3
- "version": "4.20.2",
3
+ "version": "4.21.0",
4
4
  "description": "Node.js security instrumentation by Contrast Security",
5
5
  "keywords": [
6
6
  "security",