@contrast/assess 1.3.0 → 1.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.
@@ -28,12 +28,13 @@ module.exports = function(core) {
28
28
  };
29
29
 
30
30
  require('./concat')(core);
31
+ require('./format-methods')(core);
32
+ require('./html-methods')(core);
33
+ require('./match')(core);
31
34
  require('./replace')(core);
35
+ require('./split')(core);
32
36
  require('./substring')(core);
33
37
  require('./trim')(core);
34
- require('./html-methods')(core);
35
- require('./format-methods')(core);
36
- require('./split')(core);
37
38
 
38
39
  return stringInstrumentation;
39
40
  };
@@ -0,0 +1,122 @@
1
+ /*
2
+ * Copyright: 2022 Contrast Security, Inc
3
+ * Contact: support@contrastsecurity.com
4
+ * License: Commercial
5
+
6
+ * NOTICE: This Software and the patented inventions embodied within may only be
7
+ * used as part of Contrast Security’s commercial offerings. Even though it is
8
+ * made available through public repositories, use of this Software is subject to
9
+ * the applicable End User Licensing Agreement found at
10
+ * https://www.contrastsecurity.com/enduser-terms-0317a or as otherwise agreed
11
+ * between Contrast Security and the End User. The Software may not be reverse
12
+ * engineered, modified, repackaged, sold, redistributed or otherwise used in a
13
+ * way not consistent with the End User License Agreement.
14
+ */
15
+
16
+ 'use strict';
17
+ const { join } = require('@contrast/common');
18
+ const { patchType } = require('../../common');
19
+ const { createSubsetTags } = require('../../../tag-utils');
20
+
21
+ module.exports = function(core) {
22
+ const {
23
+ scopes: { sources, instrumentation },
24
+ patcher,
25
+ assess: {
26
+ dataflow: { tracker, eventFactory: { createPropagationEvent } }
27
+ }
28
+ } = core;
29
+
30
+ function getPropagationEvent(data, res, objInfo, start) {
31
+ const { name, args, result, hooked, orig } = data;
32
+ const tags = createSubsetTags(objInfo.tags, start, res.length - 1);
33
+ if (!tags) return;
34
+
35
+ return createPropagationEvent({
36
+ name,
37
+ history: [objInfo],
38
+ object: {
39
+ value: objInfo.value,
40
+ isTracked: true,
41
+ },
42
+ args: args.map((arg) => {
43
+ const argInfo = tracker.getData(arg);
44
+ return {
45
+ value: argInfo ? argInfo.value : arg.toString(),
46
+ isTracked: !!argInfo
47
+ };
48
+ }),
49
+ tags,
50
+ result: {
51
+ value: join(result),
52
+ isTracked: false
53
+ },
54
+ stacktraceOpts: {
55
+ constructorOpt: hooked,
56
+ prependFrames: [orig]
57
+ },
58
+ source: 'O',
59
+ target: 'R'
60
+ });
61
+ }
62
+
63
+ return core.assess.dataflow.propagation.stringInstrumentation.match = {
64
+ install() {
65
+ const name = 'String.prototype.match';
66
+
67
+ patcher.patch(String.prototype, 'match', {
68
+ name,
69
+ patchType,
70
+ post(data) {
71
+ const { args, obj, result } = data;
72
+ if (
73
+ !obj ||
74
+ !result ||
75
+ args.length === 0 ||
76
+ result.length === 0 ||
77
+ !sources.getStore() ||
78
+ typeof obj !== 'string' ||
79
+ instrumentation.isLocked() ||
80
+ (args.length === 1 && args[0] == null)
81
+ ) return;
82
+
83
+ const objInfo = tracker.getData(obj);
84
+ if (!objInfo) return;
85
+
86
+ let idx = 0;
87
+ const hasCaptureGroups = 'groups' in result;
88
+ for (let i = 0; i < result.length; i++) {
89
+ const res = result[i];
90
+ if (!res) continue;
91
+ const start = obj.indexOf(res, idx);
92
+ idx += hasCaptureGroups ? 0 : res.length;
93
+ const event = getPropagationEvent(data, res, objInfo, start);
94
+ if (event) {
95
+ const { extern } = tracker.track(res, event);
96
+ if (extern) {
97
+ data.result[i] = extern;
98
+ }
99
+ }
100
+ }
101
+ if (hasCaptureGroups && result.groups) {
102
+ Object.keys(result.groups).forEach((key) => {
103
+ const res = result.groups[key];
104
+ if (!res) return;
105
+ const start = obj.indexOf(res);
106
+ const event = getPropagationEvent(data, res, objInfo, start);
107
+ if (event) {
108
+ const { extern } = tracker.track(res, event);
109
+ if (extern) {
110
+ data.result.groups[key] = extern;
111
+ }
112
+ }
113
+ });
114
+ }
115
+ },
116
+ });
117
+ },
118
+ uninstall() {
119
+ String.prototype.match = patcher.unwrap(String.prototype.match);
120
+ },
121
+ };
122
+ };
@@ -933,6 +933,16 @@ module.exports = function(core) {
933
933
  target: 'R'
934
934
  }
935
935
  ],
936
+ [
937
+ 'String.prototype.match',
938
+ {
939
+ moduleName: 'String',
940
+ methodName: 'prototype.match',
941
+ isModule: false,
942
+ source: 'O',
943
+ target: 'R'
944
+ }
945
+ ],
936
946
  [
937
947
  'sqlite3.Database.prototype.all',
938
948
  {
@@ -132,43 +132,15 @@ module.exports = function(core) {
132
132
  }
133
133
 
134
134
  function install() {
135
- [{
136
- moduleName: 'http'
137
- },
138
- {
139
- moduleName: 'https'
140
- },
141
- {
142
- moduleName: 'spdy'
143
- },
144
- {
145
- moduleName: 'http2',
146
- patchObjectsProps: [
147
- {
148
- methods: ['createServer', 'createSecureServer'],
149
- patchType,
150
- patchObjects: [
151
- {
152
- name: 'Server.prototype',
153
- methods: ['emit'],
154
- patchType,
155
- around
156
- }
157
- ]
158
- }
159
- ]
160
- }].forEach(({ moduleName, patchObjectsProps }) => {
161
- const patchObjects = patchObjectsProps || [
162
- {
135
+ ['http', 'https', 'spdy', 'http2'].forEach((moduleName) => {
136
+ instrument({
137
+ moduleName,
138
+ patchObjects: [{
163
139
  name: 'Server.prototype',
164
140
  methods: ['emit'],
165
141
  patchType,
166
142
  around
167
- }
168
- ];
169
- instrument({
170
- moduleName,
171
- patchObjects
143
+ }]
172
144
  });
173
145
  });
174
146
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/assess",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -15,7 +15,7 @@
15
15
  "dependencies": {
16
16
  "@contrast/distringuish": "^4.1.0",
17
17
  "@contrast/scopes": "1.3.0",
18
- "@contrast/common": "1.6.0",
18
+ "@contrast/common": "1.7.0",
19
19
  "parseurl": "^1.3.3"
20
20
  }
21
21
  }