@patrickdk77/script-defuse 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +187 -2
- package/dist/analyze.d.ts +22 -0
- package/dist/analyze.js +770 -0
- package/dist/api.d.ts +82 -0
- package/dist/api.js +698 -0
- package/dist/engine.d.ts +12 -0
- package/dist/engine.js +18 -0
- package/dist/findings.d.ts +19 -0
- package/dist/findings.js +79 -0
- package/dist/formcalc.d.ts +10 -0
- package/dist/formcalc.js +792 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +32 -0
- package/dist/index.mjs +3 -0
- package/dist/plugins.d.ts +28 -0
- package/dist/plugins.js +29 -0
- package/dist/score.d.ts +17 -0
- package/dist/score.js +51 -0
- package/dist/types.d.ts +130 -0
- package/dist/types.js +70 -0
- package/package.json +84 -4
package/dist/api.js
ADDED
|
@@ -0,0 +1,698 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SOM_ROOTS = exports.URL_ATTRIBUTES = exports.CODE_NODES = exports.NODE_DENY = exports.NODE_VALUES = exports.XFA_EVENT = exports.XFA_LAYOUT = exports.XFA_HOST = exports.XFA_ROOT = exports.HOST_DENY = exports.MACHINERY = exports.DENIED_GLOBALS = exports.BUILTIN_DENY = exports.BUILTIN_NAMESPACES = exports.BUILTIN_FUNCTIONS = exports.AFORM = exports.CONSTANT_ROOTS = exports.XMLDATA = exports.CONSOLE = exports.COLOR = exports.UTIL = exports.APP = exports.EVENT = exports.FIELD = exports.DOC_ALL = exports.DOC = exports.HOST_KINDS = void 0;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
exports.HOST_KINDS = new Set([
|
|
6
|
+
'doc',
|
|
7
|
+
'field',
|
|
8
|
+
'fields',
|
|
9
|
+
'event',
|
|
10
|
+
'app',
|
|
11
|
+
'util',
|
|
12
|
+
'color',
|
|
13
|
+
'console',
|
|
14
|
+
'constant',
|
|
15
|
+
'math',
|
|
16
|
+
'builtin',
|
|
17
|
+
'xmldata',
|
|
18
|
+
'xfa',
|
|
19
|
+
'xfahost',
|
|
20
|
+
'xfalayout',
|
|
21
|
+
'xfaevent',
|
|
22
|
+
'node',
|
|
23
|
+
]);
|
|
24
|
+
const ok = (kind, write = false) => ({ kind, write });
|
|
25
|
+
const bad = (c, d) => ({ finding: [c, d] });
|
|
26
|
+
function table(entries) {
|
|
27
|
+
return new Map(Object.entries(entries));
|
|
28
|
+
}
|
|
29
|
+
const url = bad(types_1.ScriptCategory.External, types_1.ScriptDetail.Url);
|
|
30
|
+
const submit = bad(types_1.ScriptCategory.External, types_1.ScriptDetail.Submit);
|
|
31
|
+
const mail = bad(types_1.ScriptCategory.External, types_1.ScriptDetail.Mail);
|
|
32
|
+
const openDoc = bad(types_1.ScriptCategory.External, types_1.ScriptDetail.OpenDocument);
|
|
33
|
+
const dataObject = bad(types_1.ScriptCategory.External, types_1.ScriptDetail.DataObject);
|
|
34
|
+
const importExport = bad(types_1.ScriptCategory.External, types_1.ScriptDetail.ImportExport);
|
|
35
|
+
const network = bad(types_1.ScriptCategory.External, types_1.ScriptDetail.Network);
|
|
36
|
+
const menu = bad(types_1.ScriptCategory.External, types_1.ScriptDetail.MenuCommand);
|
|
37
|
+
const print = bad(types_1.ScriptCategory.External, types_1.ScriptDetail.Print);
|
|
38
|
+
const save = bad(types_1.ScriptCategory.External, types_1.ScriptDetail.Save);
|
|
39
|
+
const timer = bad(types_1.ScriptCategory.DynamicCode, types_1.ScriptDetail.Timer);
|
|
40
|
+
const install = bad(types_1.ScriptCategory.DynamicCode, types_1.ScriptDetail.InstallScript);
|
|
41
|
+
const privilege = bad(types_1.ScriptCategory.DynamicCode, types_1.ScriptDetail.Privilege);
|
|
42
|
+
const exploited = bad(types_1.ScriptCategory.Api, types_1.ScriptDetail.Exploited);
|
|
43
|
+
/** The document: `this`, and what an unqualified name falls back to in a viewer. */
|
|
44
|
+
exports.DOC = table({
|
|
45
|
+
getField: ok('field'),
|
|
46
|
+
getNthFieldName: ok('string'),
|
|
47
|
+
numFields: ok('number'),
|
|
48
|
+
calculateNow: ok('data'),
|
|
49
|
+
resetForm: ok('data'),
|
|
50
|
+
dirty: ok('data', true),
|
|
51
|
+
calculate: ok('data', true),
|
|
52
|
+
pageNum: ok('number', true),
|
|
53
|
+
numPages: ok('number'),
|
|
54
|
+
// Privacy and view settings: no cached or autocompleted form data, the zoom, the page layout, deferred redraws.
|
|
55
|
+
nocache: ok('data', true),
|
|
56
|
+
noautocomplete: ok('data', true),
|
|
57
|
+
zoom: ok('number', true),
|
|
58
|
+
zoomType: ok('string', true),
|
|
59
|
+
layout: ok('string', true),
|
|
60
|
+
delay: ok('data', true),
|
|
61
|
+
scroll: ok('data'),
|
|
62
|
+
// An XFA document's form model, which bookmarks and other PDF-side scripts reach. The XFA tables check it.
|
|
63
|
+
xfa: ok('xfa'),
|
|
64
|
+
// Ways out of the form.
|
|
65
|
+
getURL: url,
|
|
66
|
+
submitForm: submit,
|
|
67
|
+
mailDoc: mail,
|
|
68
|
+
mailForm: mail,
|
|
69
|
+
openDataObject: dataObject,
|
|
70
|
+
exportDataObject: dataObject,
|
|
71
|
+
importDataObject: dataObject,
|
|
72
|
+
createDataObject: dataObject,
|
|
73
|
+
getDataObject: dataObject,
|
|
74
|
+
getDataObjectContents: dataObject,
|
|
75
|
+
setDataObjectContents: dataObject,
|
|
76
|
+
removeDataObject: dataObject,
|
|
77
|
+
dataObjects: dataObject,
|
|
78
|
+
embedDocAsDataObject: dataObject,
|
|
79
|
+
importAnFDF: importExport,
|
|
80
|
+
importAnXFDF: importExport,
|
|
81
|
+
importTextData: importExport,
|
|
82
|
+
importXFAData: importExport,
|
|
83
|
+
importIcon: importExport,
|
|
84
|
+
importSound: importExport,
|
|
85
|
+
exportAsFDF: importExport,
|
|
86
|
+
exportAsFDFStr: importExport,
|
|
87
|
+
exportAsXFDF: importExport,
|
|
88
|
+
exportAsXFDFStr: importExport,
|
|
89
|
+
exportAsText: importExport,
|
|
90
|
+
exportXFAData: importExport,
|
|
91
|
+
insertPages: importExport,
|
|
92
|
+
replacePages: importExport,
|
|
93
|
+
extractPages: importExport,
|
|
94
|
+
addWatermarkFromFile: importExport,
|
|
95
|
+
newPage: importExport,
|
|
96
|
+
print: print,
|
|
97
|
+
saveAs: save,
|
|
98
|
+
closeDoc: save,
|
|
99
|
+
addScript: install,
|
|
100
|
+
setAction: install,
|
|
101
|
+
setPageAction: install,
|
|
102
|
+
removeScript: install,
|
|
103
|
+
getAnnots: exploited,
|
|
104
|
+
getAnnot: exploited,
|
|
105
|
+
syncAnnotScan: exploited,
|
|
106
|
+
getIcon: exploited,
|
|
107
|
+
media: exploited,
|
|
108
|
+
Collab: network,
|
|
109
|
+
});
|
|
110
|
+
/**
|
|
111
|
+
* Every member Acrobat's Doc object has, form or not. A script that sets one of these on the document, or assigns to
|
|
112
|
+
* it as a bare name, sets the document's own property; any other name it sets is a global of its own.
|
|
113
|
+
*/
|
|
114
|
+
exports.DOC_ALL = new Set([
|
|
115
|
+
...exports.DOC.keys(),
|
|
116
|
+
'alternatePresentations',
|
|
117
|
+
'author',
|
|
118
|
+
'baseURL',
|
|
119
|
+
'bookmarkRoot',
|
|
120
|
+
'creationDate',
|
|
121
|
+
'creator',
|
|
122
|
+
'disclosed',
|
|
123
|
+
'docID',
|
|
124
|
+
'documentFileName',
|
|
125
|
+
'dynamicXFAForm',
|
|
126
|
+
'external',
|
|
127
|
+
'filesize',
|
|
128
|
+
'hidden',
|
|
129
|
+
'hostContainer',
|
|
130
|
+
'icons',
|
|
131
|
+
'info',
|
|
132
|
+
'innerAppWindowRect',
|
|
133
|
+
'innerDocWindowRect',
|
|
134
|
+
'isModal',
|
|
135
|
+
'keywords',
|
|
136
|
+
'metadata',
|
|
137
|
+
'modDate',
|
|
138
|
+
'mouseX',
|
|
139
|
+
'mouseY',
|
|
140
|
+
'numTemplates',
|
|
141
|
+
'outerAppWindowRect',
|
|
142
|
+
'outerDocWindowRect',
|
|
143
|
+
'pageWindowRect',
|
|
144
|
+
'path',
|
|
145
|
+
'permStatusReady',
|
|
146
|
+
'producer',
|
|
147
|
+
'requiresFullSave',
|
|
148
|
+
'securityHandler',
|
|
149
|
+
'selectedAnnots',
|
|
150
|
+
'sounds',
|
|
151
|
+
'spellDictionaryOrder',
|
|
152
|
+
'spellLanguageOrder',
|
|
153
|
+
'subject',
|
|
154
|
+
'templates',
|
|
155
|
+
'title',
|
|
156
|
+
'URL',
|
|
157
|
+
'viewState',
|
|
158
|
+
'XFAForeground',
|
|
159
|
+
'addAnnot',
|
|
160
|
+
'addField',
|
|
161
|
+
'addIcon',
|
|
162
|
+
'addLink',
|
|
163
|
+
'addRecipientListCryptFilter',
|
|
164
|
+
'addRequirement',
|
|
165
|
+
'addThumbnails',
|
|
166
|
+
'addWatermarkFromText',
|
|
167
|
+
'addWeblinks',
|
|
168
|
+
'applyRedactions',
|
|
169
|
+
'bringToFront',
|
|
170
|
+
'certifyInvisibleSign',
|
|
171
|
+
'colorConvertPage',
|
|
172
|
+
'createTemplate',
|
|
173
|
+
'deletePages',
|
|
174
|
+
'deleteSound',
|
|
175
|
+
'embedOutputIntent',
|
|
176
|
+
'encryptForRecipients',
|
|
177
|
+
'encryptUsingPolicy',
|
|
178
|
+
'flattenPages',
|
|
179
|
+
'getAnnot3D',
|
|
180
|
+
'getAnnots3D',
|
|
181
|
+
'getColorConvertAction',
|
|
182
|
+
'getLegalWarnings',
|
|
183
|
+
'getLinks',
|
|
184
|
+
'getNthTemplate',
|
|
185
|
+
'getOCGs',
|
|
186
|
+
'getOCGOrder',
|
|
187
|
+
'getPageBox',
|
|
188
|
+
'getPageLabel',
|
|
189
|
+
'getPageNthWord',
|
|
190
|
+
'getPageNthWordQuads',
|
|
191
|
+
'getPageNumWords',
|
|
192
|
+
'getPageRotation',
|
|
193
|
+
'getPageTransition',
|
|
194
|
+
'getPrintParams',
|
|
195
|
+
'getSound',
|
|
196
|
+
'getTemplate',
|
|
197
|
+
'gotoNamedDest',
|
|
198
|
+
'movePage',
|
|
199
|
+
'preflight',
|
|
200
|
+
'removeField',
|
|
201
|
+
'removeIcon',
|
|
202
|
+
'removeLinks',
|
|
203
|
+
'removeRequirement',
|
|
204
|
+
'removeTemplate',
|
|
205
|
+
'removeThumbnails',
|
|
206
|
+
'removeWeblinks',
|
|
207
|
+
'selectPageNthWord',
|
|
208
|
+
'setOCGOrder',
|
|
209
|
+
'setPageBoxes',
|
|
210
|
+
'setPageLabels',
|
|
211
|
+
'setPageRotations',
|
|
212
|
+
'setPageTabOrder',
|
|
213
|
+
'setPageTransitions',
|
|
214
|
+
'spawnPageFromTemplate',
|
|
215
|
+
'timestampSign',
|
|
216
|
+
'validatePreflightAudit',
|
|
217
|
+
]);
|
|
218
|
+
/**
|
|
219
|
+
* A form field, from getField, event.target or event.source: Acrobat's whole Field object. Since every member it has
|
|
220
|
+
* is here, any other name on a field is one the form set itself, such as event.target.oldVal.
|
|
221
|
+
*/
|
|
222
|
+
exports.FIELD = table({
|
|
223
|
+
doc: ok('doc'),
|
|
224
|
+
multipleSelection: ok('data', true),
|
|
225
|
+
print: ok('data', true),
|
|
226
|
+
buttonGetIcon: ok('data'),
|
|
227
|
+
buttonSetIcon: ok('data'),
|
|
228
|
+
getLock: ok('data'),
|
|
229
|
+
setLock: ok('data'),
|
|
230
|
+
value: ok('data', true),
|
|
231
|
+
valueAsString: ok('string'),
|
|
232
|
+
name: ok('string'),
|
|
233
|
+
type: ok('string'),
|
|
234
|
+
display: ok('number', true),
|
|
235
|
+
hidden: ok('data', true),
|
|
236
|
+
readonly: ok('data', true),
|
|
237
|
+
required: ok('data', true),
|
|
238
|
+
textColor: ok('data', true),
|
|
239
|
+
fillColor: ok('data', true),
|
|
240
|
+
bgColor: ok('data', true),
|
|
241
|
+
fgColor: ok('data', true),
|
|
242
|
+
borderColor: ok('data', true),
|
|
243
|
+
strokeColor: ok('data', true),
|
|
244
|
+
textSize: ok('number', true),
|
|
245
|
+
textFont: ok('data', true),
|
|
246
|
+
alignment: ok('string', true),
|
|
247
|
+
charLimit: ok('number', true),
|
|
248
|
+
defaultValue: ok('data', true),
|
|
249
|
+
exportValues: ok('data', true),
|
|
250
|
+
numItems: ok('number'),
|
|
251
|
+
currentValueIndices: ok('data', true),
|
|
252
|
+
getItemAt: ok('string'),
|
|
253
|
+
setItems: ok('data'),
|
|
254
|
+
insertItemAt: ok('data'),
|
|
255
|
+
deleteItemAt: ok('data'),
|
|
256
|
+
clearItems: ok('data'),
|
|
257
|
+
isBoxChecked: ok('data'),
|
|
258
|
+
isDefaultChecked: ok('data'),
|
|
259
|
+
checkThisBox: ok('data'),
|
|
260
|
+
defaultIsChecked: ok('data'),
|
|
261
|
+
page: ok('data'),
|
|
262
|
+
rect: ok('data', true),
|
|
263
|
+
setFocus: ok('data'),
|
|
264
|
+
buttonGetCaption: ok('string'),
|
|
265
|
+
buttonSetCaption: ok('data'),
|
|
266
|
+
editable: ok('data', true),
|
|
267
|
+
multiline: ok('data', true),
|
|
268
|
+
comb: ok('data', true),
|
|
269
|
+
doNotScroll: ok('data', true),
|
|
270
|
+
doNotSpellCheck: ok('data', true),
|
|
271
|
+
password: ok('data', true),
|
|
272
|
+
userName: ok('string', true),
|
|
273
|
+
rotation: ok('number', true),
|
|
274
|
+
lineWidth: ok('number', true),
|
|
275
|
+
borderStyle: ok('data', true),
|
|
276
|
+
calcOrderIndex: ok('number', true),
|
|
277
|
+
commitOnSelChange: ok('data', true),
|
|
278
|
+
radiosInUnison: ok('data', true),
|
|
279
|
+
richText: ok('data', true),
|
|
280
|
+
richValue: ok('data', true),
|
|
281
|
+
defaultStyle: ok('data', true),
|
|
282
|
+
style: ok('data', true),
|
|
283
|
+
highlight: ok('data', true),
|
|
284
|
+
delay: ok('data', true),
|
|
285
|
+
buttonAlignX: ok('number', true),
|
|
286
|
+
buttonAlignY: ok('number', true),
|
|
287
|
+
buttonFitBounds: ok('data', true),
|
|
288
|
+
buttonPosition: ok('number', true),
|
|
289
|
+
buttonScaleHow: ok('number', true),
|
|
290
|
+
buttonScaleWhen: ok('number', true),
|
|
291
|
+
getArray: ok('fields'),
|
|
292
|
+
setAction: install,
|
|
293
|
+
buttonImportIcon: importExport,
|
|
294
|
+
browseForFileToSubmit: importExport,
|
|
295
|
+
fileSelect: importExport,
|
|
296
|
+
submitName: submit,
|
|
297
|
+
signatureSign: exploited,
|
|
298
|
+
signatureSetSeedValue: exploited,
|
|
299
|
+
signatureValidate: exploited,
|
|
300
|
+
signatureInfo: exploited,
|
|
301
|
+
signatureGetSeedValue: exploited,
|
|
302
|
+
signatureGetModifications: exploited,
|
|
303
|
+
});
|
|
304
|
+
/** `event`, the object a field or document script runs for. */
|
|
305
|
+
exports.EVENT = table({
|
|
306
|
+
value: ok('data', true),
|
|
307
|
+
valueAsString: ok('string'),
|
|
308
|
+
change: ok('string', true),
|
|
309
|
+
changeEx: ok('data'),
|
|
310
|
+
commitKey: ok('number'),
|
|
311
|
+
fieldFull: ok('data'),
|
|
312
|
+
keyDown: ok('data'),
|
|
313
|
+
modifier: ok('data'),
|
|
314
|
+
name: ok('string'),
|
|
315
|
+
rc: ok('data', true),
|
|
316
|
+
richChange: ok('data', true),
|
|
317
|
+
richChangeEx: ok('data', true),
|
|
318
|
+
richValue: ok('data', true),
|
|
319
|
+
selEnd: ok('number', true),
|
|
320
|
+
selStart: ok('number', true),
|
|
321
|
+
shift: ok('data'),
|
|
322
|
+
source: ok('field'),
|
|
323
|
+
target: ok('field'),
|
|
324
|
+
targetName: ok('string'),
|
|
325
|
+
type: ok('string'),
|
|
326
|
+
willCommit: ok('data'),
|
|
327
|
+
});
|
|
328
|
+
/** `app`, the viewer. Message boxes and version checks only. */
|
|
329
|
+
exports.APP = table({
|
|
330
|
+
alert: ok('data'),
|
|
331
|
+
beep: ok('data'),
|
|
332
|
+
response: ok('string'),
|
|
333
|
+
viewerVersion: ok('number'),
|
|
334
|
+
viewerType: ok('string'),
|
|
335
|
+
viewerVariation: ok('string'),
|
|
336
|
+
platform: ok('string'),
|
|
337
|
+
language: ok('string'),
|
|
338
|
+
formsVersion: ok('number'),
|
|
339
|
+
calculate: ok('data', true),
|
|
340
|
+
runtimeHighlight: ok('data', true),
|
|
341
|
+
runtimeHighlightColor: ok('data', true),
|
|
342
|
+
focusRect: ok('data', true),
|
|
343
|
+
launchURL: url,
|
|
344
|
+
openDoc: openDoc,
|
|
345
|
+
newDoc: openDoc,
|
|
346
|
+
openFDF: importExport,
|
|
347
|
+
newFDF: importExport,
|
|
348
|
+
browseForDoc: importExport,
|
|
349
|
+
mailMsg: mail,
|
|
350
|
+
mailGetAddrs: mail,
|
|
351
|
+
execMenuItem: menu,
|
|
352
|
+
execDialog: menu,
|
|
353
|
+
addMenuItem: install,
|
|
354
|
+
addSubMenu: install,
|
|
355
|
+
addToolButton: install,
|
|
356
|
+
setTimeOut: timer,
|
|
357
|
+
setInterval: timer,
|
|
358
|
+
clearTimeOut: timer,
|
|
359
|
+
clearInterval: timer,
|
|
360
|
+
trustedFunction: privilege,
|
|
361
|
+
beginPriv: privilege,
|
|
362
|
+
endPriv: privilege,
|
|
363
|
+
trustPropagatorFunction: privilege,
|
|
364
|
+
loadPolicyFile: privilege,
|
|
365
|
+
activeDocs: openDoc,
|
|
366
|
+
doc: openDoc,
|
|
367
|
+
fs: importExport,
|
|
368
|
+
media: exploited,
|
|
369
|
+
printColorProfiles: exploited,
|
|
370
|
+
printerNames: exploited,
|
|
371
|
+
plugIns: exploited,
|
|
372
|
+
plugins: exploited,
|
|
373
|
+
monitors: exploited,
|
|
374
|
+
getPath: importExport,
|
|
375
|
+
});
|
|
376
|
+
/** `util`: formatting and parsing text, numbers and dates. */
|
|
377
|
+
exports.UTIL = table({
|
|
378
|
+
printf: ok('string'),
|
|
379
|
+
printd: ok('string'),
|
|
380
|
+
printx: ok('string'),
|
|
381
|
+
scand: ok('data'),
|
|
382
|
+
stringFromStream: dataObject,
|
|
383
|
+
streamFromString: dataObject,
|
|
384
|
+
iconStreamFromIcon: dataObject,
|
|
385
|
+
readFileIntoStream: importExport,
|
|
386
|
+
spansToXML: ok('string'),
|
|
387
|
+
xmlToSpans: ok('data'),
|
|
388
|
+
crackURL: ok('data'),
|
|
389
|
+
});
|
|
390
|
+
exports.COLOR = table({
|
|
391
|
+
transparent: ok('data'),
|
|
392
|
+
black: ok('data'),
|
|
393
|
+
white: ok('data'),
|
|
394
|
+
red: ok('data'),
|
|
395
|
+
green: ok('data'),
|
|
396
|
+
blue: ok('data'),
|
|
397
|
+
cyan: ok('data'),
|
|
398
|
+
magenta: ok('data'),
|
|
399
|
+
yellow: ok('data'),
|
|
400
|
+
dkGray: ok('data'),
|
|
401
|
+
gray: ok('data'),
|
|
402
|
+
ltGray: ok('data'),
|
|
403
|
+
convert: ok('data'),
|
|
404
|
+
equal: ok('data'),
|
|
405
|
+
});
|
|
406
|
+
exports.CONSOLE = table({ println: ok('data'), show: ok('data'), hide: ok('data'), clear: ok('data') });
|
|
407
|
+
/** `XMLData`, which parses XML text a form holds and queries it. Its parse is checked for entities on its own. */
|
|
408
|
+
exports.XMLDATA = table({ parse: ok('data'), applyXPath: ok('data') });
|
|
409
|
+
/** Namespaces of constants a form script reads, such as display.hidden. Any member of them is a constant. */
|
|
410
|
+
exports.CONSTANT_ROOTS = new Set(['display', 'border', 'style', 'font', 'highlight', 'position', 'scaleHow', 'scaleWhen', 'zoomtype', 'cursor', 'textures']);
|
|
411
|
+
/** Acrobat's AForm helpers, which format, check and calculate fields. */
|
|
412
|
+
exports.AFORM = new Set([
|
|
413
|
+
'AFDate_Format',
|
|
414
|
+
'AFDate_FormatEx',
|
|
415
|
+
'AFDate_Keystroke',
|
|
416
|
+
'AFDate_KeystrokeEx',
|
|
417
|
+
'AFExactMatch',
|
|
418
|
+
'AFExtractNums',
|
|
419
|
+
'AFMakeArrayFromList',
|
|
420
|
+
'AFMakeNumber',
|
|
421
|
+
'AFMergeChange',
|
|
422
|
+
'AFNumber_Format',
|
|
423
|
+
'AFNumber_Keystroke',
|
|
424
|
+
'AFParseDateEx',
|
|
425
|
+
'AFPercent_Format',
|
|
426
|
+
'AFPercent_Keystroke',
|
|
427
|
+
'AFRange_Validate',
|
|
428
|
+
'AFSimple',
|
|
429
|
+
'AFSimple_Calculate',
|
|
430
|
+
'AFSpecial_Format',
|
|
431
|
+
'AFSpecial_Keystroke',
|
|
432
|
+
'AFSpecial_KeystrokeEx',
|
|
433
|
+
'AFTime_Format',
|
|
434
|
+
'AFTime_FormatEx',
|
|
435
|
+
'AFTime_Keystroke',
|
|
436
|
+
'AFTime_KeystrokeEx',
|
|
437
|
+
'AFParseTime',
|
|
438
|
+
'AFParseDate',
|
|
439
|
+
'AFGetMonthIndex',
|
|
440
|
+
'AFMatchMonth',
|
|
441
|
+
'AFDefineDateString',
|
|
442
|
+
]);
|
|
443
|
+
/** Global functions and namespaces of the language itself that compute on data. */
|
|
444
|
+
exports.BUILTIN_FUNCTIONS = new Map([
|
|
445
|
+
['parseInt', 'number'],
|
|
446
|
+
['parseFloat', 'number'],
|
|
447
|
+
['isNaN', 'data'],
|
|
448
|
+
['isFinite', 'data'],
|
|
449
|
+
['Number', 'number'],
|
|
450
|
+
['String', 'string'],
|
|
451
|
+
['Boolean', 'data'],
|
|
452
|
+
['Array', 'data'],
|
|
453
|
+
['Date', 'data'],
|
|
454
|
+
['RegExp', 'data'],
|
|
455
|
+
['Error', 'data'],
|
|
456
|
+
['TypeError', 'data'],
|
|
457
|
+
['RangeError', 'data'],
|
|
458
|
+
['encodeURIComponent', 'string'],
|
|
459
|
+
['encodeURI', 'string'],
|
|
460
|
+
]);
|
|
461
|
+
/** Namespaces whose members are pure computation, apart from the ones named in BUILTIN_DENY. */
|
|
462
|
+
exports.BUILTIN_NAMESPACES = new Set(['Math', 'Number', 'String', 'Date', 'JSON', 'Array', 'Object', 'Boolean']);
|
|
463
|
+
/** Members of those namespaces that hide text or reach the machinery behind objects. */
|
|
464
|
+
exports.BUILTIN_DENY = new Map([
|
|
465
|
+
['fromCharCode', bad(types_1.ScriptCategory.Obfuscation, types_1.ScriptDetail.CharCodes)],
|
|
466
|
+
['fromCodePoint', bad(types_1.ScriptCategory.Obfuscation, types_1.ScriptDetail.CharCodes)],
|
|
467
|
+
['defineProperty', bad(types_1.ScriptCategory.DynamicCode, types_1.ScriptDetail.Prototype)],
|
|
468
|
+
['defineProperties', bad(types_1.ScriptCategory.DynamicCode, types_1.ScriptDetail.Prototype)],
|
|
469
|
+
['setPrototypeOf', bad(types_1.ScriptCategory.DynamicCode, types_1.ScriptDetail.Prototype)],
|
|
470
|
+
['getPrototypeOf', bad(types_1.ScriptCategory.DynamicCode, types_1.ScriptDetail.Prototype)],
|
|
471
|
+
['getOwnPropertyDescriptor', bad(types_1.ScriptCategory.DynamicCode, types_1.ScriptDetail.Prototype)],
|
|
472
|
+
['create', bad(types_1.ScriptCategory.DynamicCode, types_1.ScriptDetail.Prototype)],
|
|
473
|
+
['assign', bad(types_1.ScriptCategory.DynamicCode, types_1.ScriptDetail.Prototype)],
|
|
474
|
+
]);
|
|
475
|
+
/** Global names that are themselves a finding, wherever they appear. */
|
|
476
|
+
exports.DENIED_GLOBALS = new Map([
|
|
477
|
+
['eval', bad(types_1.ScriptCategory.DynamicCode, types_1.ScriptDetail.Eval)],
|
|
478
|
+
['Function', bad(types_1.ScriptCategory.DynamicCode, types_1.ScriptDetail.Eval)],
|
|
479
|
+
['setTimeout', timer],
|
|
480
|
+
['setInterval', timer],
|
|
481
|
+
['unescape', bad(types_1.ScriptCategory.Obfuscation, types_1.ScriptDetail.Decode)],
|
|
482
|
+
['escape', bad(types_1.ScriptCategory.Obfuscation, types_1.ScriptDetail.Decode)],
|
|
483
|
+
['decodeURIComponent', bad(types_1.ScriptCategory.Obfuscation, types_1.ScriptDetail.Decode)],
|
|
484
|
+
['decodeURI', bad(types_1.ScriptCategory.Obfuscation, types_1.ScriptDetail.Decode)],
|
|
485
|
+
['atob', bad(types_1.ScriptCategory.Obfuscation, types_1.ScriptDetail.Decode)],
|
|
486
|
+
['btoa', bad(types_1.ScriptCategory.Obfuscation, types_1.ScriptDetail.Decode)],
|
|
487
|
+
['Net', network],
|
|
488
|
+
['SOAP', network],
|
|
489
|
+
['Collab', network],
|
|
490
|
+
['ADBC', network],
|
|
491
|
+
['Connection', network],
|
|
492
|
+
['RSS', network],
|
|
493
|
+
['identity', network],
|
|
494
|
+
['security', privilege],
|
|
495
|
+
['spell', exploited],
|
|
496
|
+
['media', exploited],
|
|
497
|
+
['search', exploited],
|
|
498
|
+
['getURL', url],
|
|
499
|
+
['submitForm', submit],
|
|
500
|
+
['mailDoc', mail],
|
|
501
|
+
['mailForm', mail],
|
|
502
|
+
['global', bad(types_1.ScriptCategory.Api, types_1.ScriptDetail.Unknown)],
|
|
503
|
+
['Proxy', bad(types_1.ScriptCategory.DynamicCode, types_1.ScriptDetail.Prototype)],
|
|
504
|
+
['Reflect', bad(types_1.ScriptCategory.DynamicCode, types_1.ScriptDetail.Prototype)],
|
|
505
|
+
['Symbol', bad(types_1.ScriptCategory.DynamicCode, types_1.ScriptDetail.Prototype)],
|
|
506
|
+
['Report', openDoc],
|
|
507
|
+
['catalog', importExport],
|
|
508
|
+
]);
|
|
509
|
+
/** Member names that reach the language machinery on any value. */
|
|
510
|
+
exports.MACHINERY = new Set(['constructor', '__proto__', 'prototype', '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'caller', 'callee']);
|
|
511
|
+
/**
|
|
512
|
+
* Member names a viewer object has that are not form computation. A plain value, such as a function's parameter,
|
|
513
|
+
* might hold a viewer object, so one of these names on it gets the finding the object would have.
|
|
514
|
+
*/
|
|
515
|
+
exports.HOST_DENY = (() => {
|
|
516
|
+
const m = new Map();
|
|
517
|
+
for (const t of [exports.DOC, exports.FIELD, exports.APP, exports.UTIL])
|
|
518
|
+
for (const [name, member] of t) {
|
|
519
|
+
if ('finding' in member && !m.has(name))
|
|
520
|
+
m.set(name, member);
|
|
521
|
+
}
|
|
522
|
+
return m;
|
|
523
|
+
})();
|
|
524
|
+
// ---------- XFA ----------
|
|
525
|
+
/**
|
|
526
|
+
* `xfa`, the root of an XFA form's object model. Its models are trees of form nodes, apart from the host, the
|
|
527
|
+
* layout and the event, and the connections, sources and signatures that reach outside the form.
|
|
528
|
+
*/
|
|
529
|
+
exports.XFA_ROOT = table({
|
|
530
|
+
host: ok('xfahost'),
|
|
531
|
+
layout: ok('xfalayout'),
|
|
532
|
+
event: ok('xfaevent'),
|
|
533
|
+
form: ok('node'),
|
|
534
|
+
template: ok('node'),
|
|
535
|
+
data: ok('node'),
|
|
536
|
+
datasets: ok('node'),
|
|
537
|
+
record: ok('node'),
|
|
538
|
+
dataWindow: ok('node'),
|
|
539
|
+
config: ok('node'),
|
|
540
|
+
localeSet: ok('node'),
|
|
541
|
+
context: ok('node'),
|
|
542
|
+
log: ok('node'),
|
|
543
|
+
resolveNode: ok('node'),
|
|
544
|
+
resolveNodes: ok('node'),
|
|
545
|
+
createNode: ok('node'),
|
|
546
|
+
isCompatibleNS: ok('data'),
|
|
547
|
+
isPropertySpecified: ok('data'),
|
|
548
|
+
nodes: ok('node'),
|
|
549
|
+
parent: ok('node'),
|
|
550
|
+
all: ok('node'),
|
|
551
|
+
oneOfChild: ok('node'),
|
|
552
|
+
name: ok('string'),
|
|
553
|
+
className: ok('string'),
|
|
554
|
+
somExpression: ok('string'),
|
|
555
|
+
connectionSet: network,
|
|
556
|
+
sourceSet: network,
|
|
557
|
+
signature: exploited,
|
|
558
|
+
});
|
|
559
|
+
/** `xfa.host`, the viewer as an XFA form sees it. Message boxes, focus, pages and version checks. */
|
|
560
|
+
exports.XFA_HOST = table({
|
|
561
|
+
appType: ok('string'),
|
|
562
|
+
calculationsEnabled: ok('data', true),
|
|
563
|
+
currentPage: ok('number', true),
|
|
564
|
+
language: ok('string'),
|
|
565
|
+
name: ok('string'),
|
|
566
|
+
numPages: ok('number'),
|
|
567
|
+
platform: ok('string'),
|
|
568
|
+
title: ok('string', true),
|
|
569
|
+
validationsEnabled: ok('data', true),
|
|
570
|
+
variation: ok('string'),
|
|
571
|
+
version: ok('string'),
|
|
572
|
+
beep: ok('data'),
|
|
573
|
+
documentCountInBatch: ok('number'),
|
|
574
|
+
documentInBatch: ok('number'),
|
|
575
|
+
getFocus: ok('node'),
|
|
576
|
+
messageBox: ok('number'),
|
|
577
|
+
pageDown: ok('data'),
|
|
578
|
+
pageUp: ok('data'),
|
|
579
|
+
resetData: ok('data'),
|
|
580
|
+
response: ok('string'),
|
|
581
|
+
setFocus: ok('data'),
|
|
582
|
+
openList: ok('data'),
|
|
583
|
+
gotoURL: url,
|
|
584
|
+
exportData: importExport,
|
|
585
|
+
importData: importExport,
|
|
586
|
+
print: print,
|
|
587
|
+
});
|
|
588
|
+
/** `xfa.layout`: where nodes fall on pages. */
|
|
589
|
+
exports.XFA_LAYOUT = table({
|
|
590
|
+
absPage: ok('number'),
|
|
591
|
+
absPageCount: ok('number'),
|
|
592
|
+
absPageCountInBatch: ok('number'),
|
|
593
|
+
absPageInBatch: ok('number'),
|
|
594
|
+
absPageSpan: ok('number'),
|
|
595
|
+
h: ok('number'),
|
|
596
|
+
w: ok('number'),
|
|
597
|
+
x: ok('number'),
|
|
598
|
+
y: ok('number'),
|
|
599
|
+
page: ok('number'),
|
|
600
|
+
pageContent: ok('node'),
|
|
601
|
+
pageCount: ok('number'),
|
|
602
|
+
pageSpan: ok('number'),
|
|
603
|
+
relayout: ok('data'),
|
|
604
|
+
relayoutPageArea: ok('data'),
|
|
605
|
+
sheet: ok('number'),
|
|
606
|
+
sheetCount: ok('number'),
|
|
607
|
+
sheetCountInBatch: ok('number'),
|
|
608
|
+
sheetInBatch: ok('number'),
|
|
609
|
+
ready: ok('data'),
|
|
610
|
+
});
|
|
611
|
+
/**
|
|
612
|
+
* `event` in an XFA script, and `xfa.event`: the XFA event's members and those of Acrobat's event object. Its target
|
|
613
|
+
* is the Acrobat document.
|
|
614
|
+
*/
|
|
615
|
+
exports.XFA_EVENT = new Map([
|
|
616
|
+
...exports.EVENT,
|
|
617
|
+
['change', ok('string', true)],
|
|
618
|
+
['commitKey', ok('number')],
|
|
619
|
+
['fullText', ok('string')],
|
|
620
|
+
['keyDown', ok('data')],
|
|
621
|
+
['modifier', ok('data')],
|
|
622
|
+
['name', ok('string')],
|
|
623
|
+
['newContentType', ok('string')],
|
|
624
|
+
['newText', ok('string')],
|
|
625
|
+
['prevContentType', ok('string')],
|
|
626
|
+
['prevText', ok('string')],
|
|
627
|
+
['reenter', ok('data')],
|
|
628
|
+
['selEnd', ok('number', true)],
|
|
629
|
+
['selStart', ok('number', true)],
|
|
630
|
+
['shift', ok('data')],
|
|
631
|
+
['soapFaultCode', ok('string')],
|
|
632
|
+
['soapFaultString', ok('string')],
|
|
633
|
+
['cancelAction', ok('data', true)],
|
|
634
|
+
['target', ok('doc')],
|
|
635
|
+
]);
|
|
636
|
+
/** Members of a form node that hold its value, rather than another node. Any other member is a node. */
|
|
637
|
+
exports.NODE_VALUES = new Map([
|
|
638
|
+
['rawValue', 'data'],
|
|
639
|
+
['formattedValue', 'string'],
|
|
640
|
+
['editValue', 'string'],
|
|
641
|
+
['isNull', 'data'],
|
|
642
|
+
['length', 'number'],
|
|
643
|
+
['index', 'number'],
|
|
644
|
+
['classIndex', 'number'],
|
|
645
|
+
['name', 'string'],
|
|
646
|
+
['className', 'string'],
|
|
647
|
+
['somExpression', 'string'],
|
|
648
|
+
['value', 'node'],
|
|
649
|
+
]);
|
|
650
|
+
/**
|
|
651
|
+
* Members of form nodes, and of XFA's host and connections reached through a node, that leave the form or run what
|
|
652
|
+
* the form did not carry. A node can be any object of the model, so any of these names on one is a finding.
|
|
653
|
+
*/
|
|
654
|
+
exports.NODE_DENY = new Map([
|
|
655
|
+
['connectionSet', network],
|
|
656
|
+
['sourceSet', network],
|
|
657
|
+
['execute', network],
|
|
658
|
+
['signature', exploited],
|
|
659
|
+
['gotoURL', url],
|
|
660
|
+
['exportData', importExport],
|
|
661
|
+
['importData', importExport],
|
|
662
|
+
['applyXSL', bad(types_1.ScriptCategory.DynamicCode, types_1.ScriptDetail.Eval)],
|
|
663
|
+
]);
|
|
664
|
+
/** Node types a script may not create: they would carry script, actions or content from outside the form. */
|
|
665
|
+
exports.CODE_NODES = new Set([
|
|
666
|
+
'script',
|
|
667
|
+
'event',
|
|
668
|
+
'calculate',
|
|
669
|
+
'validate',
|
|
670
|
+
'variables',
|
|
671
|
+
'submit',
|
|
672
|
+
'execute',
|
|
673
|
+
'signData',
|
|
674
|
+
'encryptData',
|
|
675
|
+
'exObject',
|
|
676
|
+
'connect',
|
|
677
|
+
'image',
|
|
678
|
+
'exData',
|
|
679
|
+
'proto',
|
|
680
|
+
]);
|
|
681
|
+
/** Attributes of a node that name something outside the form. */
|
|
682
|
+
exports.URL_ATTRIBUTES = new Set(['href', 'usehref', 'use', 'target', 'url', 'server', 'codeBase', 'archive', 'classId']);
|
|
683
|
+
/** Roots of the SOM in an XFA script, written with `$`. `!` is the datasets model. */
|
|
684
|
+
exports.SOM_ROOTS = new Map([
|
|
685
|
+
['$', 'node'],
|
|
686
|
+
['$form', 'node'],
|
|
687
|
+
['$data', 'node'],
|
|
688
|
+
['$record', 'node'],
|
|
689
|
+
['$template', 'node'],
|
|
690
|
+
['$config', 'node'],
|
|
691
|
+
['$xfa', 'xfa'],
|
|
692
|
+
['$host', 'xfahost'],
|
|
693
|
+
['$layout', 'xfalayout'],
|
|
694
|
+
['$event', 'xfaevent'],
|
|
695
|
+
['$connectionSet', network],
|
|
696
|
+
['$sourceSet', network],
|
|
697
|
+
['$signature', exploited],
|
|
698
|
+
]);
|