@nocobase/plugin-flow-engine 2.0.0-alpha.2
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/LICENSE +661 -0
- package/README.md +29 -0
- package/build.config.ts +22 -0
- package/client.d.ts +2 -0
- package/client.js +1 -0
- package/dist/client/index.d.ts +15 -0
- package/dist/client/index.js +10 -0
- package/dist/externalVersion.js +21 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +48 -0
- package/dist/locale/en-US.json +61 -0
- package/dist/locale/index.d.ts +141 -0
- package/dist/locale/index.js +79 -0
- package/dist/locale/zh-CN.json +61 -0
- package/dist/node_modules/ses/LICENSE +201 -0
- package/dist/node_modules/ses/LICENSE-aura +16 -0
- package/dist/node_modules/ses/LICENSE-caja +13 -0
- package/dist/node_modules/ses/LICENSE-corejs +19 -0
- package/dist/node_modules/ses/LICENSE-v8 +9 -0
- package/dist/node_modules/ses/assert-shim.js +1 -0
- package/dist/node_modules/ses/compartment-shim.js +1 -0
- package/dist/node_modules/ses/console-shim.js +1 -0
- package/dist/node_modules/ses/dist/lockdown.cjs +13912 -0
- package/dist/node_modules/ses/dist/lockdown.umd.js +13912 -0
- package/dist/node_modules/ses/dist/lockdown.umd.min.js +1 -0
- package/dist/node_modules/ses/dist/ses-hermes.cjs +13912 -0
- package/dist/node_modules/ses/dist/ses.cjs +1 -0
- package/dist/node_modules/ses/dist/ses.umd.js +13912 -0
- package/dist/node_modules/ses/dist/ses.umd.min.js +1 -0
- package/dist/node_modules/ses/dist/types.d.cts +606 -0
- package/dist/node_modules/ses/index.js +18 -0
- package/dist/node_modules/ses/lockdown-shim.js +1 -0
- package/dist/node_modules/ses/lockdown.js +1 -0
- package/dist/node_modules/ses/package.json +1 -0
- package/dist/node_modules/ses/src/assert-shim.js +4 -0
- package/dist/node_modules/ses/src/assert-sloppy-mode.js +11 -0
- package/dist/node_modules/ses/src/cauterize-property.js +69 -0
- package/dist/node_modules/ses/src/commons.js +425 -0
- package/dist/node_modules/ses/src/compartment-evaluate.js +93 -0
- package/dist/node_modules/ses/src/compartment-shim.js +22 -0
- package/dist/node_modules/ses/src/compartment.js +477 -0
- package/dist/node_modules/ses/src/console-shim.js +50 -0
- package/dist/node_modules/ses/src/enable-property-overrides.js +211 -0
- package/dist/node_modules/ses/src/enablements.js +244 -0
- package/dist/node_modules/ses/src/error/assert.js +584 -0
- package/dist/node_modules/ses/src/error/console.js +541 -0
- package/dist/node_modules/ses/src/error/fatal-assert.js +54 -0
- package/dist/node_modules/ses/src/error/internal-types.js +98 -0
- package/dist/node_modules/ses/src/error/note-log-args.js +77 -0
- package/dist/node_modules/ses/src/error/stringify-utils.js +195 -0
- package/dist/node_modules/ses/src/error/tame-console.js +197 -0
- package/dist/node_modules/ses/src/error/tame-error-constructor.js +284 -0
- package/dist/node_modules/ses/src/error/tame-v8-error-constructor.js +386 -0
- package/dist/node_modules/ses/src/error/types.js +59 -0
- package/dist/node_modules/ses/src/error/unhandled-rejection.js +122 -0
- package/dist/node_modules/ses/src/eval-scope.js +89 -0
- package/dist/node_modules/ses/src/get-anonymous-intrinsics.js +181 -0
- package/dist/node_modules/ses/src/get-source-url.js +50 -0
- package/dist/node_modules/ses/src/global-object.js +175 -0
- package/dist/node_modules/ses/src/intrinsics.js +192 -0
- package/dist/node_modules/ses/src/lockdown-shim.js +37 -0
- package/dist/node_modules/ses/src/lockdown.js +558 -0
- package/dist/node_modules/ses/src/make-eval-function.js +28 -0
- package/dist/node_modules/ses/src/make-evaluate.js +110 -0
- package/dist/node_modules/ses/src/make-function-constructor.js +79 -0
- package/dist/node_modules/ses/src/make-hardener.js +275 -0
- package/dist/node_modules/ses/src/make-safe-evaluator.js +112 -0
- package/dist/node_modules/ses/src/module-instance.js +497 -0
- package/dist/node_modules/ses/src/module-link.js +159 -0
- package/dist/node_modules/ses/src/module-load.js +719 -0
- package/dist/node_modules/ses/src/module-proxy.js +200 -0
- package/dist/node_modules/ses/src/permits-intrinsics.js +291 -0
- package/dist/node_modules/ses/src/permits.js +1761 -0
- package/dist/node_modules/ses/src/reporting-types.d.ts +13 -0
- package/dist/node_modules/ses/src/reporting.js +105 -0
- package/dist/node_modules/ses/src/scope-constants.js +180 -0
- package/dist/node_modules/ses/src/shim-arraybuffer-transfer.js +85 -0
- package/dist/node_modules/ses/src/sloppy-globals-scope-terminator.js +61 -0
- package/dist/node_modules/ses/src/strict-scope-terminator.js +99 -0
- package/dist/node_modules/ses/src/tame-date-constructor.js +127 -0
- package/dist/node_modules/ses/src/tame-domains.js +41 -0
- package/dist/node_modules/ses/src/tame-faux-data-properties.js +210 -0
- package/dist/node_modules/ses/src/tame-function-constructors.js +140 -0
- package/dist/node_modules/ses/src/tame-function-tostring.js +50 -0
- package/dist/node_modules/ses/src/tame-harden.js +29 -0
- package/dist/node_modules/ses/src/tame-locale-methods.js +78 -0
- package/dist/node_modules/ses/src/tame-math-object.js +41 -0
- package/dist/node_modules/ses/src/tame-module-source.js +51 -0
- package/dist/node_modules/ses/src/tame-regenerator-runtime.js +29 -0
- package/dist/node_modules/ses/src/tame-regexp-constructor.js +65 -0
- package/dist/node_modules/ses/src/tame-symbol-constructor.js +64 -0
- package/dist/node_modules/ses/src/transforms.js +267 -0
- package/dist/node_modules/ses/tools.js +25 -0
- package/dist/node_modules/ses/types.d.ts +606 -0
- package/dist/server/actions/ui-schema-action.d.ts +27 -0
- package/dist/server/actions/ui-schema-action.js +118 -0
- package/dist/server/collections/flowModelTreePath.d.ts +11 -0
- package/dist/server/collections/flowModelTreePath.js +74 -0
- package/dist/server/collections/flowModels.d.ts +11 -0
- package/dist/server/collections/flowModels.js +57 -0
- package/dist/server/collections/flowsql.d.ts +10 -0
- package/dist/server/collections/flowsql.js +51 -0
- package/dist/server/dao/ui_schema_node_dao.d.ts +26 -0
- package/dist/server/dao/ui_schema_node_dao.js +24 -0
- package/dist/server/helper.d.ts +8 -0
- package/dist/server/helper.js +9 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.js +42 -0
- package/dist/server/model.d.ts +12 -0
- package/dist/server/model.js +38 -0
- package/dist/server/plugin.d.ts +26 -0
- package/dist/server/plugin.js +270 -0
- package/dist/server/repository.d.ts +116 -0
- package/dist/server/repository.js +1209 -0
- package/dist/server/server.d.ts +16 -0
- package/dist/server/server.js +198 -0
- package/dist/server/template/contexts.d.ts +73 -0
- package/dist/server/template/contexts.js +233 -0
- package/dist/server/template/resolver.d.ts +30 -0
- package/dist/server/template/resolver.js +225 -0
- package/dist/server/variables/registry.d.ts +42 -0
- package/dist/server/variables/registry.js +299 -0
- package/package.json +28 -0
- package/server.d.ts +2 -0
- package/server.js +1 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FERAL_REG_EXP,
|
|
3
|
+
TypeError,
|
|
4
|
+
construct,
|
|
5
|
+
defineProperties,
|
|
6
|
+
getOwnPropertyDescriptor,
|
|
7
|
+
speciesSymbol,
|
|
8
|
+
} from './commons.js';
|
|
9
|
+
|
|
10
|
+
export default function tameRegExpConstructor(regExpTaming = 'safe') {
|
|
11
|
+
const RegExpPrototype = FERAL_REG_EXP.prototype;
|
|
12
|
+
|
|
13
|
+
const makeRegExpConstructor = (_ = {}) => {
|
|
14
|
+
// RegExp has non-writable static properties we need to omit.
|
|
15
|
+
/**
|
|
16
|
+
* @param {Parameters<typeof FERAL_REG_EXP>} rest
|
|
17
|
+
*/
|
|
18
|
+
const ResultRegExp = function RegExp(...rest) {
|
|
19
|
+
if (new.target === undefined) {
|
|
20
|
+
return FERAL_REG_EXP(...rest);
|
|
21
|
+
}
|
|
22
|
+
return construct(FERAL_REG_EXP, rest, new.target);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
defineProperties(ResultRegExp, {
|
|
26
|
+
length: { value: 2 },
|
|
27
|
+
prototype: {
|
|
28
|
+
value: RegExpPrototype,
|
|
29
|
+
writable: false,
|
|
30
|
+
enumerable: false,
|
|
31
|
+
configurable: false,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
// Hermes does not have `Symbol.species`. We should support such platforms.
|
|
35
|
+
if (speciesSymbol) {
|
|
36
|
+
const speciesDesc = getOwnPropertyDescriptor(
|
|
37
|
+
FERAL_REG_EXP,
|
|
38
|
+
speciesSymbol,
|
|
39
|
+
);
|
|
40
|
+
if (!speciesDesc) {
|
|
41
|
+
throw TypeError('no RegExp[Symbol.species] descriptor');
|
|
42
|
+
}
|
|
43
|
+
defineProperties(ResultRegExp, {
|
|
44
|
+
[speciesSymbol]: speciesDesc,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return ResultRegExp;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const InitialRegExp = makeRegExpConstructor();
|
|
51
|
+
const SharedRegExp = makeRegExpConstructor();
|
|
52
|
+
|
|
53
|
+
if (regExpTaming !== 'unsafe') {
|
|
54
|
+
// @ts-expect-error Deleted properties must be optional
|
|
55
|
+
delete RegExpPrototype.compile;
|
|
56
|
+
}
|
|
57
|
+
defineProperties(RegExpPrototype, {
|
|
58
|
+
constructor: { value: SharedRegExp },
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
'%InitialRegExp%': InitialRegExp,
|
|
63
|
+
'%SharedRegExp%': SharedRegExp,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Symbol,
|
|
3
|
+
entries,
|
|
4
|
+
fromEntries,
|
|
5
|
+
getOwnPropertyDescriptors,
|
|
6
|
+
defineProperties,
|
|
7
|
+
arrayMap,
|
|
8
|
+
functionBind,
|
|
9
|
+
} from './commons.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* This taming provides a tamed alternative to the original `Symbol` constructor
|
|
13
|
+
* that starts off identical, except that all its properties are "temporarily"
|
|
14
|
+
* configurable. The original `Symbol` constructor remains unmodified on
|
|
15
|
+
* the start compartment's global. The tamed alternative is used as the shared
|
|
16
|
+
* `Symbol` constructor on constructed compartments.
|
|
17
|
+
*
|
|
18
|
+
* Starting these properties as configurable assumes two succeeding phases of
|
|
19
|
+
* processing: A permit enforcement phase, that
|
|
20
|
+
* removes all properties not on the permits (which requires them to be
|
|
21
|
+
* configurable) and a global hardening step that freezes all primordials,
|
|
22
|
+
* returning these properties to their expected non-configurable status.
|
|
23
|
+
*
|
|
24
|
+
* The ses shim is constructed to eventually enable vetted shims to run between
|
|
25
|
+
* repair and global hardening. However, such vetted shims would normally
|
|
26
|
+
* run in the start compartment, which continues to use the original unmodified
|
|
27
|
+
* `Symbol`, so they should not normally be affected by the temporary
|
|
28
|
+
* configurability of these properties.
|
|
29
|
+
*
|
|
30
|
+
* Note that the spec refers to the global `Symbol` function as the
|
|
31
|
+
* ["Symbol Constructor"](https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-symbol-constructor)
|
|
32
|
+
* even though it has a call behavior (can be called as a function) and does not
|
|
33
|
+
* not have a construct behavior (cannot be called with `new`). Accordingly,
|
|
34
|
+
* to tame it, we must replace it with a function without a construct
|
|
35
|
+
* behavior.
|
|
36
|
+
*/
|
|
37
|
+
export const tameSymbolConstructor = () => {
|
|
38
|
+
const OriginalSymbol = Symbol;
|
|
39
|
+
const SymbolPrototype = OriginalSymbol.prototype;
|
|
40
|
+
|
|
41
|
+
// Bypass Hermes bug, fixed in: https://github.com/facebook/hermes/commit/00f18c89c720e1c34592bb85a1a8d311e6e99599
|
|
42
|
+
// Make a "copy" of the primordial [Symbol "constructor"](https://tc39.es/ecma262/#sec-symbol-description) which maintains all observable behavior. The primordial explicitly throws on `[[Construct]]` and has a `[[Call]]` which ignores the receiver. Binding also maintains the `toString` source as a native function. The `name` is restored below when copying own properties.
|
|
43
|
+
const SharedSymbol = functionBind(Symbol, undefined);
|
|
44
|
+
|
|
45
|
+
defineProperties(SymbolPrototype, {
|
|
46
|
+
constructor: {
|
|
47
|
+
value: SharedSymbol,
|
|
48
|
+
// leave other `constructor` attributes as is
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const originalDescsEntries = entries(
|
|
53
|
+
getOwnPropertyDescriptors(OriginalSymbol),
|
|
54
|
+
);
|
|
55
|
+
const descs = fromEntries(
|
|
56
|
+
arrayMap(originalDescsEntries, ([name, desc]) => [
|
|
57
|
+
name,
|
|
58
|
+
{ ...desc, configurable: true },
|
|
59
|
+
]),
|
|
60
|
+
);
|
|
61
|
+
defineProperties(SharedSymbol, descs);
|
|
62
|
+
|
|
63
|
+
return { '%SharedSymbol%': SharedSymbol };
|
|
64
|
+
};
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
FERAL_REG_EXP,
|
|
5
|
+
SyntaxError,
|
|
6
|
+
stringReplace,
|
|
7
|
+
stringSearch,
|
|
8
|
+
stringSlice,
|
|
9
|
+
stringSplit,
|
|
10
|
+
freeze,
|
|
11
|
+
} from './commons.js';
|
|
12
|
+
import { getSourceURL } from './get-source-url.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Find the first occurence of the given pattern and return
|
|
16
|
+
* the location as the approximate line number.
|
|
17
|
+
*
|
|
18
|
+
* @param {string} src
|
|
19
|
+
* @param {RegExp} pattern
|
|
20
|
+
* @returns {number}
|
|
21
|
+
*/
|
|
22
|
+
function getLineNumber(src, pattern) {
|
|
23
|
+
const index = stringSearch(src, pattern);
|
|
24
|
+
if (index < 0) {
|
|
25
|
+
return -1;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// The importPattern incidentally captures an initial \n in
|
|
29
|
+
// an attempt to reject a . prefix, so we need to offset
|
|
30
|
+
// the line number in that case.
|
|
31
|
+
const adjustment = src[index] === '\n' ? 1 : 0;
|
|
32
|
+
|
|
33
|
+
return stringSplit(stringSlice(src, 0, index), '\n').length + adjustment;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// /////////////////////////////////////////////////////////////////////////////
|
|
37
|
+
|
|
38
|
+
const htmlCommentPattern = new FERAL_REG_EXP(`(?:${'<'}!--|--${'>'})`, 'g');
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Conservatively reject the source text if it may contain text that some
|
|
42
|
+
* JavaScript parsers may treat as an html-like comment. To reject without
|
|
43
|
+
* parsing, `rejectHtmlComments` will also reject some other text as well.
|
|
44
|
+
*
|
|
45
|
+
* https://www.ecma-international.org/ecma-262/9.0/index.html#sec-html-like-comments
|
|
46
|
+
* explains that JavaScript parsers may or may not recognize html
|
|
47
|
+
* comment tokens "<" immediately followed by "!--" and "--"
|
|
48
|
+
* immediately followed by ">" in non-module source text, and treat
|
|
49
|
+
* them as a kind of line comment. Since otherwise both of these can
|
|
50
|
+
* appear in normal JavaScript source code as a sequence of operators,
|
|
51
|
+
* we have the terrifying possibility of the same source code parsing
|
|
52
|
+
* one way on one correct JavaScript implementation, and another way
|
|
53
|
+
* on another.
|
|
54
|
+
*
|
|
55
|
+
* This shim takes the conservative strategy of just rejecting source
|
|
56
|
+
* text that contains these strings anywhere. Note that this very
|
|
57
|
+
* source file is written strangely to avoid mentioning these
|
|
58
|
+
* character strings explicitly.
|
|
59
|
+
*
|
|
60
|
+
* We do not write the regexp in a straightforward way, so that an
|
|
61
|
+
* apparennt html comment does not appear in this file. Thus, we avoid
|
|
62
|
+
* rejection by the overly eager rejectDangerousSources.
|
|
63
|
+
*
|
|
64
|
+
* @param {string} src
|
|
65
|
+
* @returns {string}
|
|
66
|
+
*/
|
|
67
|
+
export const rejectHtmlComments = src => {
|
|
68
|
+
const lineNumber = getLineNumber(src, htmlCommentPattern);
|
|
69
|
+
if (lineNumber < 0) {
|
|
70
|
+
return src;
|
|
71
|
+
}
|
|
72
|
+
const name = getSourceURL(src);
|
|
73
|
+
// See https://github.com/endojs/endo/blob/master/packages/ses/error-codes/SES_HTML_COMMENT_REJECTED.md
|
|
74
|
+
throw SyntaxError(
|
|
75
|
+
`Possible HTML comment rejected at ${name}:${lineNumber}. (SES_HTML_COMMENT_REJECTED)`,
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* An optional transform to place ahead of `rejectHtmlComments` to evade *that*
|
|
81
|
+
* rejection. However, it may change the meaning of the program.
|
|
82
|
+
*
|
|
83
|
+
* This evasion replaces each alleged html comment with the space-separated
|
|
84
|
+
* JavaScript operator sequence that it may mean, assuming that it appears
|
|
85
|
+
* outside of a comment or literal string, in source code where the JS
|
|
86
|
+
* parser makes no special case for html comments (like module source code).
|
|
87
|
+
* In that case, this evasion preserves the meaning of the program, though it
|
|
88
|
+
* does change the souce column numbers on each effected line.
|
|
89
|
+
*
|
|
90
|
+
* If the html comment appeared in a literal (a string literal, regexp literal,
|
|
91
|
+
* or a template literal), then this evasion will change the meaning of the
|
|
92
|
+
* program by changing the text of that literal.
|
|
93
|
+
*
|
|
94
|
+
* If the html comment appeared in a JavaScript comment, then this evasion does
|
|
95
|
+
* not change the meaning of the program because it only changes the contents of
|
|
96
|
+
* those comments.
|
|
97
|
+
*
|
|
98
|
+
* @param {string} src
|
|
99
|
+
* @returns {string}
|
|
100
|
+
*/
|
|
101
|
+
export const evadeHtmlCommentTest = src => {
|
|
102
|
+
const replaceFn = match => (match[0] === '<' ? '< ! --' : '-- >');
|
|
103
|
+
return stringReplace(src, htmlCommentPattern, replaceFn);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// /////////////////////////////////////////////////////////////////////////////
|
|
107
|
+
|
|
108
|
+
const importPattern = new FERAL_REG_EXP(
|
|
109
|
+
'(^|[^.]|\\.\\.\\.)\\bimport(\\s*(?:\\(|/[/*]))',
|
|
110
|
+
'g',
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Conservatively reject the source text if it may contain a dynamic
|
|
115
|
+
* import expression. To reject without parsing, `rejectImportExpressions` will
|
|
116
|
+
* also reject some other text as well.
|
|
117
|
+
*
|
|
118
|
+
* The proposed dynamic import expression is the only syntax currently
|
|
119
|
+
* proposed, that can appear in non-module JavaScript code, that
|
|
120
|
+
* enables direct access to the outside world that cannot be
|
|
121
|
+
* suppressed or intercepted without parsing and rewriting. Instead,
|
|
122
|
+
* this shim conservatively rejects any source text that seems to
|
|
123
|
+
* contain such an expression. To do this safely without parsing, we
|
|
124
|
+
* must also reject some valid programs, i.e., those containing
|
|
125
|
+
* apparent import expressions in literal strings or comments.
|
|
126
|
+
*
|
|
127
|
+
* The current conservative rule looks for the identifier "import"
|
|
128
|
+
* followed by either an open paren or something that looks like the
|
|
129
|
+
* beginning of a comment. We assume that we do not need to worry
|
|
130
|
+
* about html comment syntax because that was already rejected by
|
|
131
|
+
* rejectHtmlComments.
|
|
132
|
+
*
|
|
133
|
+
* this \s *must* match all kinds of syntax-defined whitespace. If e.g.
|
|
134
|
+
* U+2028 (LINE SEPARATOR) or U+2029 (PARAGRAPH SEPARATOR) is treated as
|
|
135
|
+
* whitespace by the parser, but not matched by /\s/, then this would admit
|
|
136
|
+
* an attack like: import\u2028('power.js') . We're trying to distinguish
|
|
137
|
+
* something like that from something like importnotreally('power.js') which
|
|
138
|
+
* is perfectly safe.
|
|
139
|
+
*
|
|
140
|
+
* @param {string} src
|
|
141
|
+
* @returns {string}
|
|
142
|
+
*/
|
|
143
|
+
export const rejectImportExpressions = src => {
|
|
144
|
+
const lineNumber = getLineNumber(src, importPattern);
|
|
145
|
+
if (lineNumber < 0) {
|
|
146
|
+
return src;
|
|
147
|
+
}
|
|
148
|
+
const name = getSourceURL(src);
|
|
149
|
+
// See https://github.com/endojs/endo/blob/master/packages/ses/error-codes/SES_IMPORT_REJECTED.md
|
|
150
|
+
throw SyntaxError(
|
|
151
|
+
`Possible import expression rejected at ${name}:${lineNumber}. (SES_IMPORT_REJECTED)`,
|
|
152
|
+
);
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* An optional transform to place ahead of `rejectImportExpressions` to evade
|
|
157
|
+
* *that* rejection. However, it may change the meaning of the program.
|
|
158
|
+
*
|
|
159
|
+
* This evasion replaces each suspicious `import` identifier with `__import__`.
|
|
160
|
+
* If the alleged import expression appears in a JavaScript comment, this
|
|
161
|
+
* evasion will not change the meaning of the program. If it appears in a
|
|
162
|
+
* literal (string literal, regexp literal, or a template literal), then this
|
|
163
|
+
* evasion will change the contents of that literal. If it appears as code
|
|
164
|
+
* where it would be parsed as an expression, then it might or might not change
|
|
165
|
+
* the meaning of the program, depending on the binding, if any, of the lexical
|
|
166
|
+
* variable `__import__`.
|
|
167
|
+
*
|
|
168
|
+
* @param {string} src
|
|
169
|
+
* @returns {string}
|
|
170
|
+
*/
|
|
171
|
+
export const evadeImportExpressionTest = src => {
|
|
172
|
+
const replaceFn = (_, p1, p2) => `${p1}__import__${p2}`;
|
|
173
|
+
return stringReplace(src, importPattern, replaceFn);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// /////////////////////////////////////////////////////////////////////////////
|
|
177
|
+
|
|
178
|
+
const someDirectEvalPattern = new FERAL_REG_EXP(
|
|
179
|
+
'(^|[^.])\\beval(\\s*\\()',
|
|
180
|
+
'g',
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Heuristically reject some text that seems to contain a direct eval
|
|
185
|
+
* expression, with both false positives and false negavives. To reject without
|
|
186
|
+
* parsing, `rejectSomeDirectEvalExpressions` may will also reject some other
|
|
187
|
+
* text as well. It may also accept source text that contains a direct eval
|
|
188
|
+
* written oddly, such as `(eval)(src)`. This false negative is not a security
|
|
189
|
+
* vulnerability. Rather it is a compat hazard because it will execute as
|
|
190
|
+
* an indirect eval under the SES-shim but as a direct eval on platforms that
|
|
191
|
+
* support SES directly (like XS).
|
|
192
|
+
*
|
|
193
|
+
* The shim cannot correctly emulate a direct eval as explained at
|
|
194
|
+
* https://github.com/Agoric/realms-shim/issues/12
|
|
195
|
+
* If we did not reject direct eval syntax, we would
|
|
196
|
+
* accidentally evaluate these with an emulation of indirect eval. To
|
|
197
|
+
* prevent future compatibility problems, in shifting from use of the
|
|
198
|
+
* shim to genuine platform support for the proposal, we should
|
|
199
|
+
* instead statically reject code that seems to contain a direct eval
|
|
200
|
+
* expression.
|
|
201
|
+
*
|
|
202
|
+
* As with the dynamic import expression, to avoid a full parse, we do
|
|
203
|
+
* this approximately with a regexp, that will also reject strings
|
|
204
|
+
* that appear safely in comments or strings. Unlike dynamic import,
|
|
205
|
+
* if we miss some, this only creates future compat problems, not
|
|
206
|
+
* security problems. Thus, we are only trying to catch innocent
|
|
207
|
+
* occurrences, not malicious one. In particular, `(eval)(...)` is
|
|
208
|
+
* direct eval syntax that would not be caught by the following regexp.
|
|
209
|
+
*
|
|
210
|
+
* Exported for unit tests.
|
|
211
|
+
*
|
|
212
|
+
* @param {string} src
|
|
213
|
+
* @returns {string}
|
|
214
|
+
*/
|
|
215
|
+
export const rejectSomeDirectEvalExpressions = src => {
|
|
216
|
+
const lineNumber = getLineNumber(src, someDirectEvalPattern);
|
|
217
|
+
if (lineNumber < 0) {
|
|
218
|
+
return src;
|
|
219
|
+
}
|
|
220
|
+
const name = getSourceURL(src);
|
|
221
|
+
// See https://github.com/endojs/endo/blob/master/packages/ses/error-codes/SES_EVAL_REJECTED.md
|
|
222
|
+
throw SyntaxError(
|
|
223
|
+
`Possible direct eval expression rejected at ${name}:${lineNumber}. (SES_EVAL_REJECTED)`,
|
|
224
|
+
);
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
// /////////////////////////////////////////////////////////////////////////////
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* A transform that bundles together the transforms that must unconditionally
|
|
231
|
+
* happen last in order to ensure safe evaluation without parsing.
|
|
232
|
+
*
|
|
233
|
+
* @param {string} source
|
|
234
|
+
* @returns {string}
|
|
235
|
+
*/
|
|
236
|
+
export const mandatoryTransforms = source => {
|
|
237
|
+
source = rejectHtmlComments(source);
|
|
238
|
+
source = rejectImportExpressions(source);
|
|
239
|
+
return source;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Starting with `source`, apply each transform to the result of the
|
|
244
|
+
* previous one, returning the result of the last transformation.
|
|
245
|
+
*
|
|
246
|
+
* @param {string} source
|
|
247
|
+
* @param {((str: string) => string)[]} transforms
|
|
248
|
+
* @returns {string}
|
|
249
|
+
*/
|
|
250
|
+
export const applyTransforms = (source, transforms) => {
|
|
251
|
+
for (let i = 0, l = transforms.length; i < l; i += 1) {
|
|
252
|
+
const transform = transforms[i];
|
|
253
|
+
source = transform(source);
|
|
254
|
+
}
|
|
255
|
+
return source;
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
// export all as a frozen object
|
|
259
|
+
export const transforms = freeze({
|
|
260
|
+
rejectHtmlComments: freeze(rejectHtmlComments),
|
|
261
|
+
evadeHtmlCommentTest: freeze(evadeHtmlCommentTest),
|
|
262
|
+
rejectImportExpressions: freeze(rejectImportExpressions),
|
|
263
|
+
evadeImportExpressionTest: freeze(evadeImportExpressionTest),
|
|
264
|
+
rejectSomeDirectEvalExpressions: freeze(rejectSomeDirectEvalExpressions),
|
|
265
|
+
mandatoryTransforms: freeze(mandatoryTransforms),
|
|
266
|
+
applyTransforms: freeze(applyTransforms),
|
|
267
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Copyright (C) 2018 Agoric
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
import { freeze } from './src/commons.js';
|
|
16
|
+
import { transforms } from './src/transforms.js';
|
|
17
|
+
import { strictScopeTerminator } from './src/strict-scope-terminator.js';
|
|
18
|
+
import { createSloppyGlobalsScopeTerminator } from './src/sloppy-globals-scope-terminator.js';
|
|
19
|
+
|
|
20
|
+
export { transforms };
|
|
21
|
+
|
|
22
|
+
export const scopeTerminators = freeze({
|
|
23
|
+
strictScopeTerminator,
|
|
24
|
+
createSloppyGlobalsScopeTerminator,
|
|
25
|
+
});
|