@keithadler/frostjs 0.1.0 → 0.3.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/README.md +98 -8
- package/dist/audit.d.ts +71 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +202 -0
- package/dist/audit.js.map +1 -0
- package/dist/capabilities.d.ts +22 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +140 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/cli/args.d.ts +4 -3
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +23 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +99 -5
- package/dist/cli/run.js.map +1 -1
- package/dist/extract/html.d.ts +11 -0
- package/dist/extract/html.d.ts.map +1 -1
- package/dist/extract/html.js +58 -0
- package/dist/extract/html.js.map +1 -1
- package/dist/extract/index.d.ts +2 -0
- package/dist/extract/index.d.ts.map +1 -1
- package/dist/extract/index.js +19 -0
- package/dist/extract/index.js.map +1 -1
- package/dist/extract/recognizers/device.d.ts +10 -0
- package/dist/extract/recognizers/device.d.ts.map +1 -0
- package/dist/extract/recognizers/device.js +46 -0
- package/dist/extract/recognizers/device.js.map +1 -0
- package/dist/extract/recognizers/dom-escape.d.ts.map +1 -1
- package/dist/extract/recognizers/dom-escape.js +11 -0
- package/dist/extract/recognizers/dom-escape.js.map +1 -1
- package/dist/extract/recognizers/message.d.ts +16 -0
- package/dist/extract/recognizers/message.d.ts.map +1 -0
- package/dist/extract/recognizers/message.js +92 -0
- package/dist/extract/recognizers/message.js.map +1 -0
- package/dist/extract/recognizers/network.d.ts +10 -2
- package/dist/extract/recognizers/network.d.ts.map +1 -1
- package/dist/extract/recognizers/network.js +49 -6
- package/dist/extract/recognizers/network.js.map +1 -1
- package/dist/extract/taint.d.ts +36 -0
- package/dist/extract/taint.d.ts.map +1 -0
- package/dist/extract/taint.js +503 -0
- package/dist/extract/taint.js.map +1 -0
- package/dist/extract/target.d.ts.map +1 -1
- package/dist/extract/target.js +23 -1
- package/dist/extract/target.js.map +1 -1
- package/dist/policy/compile.d.ts +3 -1
- package/dist/policy/compile.d.ts.map +1 -1
- package/dist/policy/compile.js +1 -0
- package/dist/policy/compile.js.map +1 -1
- package/dist/policy/index.js +1 -1
- package/dist/policy/index.js.map +1 -1
- package/dist/policy/parse.d.ts +2 -0
- package/dist/policy/parse.d.ts.map +1 -1
- package/dist/policy/parse.js +11 -1
- package/dist/policy/parse.js.map +1 -1
- package/dist/policy/vocabulary.d.ts.map +1 -1
- package/dist/policy/vocabulary.js +20 -0
- package/dist/policy/vocabulary.js.map +1 -1
- package/dist/report/summary.d.ts.map +1 -1
- package/dist/report/summary.js +2 -0
- package/dist/report/summary.js.map +1 -1
- package/dist/report/text.d.ts.map +1 -1
- package/dist/report/text.js +5 -0
- package/dist/report/text.js.map +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded taint analysis: does untrusted input reach a dangerous sink?
|
|
3
|
+
*
|
|
4
|
+
* frostjs's recognizers say "this file can eval" or "this file reaches
|
|
5
|
+
* host X". Taint answers the harder question: does a value that came from
|
|
6
|
+
* an attacker-influenced source (a URL parameter, document.cookie, a
|
|
7
|
+
* postMessage payload) actually flow into eval, innerHTML, importScripts,
|
|
8
|
+
* a redirect, and so on. That is the difference between a capability and a
|
|
9
|
+
* vulnerability, and it is what the three.js/ECSY finding was underneath:
|
|
10
|
+
* `location.search` gated a path that eval'd relay data.
|
|
11
|
+
*
|
|
12
|
+
* The one rule that keeps this from crying wolf: **taint survives only
|
|
13
|
+
* through operations that provably preserve it** - string methods, URL
|
|
14
|
+
* decoding, JSON.parse, template concatenation, member access. Any other
|
|
15
|
+
* function call breaks the chain, so `el.innerHTML = DOMPurify.sanitize(x)`
|
|
16
|
+
* is not flagged while `el.innerHTML = x` is. Flow is followed within a
|
|
17
|
+
* function (with closure inheritance and message-handler seeding) and one
|
|
18
|
+
* hop across a call: a tainted argument to a local function whose parameter
|
|
19
|
+
* reaches a sink. A whole call graph is not walked, and that is stated as a
|
|
20
|
+
* limit rather than hidden.
|
|
21
|
+
*/
|
|
22
|
+
import { positionAt } from "./ast.js";
|
|
23
|
+
import { analyzeScopes } from "./scope.js";
|
|
24
|
+
import { FOLDED, FREE } from "./annotations.js";
|
|
25
|
+
import { isIdentifier, memberName } from "./recognizers/resolve.js";
|
|
26
|
+
/** The global objects a source can hang off. */
|
|
27
|
+
const GLOBALS = new Set(["window", "globalThis", "self"]);
|
|
28
|
+
/**
|
|
29
|
+
* location members that carry attacker-influenced text. Narrowed to the
|
|
30
|
+
* parts an attacker actually controls (the query, fragment, full URL and
|
|
31
|
+
* path); host/hostname/origin/protocol are the page's own identity and
|
|
32
|
+
* are rarely an injection vector, so they are left out to protect the
|
|
33
|
+
* zero-false-positive property.
|
|
34
|
+
*/
|
|
35
|
+
const LOCATION_PROPS = new Set(["search", "hash", "href", "pathname"]);
|
|
36
|
+
/** document members that carry attacker-influenced text. */
|
|
37
|
+
const DOCUMENT_PROPS = new Set(["URL", "documentURI", "referrer", "cookie", "baseURI"]);
|
|
38
|
+
/** String and URL operations that preserve taint: `t.<method>(...)` stays tainted. */
|
|
39
|
+
const PRESERVING_METHODS = new Set([
|
|
40
|
+
"replace",
|
|
41
|
+
"replaceAll",
|
|
42
|
+
"slice",
|
|
43
|
+
"substring",
|
|
44
|
+
"substr",
|
|
45
|
+
"trim",
|
|
46
|
+
"trimStart",
|
|
47
|
+
"trimEnd",
|
|
48
|
+
"toLowerCase",
|
|
49
|
+
"toUpperCase",
|
|
50
|
+
"toString",
|
|
51
|
+
"split",
|
|
52
|
+
"concat",
|
|
53
|
+
"padStart",
|
|
54
|
+
"padEnd",
|
|
55
|
+
"normalize",
|
|
56
|
+
"at",
|
|
57
|
+
"charAt",
|
|
58
|
+
"repeat",
|
|
59
|
+
"get",
|
|
60
|
+
"getAll",
|
|
61
|
+
"toJSON",
|
|
62
|
+
]);
|
|
63
|
+
/** Global functions that preserve taint on their first argument. */
|
|
64
|
+
const PRESERVING_CALLS = new Set([
|
|
65
|
+
"decodeURIComponent",
|
|
66
|
+
"decodeURI",
|
|
67
|
+
"encodeURIComponent",
|
|
68
|
+
"encodeURI",
|
|
69
|
+
"atob",
|
|
70
|
+
"escape",
|
|
71
|
+
"unescape",
|
|
72
|
+
"String",
|
|
73
|
+
]);
|
|
74
|
+
const isNode = (v) => typeof v === "object" && v !== null && typeof v.type === "string";
|
|
75
|
+
/** Strip TS value wrappers and parentheses. */
|
|
76
|
+
function unwrap(n) {
|
|
77
|
+
let c = n;
|
|
78
|
+
while (c.type === "ParenthesizedExpression" ||
|
|
79
|
+
c.type === "TSAsExpression" ||
|
|
80
|
+
c.type === "TSNonNullExpression" ||
|
|
81
|
+
c.type === "TSSatisfiesExpression" ||
|
|
82
|
+
c.type === "TSTypeAssertion") {
|
|
83
|
+
c = c["expression"];
|
|
84
|
+
}
|
|
85
|
+
return c;
|
|
86
|
+
}
|
|
87
|
+
/** A free reference to one of `names`. */
|
|
88
|
+
function freeGlobal(n, names) {
|
|
89
|
+
return isIdentifier(n) && names.has(n.name) && n[FREE] === true;
|
|
90
|
+
}
|
|
91
|
+
/** `location`, `window.location`, `document.location`, `self.location`. */
|
|
92
|
+
function isLocation(n) {
|
|
93
|
+
n = unwrap(n);
|
|
94
|
+
if (freeGlobal(n, new Set(["location"])))
|
|
95
|
+
return true;
|
|
96
|
+
if (n.type === "MemberExpression" && memberName(n) === "location") {
|
|
97
|
+
const obj = unwrap(n["object"]);
|
|
98
|
+
return freeGlobal(obj, GLOBALS) || freeGlobal(obj, new Set(["document"]));
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
/** A member read that is itself an untrusted source; returns a label or null. */
|
|
103
|
+
function sourceMember(n) {
|
|
104
|
+
if (n.type !== "MemberExpression")
|
|
105
|
+
return null;
|
|
106
|
+
const prop = memberName(n);
|
|
107
|
+
if (prop === null)
|
|
108
|
+
return null;
|
|
109
|
+
const obj = unwrap(n["object"]);
|
|
110
|
+
if (LOCATION_PROPS.has(prop) && isLocation(obj))
|
|
111
|
+
return `location.${prop}`;
|
|
112
|
+
if (DOCUMENT_PROPS.has(prop) && freeGlobal(obj, new Set(["document"])))
|
|
113
|
+
return `document.${prop}`;
|
|
114
|
+
if (prop === "name" && freeGlobal(obj, GLOBALS))
|
|
115
|
+
return "window.name";
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
/** Does `n` evaluate to a tainted value under the current scope? Also reports which source, when asked. */
|
|
119
|
+
function taintSource(n, scope) {
|
|
120
|
+
n = unwrap(n);
|
|
121
|
+
switch (n.type) {
|
|
122
|
+
case "Identifier":
|
|
123
|
+
return scope.tainted.has(n.name) ? (scope.sources.get(n.name) ?? "untrusted input") : null;
|
|
124
|
+
case "MemberExpression": {
|
|
125
|
+
const direct = sourceMember(n);
|
|
126
|
+
if (direct)
|
|
127
|
+
return direct;
|
|
128
|
+
// t.foo / t[i]: a member of a tainted object is tainted.
|
|
129
|
+
return taintSource(n["object"], scope);
|
|
130
|
+
}
|
|
131
|
+
case "BinaryExpression":
|
|
132
|
+
return n["operator"] === "+"
|
|
133
|
+
? (taintSource(n["left"], scope) ?? taintSource(n["right"], scope))
|
|
134
|
+
: null;
|
|
135
|
+
case "TemplateLiteral": {
|
|
136
|
+
for (const e of n["expressions"]) {
|
|
137
|
+
const s = taintSource(e, scope);
|
|
138
|
+
if (s)
|
|
139
|
+
return s;
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
case "ConditionalExpression":
|
|
144
|
+
return taintSource(n["consequent"], scope) ?? taintSource(n["alternate"], scope);
|
|
145
|
+
case "AwaitExpression":
|
|
146
|
+
case "YieldExpression":
|
|
147
|
+
return n["argument"] ? taintSource(n["argument"], scope) : null;
|
|
148
|
+
case "AssignmentExpression":
|
|
149
|
+
return taintSource(n["right"], scope);
|
|
150
|
+
case "SequenceExpression": {
|
|
151
|
+
const exprs = n["expressions"];
|
|
152
|
+
return exprs.length ? taintSource(exprs[exprs.length - 1], scope) : null;
|
|
153
|
+
}
|
|
154
|
+
case "NewExpression":
|
|
155
|
+
// new URLSearchParams(tainted) / new URL(tainted) is a tainted object.
|
|
156
|
+
if (isIdentifier(n["callee"], "URLSearchParams") || isIdentifier(n["callee"], "URL")) {
|
|
157
|
+
for (const a of n["arguments"]) {
|
|
158
|
+
const s = taintSource(a, scope);
|
|
159
|
+
if (s)
|
|
160
|
+
return s;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return null;
|
|
164
|
+
case "CallExpression": {
|
|
165
|
+
const callee = unwrap(n["callee"]);
|
|
166
|
+
const args = n["arguments"];
|
|
167
|
+
// preserving global call: decodeURIComponent(tainted), JSON.parse(tainted)
|
|
168
|
+
if (isIdentifier(callee) && PRESERVING_CALLS.has(callee.name))
|
|
169
|
+
return taintSource(args[0] ?? callee, scope);
|
|
170
|
+
if (callee.type === "MemberExpression") {
|
|
171
|
+
const method = memberName(callee);
|
|
172
|
+
const recv = callee["object"];
|
|
173
|
+
if (method === "parse" && isIdentifier(unwrap(recv), "JSON"))
|
|
174
|
+
return taintSource(args[0] ?? callee, scope);
|
|
175
|
+
// preserving method on a tainted receiver: location.hash.slice(1), params.get('x')
|
|
176
|
+
if (method !== null && PRESERVING_METHODS.has(method))
|
|
177
|
+
return taintSource(recv, scope);
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
default:
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/** The sinks: a tainted value here is markup, code, a remote load, or a redirect. */
|
|
186
|
+
function checkSinks(n, scope, add) {
|
|
187
|
+
// assignment sinks: el.innerHTML = tainted, location.href = tainted, setAttribute-less
|
|
188
|
+
if (n.type === "AssignmentExpression") {
|
|
189
|
+
const left = unwrap(n["left"]);
|
|
190
|
+
const right = n["right"];
|
|
191
|
+
if (left.type === "MemberExpression") {
|
|
192
|
+
const prop = memberName(left);
|
|
193
|
+
if (prop === "innerHTML" || prop === "outerHTML" || prop === "srcdoc") {
|
|
194
|
+
const s = taintSource(right, scope);
|
|
195
|
+
if (s)
|
|
196
|
+
add(s, prop, n);
|
|
197
|
+
}
|
|
198
|
+
// location = tainted, location.href = tainted
|
|
199
|
+
if ((prop !== null && LOCATION_PROPS.has(prop) && isLocation(left["object"])) || isLocation(left)) {
|
|
200
|
+
const s = taintSource(right, scope);
|
|
201
|
+
if (s)
|
|
202
|
+
add(s, "location (redirect)", n);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (n.type === "CallExpression" || n.type === "NewExpression" || n.type === "ImportExpression") {
|
|
207
|
+
const args = n["arguments"] ?? [];
|
|
208
|
+
const src = n.type === "ImportExpression" ? n["source"] : undefined;
|
|
209
|
+
const callee = n.type === "ImportExpression" ? null : unwrap(n["callee"]);
|
|
210
|
+
const flag = (arg, sink) => {
|
|
211
|
+
if (!arg)
|
|
212
|
+
return;
|
|
213
|
+
const s = taintSource(arg, scope);
|
|
214
|
+
if (s)
|
|
215
|
+
add(s, sink, n);
|
|
216
|
+
};
|
|
217
|
+
if (n.type === "ImportExpression")
|
|
218
|
+
return flag(src, "import()");
|
|
219
|
+
if (callee === null)
|
|
220
|
+
return;
|
|
221
|
+
if (isIdentifier(callee, "eval"))
|
|
222
|
+
return flag(args[0], "eval");
|
|
223
|
+
if (isIdentifier(callee, "Function"))
|
|
224
|
+
return flag(args[args.length - 1], "Function");
|
|
225
|
+
if (isIdentifier(callee, "importScripts"))
|
|
226
|
+
return args.forEach((a) => flag(a, "importScripts"));
|
|
227
|
+
// A tainted first argument to a timer is a string, so it is the string-code
|
|
228
|
+
// form (setTimeout("...", n)); a function callback is never tainted.
|
|
229
|
+
if (isIdentifier(callee, "setTimeout") || isIdentifier(callee, "setInterval"))
|
|
230
|
+
return flag(args[0], callee.name);
|
|
231
|
+
if (callee.type === "MemberExpression") {
|
|
232
|
+
const method = memberName(callee);
|
|
233
|
+
const obj = callee["object"];
|
|
234
|
+
if (method === "eval")
|
|
235
|
+
return flag(args[0], "eval");
|
|
236
|
+
if ((method === "setTimeout" || method === "setInterval") && freeGlobal(unwrap(obj), GLOBALS))
|
|
237
|
+
return flag(args[0], method);
|
|
238
|
+
if (method === "importScripts")
|
|
239
|
+
return args.forEach((a) => flag(a, "importScripts"));
|
|
240
|
+
if (method === "insertAdjacentHTML")
|
|
241
|
+
return flag(args[1], "insertAdjacentHTML");
|
|
242
|
+
if (method === "write" || method === "writeln")
|
|
243
|
+
return flag(args[0], "document.write");
|
|
244
|
+
if (method === "setAttribute") {
|
|
245
|
+
const attr = args[0];
|
|
246
|
+
const name = attr?.type === "Literal" && typeof attr["value"] === "string" ? attr["value"].toLowerCase() : null;
|
|
247
|
+
if (name === "srcdoc" || (name !== null && /^on[a-z]+$/.test(name)))
|
|
248
|
+
flag(args[1], `setAttribute("${name}")`);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
if ((method === "assign" || method === "replace") && isLocation(obj))
|
|
252
|
+
return flag(args[0], "location (redirect)");
|
|
253
|
+
if (method === "open" && freeGlobal(unwrap(obj), GLOBALS))
|
|
254
|
+
return flag(args[0], "window.open (redirect)");
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/** Statements introduced by declarations/assignments that may add taint in this scope. */
|
|
259
|
+
function propagate(node, scope) {
|
|
260
|
+
let changed = false;
|
|
261
|
+
const bind = (name, init) => {
|
|
262
|
+
if (!init)
|
|
263
|
+
return;
|
|
264
|
+
const s = taintSource(init, scope);
|
|
265
|
+
if (s && !scope.tainted.has(name)) {
|
|
266
|
+
scope.tainted.add(name);
|
|
267
|
+
scope.sources.set(name, s);
|
|
268
|
+
changed = true;
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
if (node.type === "VariableDeclarator" && node["id"].type === "Identifier") {
|
|
272
|
+
bind(node["id"]["name"], node["init"]);
|
|
273
|
+
}
|
|
274
|
+
else if (node.type === "AssignmentExpression" && node["left"].type === "Identifier") {
|
|
275
|
+
bind(node["left"]["name"], node["right"]);
|
|
276
|
+
}
|
|
277
|
+
return changed;
|
|
278
|
+
}
|
|
279
|
+
/** Collect every node in a function body, not descending into nested functions. */
|
|
280
|
+
function ownNodes(root) {
|
|
281
|
+
const out = [];
|
|
282
|
+
const FN = new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"]);
|
|
283
|
+
const go = (n, top) => {
|
|
284
|
+
if (!top && FN.has(n.type))
|
|
285
|
+
return; // a nested function is its own scope
|
|
286
|
+
out.push(n);
|
|
287
|
+
for (const key of Object.keys(n)) {
|
|
288
|
+
if (key === "type" || key === "start" || key === "end")
|
|
289
|
+
continue;
|
|
290
|
+
const v = n[key];
|
|
291
|
+
if (Array.isArray(v)) {
|
|
292
|
+
for (const it of v)
|
|
293
|
+
if (isNode(it))
|
|
294
|
+
go(it, false);
|
|
295
|
+
}
|
|
296
|
+
else if (isNode(v))
|
|
297
|
+
go(v, false);
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
go(root, true);
|
|
301
|
+
return out;
|
|
302
|
+
}
|
|
303
|
+
const NO_SINK_FNS = new Map();
|
|
304
|
+
function analyzeScope(body, inherited, findings, parsed, seedParam, sinkFns = NO_SINK_FNS) {
|
|
305
|
+
const scope = { tainted: new Set(inherited.tainted), sources: new Map(inherited.sources) };
|
|
306
|
+
if (seedParam) {
|
|
307
|
+
scope.tainted.add(seedParam.name);
|
|
308
|
+
scope.sources.set(seedParam.name, seedParam.source);
|
|
309
|
+
}
|
|
310
|
+
const nodes = ownNodes(body);
|
|
311
|
+
// Fixpoint: keep binding tainted variables until nothing changes.
|
|
312
|
+
for (let changed = true; changed;) {
|
|
313
|
+
changed = false;
|
|
314
|
+
for (const n of nodes)
|
|
315
|
+
if (propagate(n, scope))
|
|
316
|
+
changed = true;
|
|
317
|
+
}
|
|
318
|
+
const report = (source, sink, at) => {
|
|
319
|
+
const pos = positionAt(parsed.lines, at.start);
|
|
320
|
+
findings.push({
|
|
321
|
+
source,
|
|
322
|
+
sink,
|
|
323
|
+
file: parsed.file,
|
|
324
|
+
line: pos.line,
|
|
325
|
+
column: pos.column,
|
|
326
|
+
expression: parsed.source.slice(at.start, at.end).replace(/\s+/g, " ").slice(0, 120),
|
|
327
|
+
});
|
|
328
|
+
};
|
|
329
|
+
for (const n of nodes) {
|
|
330
|
+
checkSinks(n, scope, report);
|
|
331
|
+
// One-hop interprocedural: a tainted argument passed to a local function's sink parameter.
|
|
332
|
+
if (n.type === "CallExpression") {
|
|
333
|
+
const name = isIdentifier(n["callee"]) ? n["callee"]["name"] : null;
|
|
334
|
+
const summary = name !== null ? sinkFns.get(name) : undefined;
|
|
335
|
+
if (summary) {
|
|
336
|
+
const args = n["arguments"];
|
|
337
|
+
for (const [i, sink] of summary) {
|
|
338
|
+
const s = args[i] ? taintSource(args[i], scope) : null;
|
|
339
|
+
if (s)
|
|
340
|
+
report(s, `${sink} (via ${name}())`, n);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
// Recurse into nested functions, inheriting this scope's taint (closure).
|
|
346
|
+
for (const fn of nestedFunctions(body)) {
|
|
347
|
+
analyzeScope(fn["body"], scope, findings, parsed, messageSeed(fn), sinkFns);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
/** Every function reachable by name: `function f(){}` and `const f = () => {}`. */
|
|
351
|
+
function namedFunctions(program) {
|
|
352
|
+
const out = new Map();
|
|
353
|
+
const FN = new Set(["FunctionExpression", "ArrowFunctionExpression"]);
|
|
354
|
+
const walk = (n) => {
|
|
355
|
+
if (n.type === "FunctionDeclaration" && n["id"])
|
|
356
|
+
out.set(n["id"]["name"], n);
|
|
357
|
+
if (n.type === "VariableDeclarator" &&
|
|
358
|
+
n["id"].type === "Identifier" &&
|
|
359
|
+
n["init"] &&
|
|
360
|
+
FN.has(n["init"].type)) {
|
|
361
|
+
out.set(n["id"]["name"], n["init"]);
|
|
362
|
+
}
|
|
363
|
+
for (const key of Object.keys(n)) {
|
|
364
|
+
if (key === "type" || key === "start" || key === "end")
|
|
365
|
+
continue;
|
|
366
|
+
const v = n[key];
|
|
367
|
+
if (Array.isArray(v)) {
|
|
368
|
+
for (const it of v)
|
|
369
|
+
if (isNode(it))
|
|
370
|
+
walk(it);
|
|
371
|
+
}
|
|
372
|
+
else if (isNode(v))
|
|
373
|
+
walk(v);
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
walk(program);
|
|
377
|
+
return out;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* For each named function, which parameters flow to a sink. Computed by
|
|
381
|
+
* seeding one parameter at a time as the only source and seeing whether any
|
|
382
|
+
* sink fires - so a parameter that is sanitized before the sink does not
|
|
383
|
+
* count. Direct only: a parameter that reaches a sink through another
|
|
384
|
+
* function is not summarized (a stated limit).
|
|
385
|
+
*/
|
|
386
|
+
function summarize(functions, parsed) {
|
|
387
|
+
const out = new Map();
|
|
388
|
+
for (const [name, fn] of functions) {
|
|
389
|
+
const params = fn["params"];
|
|
390
|
+
const sinkParams = new Map();
|
|
391
|
+
for (let i = 0; i < params.length; i++) {
|
|
392
|
+
const p = params[i];
|
|
393
|
+
if (p.type !== "Identifier")
|
|
394
|
+
continue;
|
|
395
|
+
const probe = [];
|
|
396
|
+
const scope = { tainted: new Set(), sources: new Map() };
|
|
397
|
+
analyzeScope(fn["body"], scope, probe, parsed, { name: p["name"], source: "@param" });
|
|
398
|
+
const hit = probe.find((f) => f.source === "@param");
|
|
399
|
+
if (hit)
|
|
400
|
+
sinkParams.set(i, hit.sink);
|
|
401
|
+
}
|
|
402
|
+
if (sinkParams.size > 0)
|
|
403
|
+
out.set(name, sinkParams);
|
|
404
|
+
}
|
|
405
|
+
return out;
|
|
406
|
+
}
|
|
407
|
+
/** Immediate nested functions of a body (not deeper - each recursion handles its own). */
|
|
408
|
+
function nestedFunctions(root) {
|
|
409
|
+
const out = [];
|
|
410
|
+
const FN = new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"]);
|
|
411
|
+
const go = (n, top) => {
|
|
412
|
+
if (!top && FN.has(n.type)) {
|
|
413
|
+
out.push(n);
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
for (const key of Object.keys(n)) {
|
|
417
|
+
if (key === "type" || key === "start" || key === "end")
|
|
418
|
+
continue;
|
|
419
|
+
const v = n[key];
|
|
420
|
+
if (Array.isArray(v)) {
|
|
421
|
+
for (const it of v)
|
|
422
|
+
if (isNode(it))
|
|
423
|
+
go(it, false);
|
|
424
|
+
}
|
|
425
|
+
else if (isNode(v))
|
|
426
|
+
go(v, false);
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
go(root, true);
|
|
430
|
+
return out;
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* If a function is the handler of a `window` message listener, its first
|
|
434
|
+
* parameter is a source ("postMessage data"). Only window, not self: a
|
|
435
|
+
* worker's messages come from its own creator (see message.ts).
|
|
436
|
+
*/
|
|
437
|
+
function messageSeed(fn) {
|
|
438
|
+
const p = fn["params"][0];
|
|
439
|
+
const name = p?.type === "Identifier" ? p["name"] : null;
|
|
440
|
+
if (name === null)
|
|
441
|
+
return null;
|
|
442
|
+
const listener = fn["$frostjsMessageHandler"];
|
|
443
|
+
return listener === true ? { name, source: "postMessage data" } : null;
|
|
444
|
+
}
|
|
445
|
+
/** Mark window message handlers so messageSeed can find them. */
|
|
446
|
+
function markMessageHandlers(program) {
|
|
447
|
+
const walk = (n) => {
|
|
448
|
+
if (n.type === "CallExpression") {
|
|
449
|
+
const callee = n["callee"];
|
|
450
|
+
if (callee.type === "MemberExpression" &&
|
|
451
|
+
memberName(callee) === "addEventListener" &&
|
|
452
|
+
freeGlobal(callee["object"], new Set(["window"]))) {
|
|
453
|
+
const args = n["arguments"];
|
|
454
|
+
if (args[0]?.type === "Literal" && args[0]["value"] === "message" && args[1])
|
|
455
|
+
args[1]["$frostjsMessageHandler"] = true;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
if (n.type === "AssignmentExpression") {
|
|
459
|
+
const left = n["left"];
|
|
460
|
+
if (left.type === "MemberExpression" &&
|
|
461
|
+
memberName(left) === "onmessage" &&
|
|
462
|
+
freeGlobal(left["object"], new Set(["window"]))) {
|
|
463
|
+
n["right"]["$frostjsMessageHandler"] = true;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
for (const key of Object.keys(n)) {
|
|
467
|
+
if (key === "type" || key === "start" || key === "end")
|
|
468
|
+
continue;
|
|
469
|
+
const v = n[key];
|
|
470
|
+
if (Array.isArray(v)) {
|
|
471
|
+
for (const it of v)
|
|
472
|
+
if (isNode(it))
|
|
473
|
+
walk(it);
|
|
474
|
+
}
|
|
475
|
+
else if (isNode(v))
|
|
476
|
+
walk(v);
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
walk(program);
|
|
480
|
+
}
|
|
481
|
+
/** Find every untrusted-source-to-dangerous-sink flow in the file. */
|
|
482
|
+
export function taint(parsed) {
|
|
483
|
+
const info = analyzeScopes(parsed.program);
|
|
484
|
+
for (const n of info.free)
|
|
485
|
+
n[FREE] = true;
|
|
486
|
+
for (const [n, v] of info.constants)
|
|
487
|
+
n[FOLDED] = v;
|
|
488
|
+
markMessageHandlers(parsed.program);
|
|
489
|
+
const sinkFns = summarize(namedFunctions(parsed.program), parsed);
|
|
490
|
+
const findings = [];
|
|
491
|
+
const empty = { tainted: new Set(), sources: new Map() };
|
|
492
|
+
analyzeScope(parsed.program, empty, findings, parsed, null, sinkFns);
|
|
493
|
+
// Deduplicate by position and sink.
|
|
494
|
+
const seen = new Set();
|
|
495
|
+
return findings.filter((f) => {
|
|
496
|
+
const k = `${f.line}:${f.column}:${f.sink}`;
|
|
497
|
+
if (seen.has(k))
|
|
498
|
+
return false;
|
|
499
|
+
seen.add(k);
|
|
500
|
+
return true;
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
//# sourceMappingURL=taint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taint.js","sourceRoot":"","sources":["../../src/extract/taint.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"target.d.ts","sourceRoot":"","sources":["../../src/extract/target.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAIxC,+DAA+D;AAC/D,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CA4BvF;AAKD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,WAAW,CAAC;AAE7C;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,UAAO,EAAE,IAAI,GAAE,UAAkB,GAAG,MAAM,GAAG,IAAI,CAqBpG;AAED,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,EAAE,IAAI,GAAE,UAAkB,GAAG,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"target.d.ts","sourceRoot":"","sources":["../../src/extract/target.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAIxC,+DAA+D;AAC/D,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CA4BvF;AAKD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,WAAW,CAAC;AAE7C;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,UAAO,EAAE,IAAI,GAAE,UAAkB,GAAG,MAAM,GAAG,IAAI,CAqBpG;AAED,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,EAAE,IAAI,GAAE,UAAkB,GAAG,MAAM,GAAG,IAAI,CAWjG"}
|
package/dist/extract/target.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FOLDED } from "./annotations.js";
|
|
1
|
+
import { FOLDED, FREE } from "./annotations.js";
|
|
2
2
|
import { unwrap } from "./typescript.js";
|
|
3
3
|
/** The target of a relative URL: the document's own origin. */
|
|
4
4
|
export const SAME_ORIGIN = "same-origin";
|
|
@@ -73,9 +73,31 @@ export function resolveTarget(text, complete = true, kind = "url") {
|
|
|
73
73
|
export function resolveTargetOf(arg, kind = "url") {
|
|
74
74
|
if (!arg)
|
|
75
75
|
return null;
|
|
76
|
+
// new URL(path, "https://host/..."): the host comes from the base, whatever the (possibly dynamic) first arg.
|
|
77
|
+
if (arg.type === "NewExpression" && isUrlCtor(arg["callee"])) {
|
|
78
|
+
const args = arg["arguments"];
|
|
79
|
+
if (args.length >= 2)
|
|
80
|
+
return resolveTargetOf(args[1]);
|
|
81
|
+
return resolveTargetOf(args[0]); // new URL("https://host/...")
|
|
82
|
+
}
|
|
76
83
|
const lit = leadingLiteral(arg);
|
|
77
84
|
if (lit === null)
|
|
78
85
|
return null;
|
|
79
86
|
return resolveTarget(lit.text, lit.complete, kind);
|
|
80
87
|
}
|
|
88
|
+
/** True for the global `URL` constructor (bare or window.URL), not a local one. */
|
|
89
|
+
function isUrlCtor(callee) {
|
|
90
|
+
if (callee.type === "Identifier")
|
|
91
|
+
return callee["name"] === "URL" && callee[FREE] === true;
|
|
92
|
+
if (callee.type === "MemberExpression" && callee["computed"] !== true) {
|
|
93
|
+
const prop = callee["property"];
|
|
94
|
+
const obj = callee["object"];
|
|
95
|
+
return (prop.type === "Identifier" &&
|
|
96
|
+
prop["name"] === "URL" &&
|
|
97
|
+
obj.type === "Identifier" &&
|
|
98
|
+
GLOBAL_OBJECT_NAMES.has(obj["name"]));
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
const GLOBAL_OBJECT_NAMES = new Set(["window", "globalThis", "self"]);
|
|
81
103
|
//# sourceMappingURL=target.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"target.js","sourceRoot":"","sources":["../../src/extract/target.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"target.js","sourceRoot":"","sources":["../../src/extract/target.ts"],"names":[],"mappings":"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"}
|
package/dist/policy/compile.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ import { type ParsedPolicy, type Rule } from "./parse.js";
|
|
|
17
17
|
* `decide()` for vendored files the registry does not know, never by
|
|
18
18
|
* `compile()`.
|
|
19
19
|
*/
|
|
20
|
-
export type Reason = "granted" | "forbidden" | "expired" | "not granted" | "unknown destination" | "unregistered";
|
|
20
|
+
export type Reason = "granted" | "forbidden" | "expired" | "not granted" | "unknown destination" | "unregistered" | "tainted";
|
|
21
21
|
export interface Evaluation {
|
|
22
22
|
verdict: "allowed" | "denied";
|
|
23
23
|
reason: Reason;
|
|
@@ -32,6 +32,8 @@ export interface Policy {
|
|
|
32
32
|
rules: readonly Rule[];
|
|
33
33
|
/** Globs of vendored files, relative to the policy directory. */
|
|
34
34
|
vendored: readonly string[];
|
|
35
|
+
/** The policy asks frostjs check to gate on taint flows. */
|
|
36
|
+
taint: boolean;
|
|
35
37
|
/** Globs of files not analyzed at all, relative to the policy directory. */
|
|
36
38
|
ignore: readonly string[];
|
|
37
39
|
/** Grants that expire within the warning window, as printable lines. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/policy/compile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAO,KAAK,YAAY,EAAE,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAE/D;;;;GAIG;AACH,MAAM,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/policy/compile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAO,KAAK,YAAY,EAAE,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAE/D;;;;GAIG;AACH,MAAM,MAAM,MAAM,GAChB,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,aAAa,GAAG,qBAAqB,GAAG,cAAc,GAAG,SAAS,CAAC;AAE3G,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,oGAAoG;IACpG,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IACvB,iEAAiE;IACjE,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,4DAA4D;IAC5D,KAAK,EAAE,OAAO,CAAC;IACf,4EAA4E;IAC5E,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,wEAAwE;IACxE,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,UAAU,CAAC;CAC1C;AAED,MAAM,WAAW,cAAc;IAC7B,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,yFAAyF;AACzF,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,oFAAoF;AACpF,wBAAgB,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CAuD1E;AAED,wFAAwF;AACxF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAE9E;AAED,4GAA4G;AAC5G,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAGlE"}
|