Skip to content

Commit 9a17cb7

Browse files
committed
Fix #398 and Fix #399 Add targetConfig.policy.unchainAcl config to unchain policy objects to Object.prototype
1 parent 9dfdf9d commit 9a17cb7

File tree

6 files changed

+81
-2
lines changed

6 files changed

+81
-2
lines changed

demo-config/config.js

+2
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,8 @@ class TargetConfig extends Injectable(Traceable(Configurable(GulpDefaultRegistry
824824
__hook__min: true, // undefined to skip including plugins/policy/__hook__min.js
825825
// @ifdef argument to include/exclude hookBenchmark() in hook-callback.js
826826
hookBenchmark: true, // undefined to exclude hookBenchmark()
827+
// @ifdef argument to unchain ACL policy objects if they are chained directly to Object.prototype
828+
//unchainAcl: true, // uncomment this argument to enable vulnerability fix for #398 and #399
827829
// postfix to the hook callback function name __hook__
828830
__hook__callback: 'acl', // '': __hook__, 'acl': __hook__acl, 'min': __hook__min
829831
// TODO: modify plugin/policy/hook-callback.js to use hook.parameters.emptyDocumentUrl

demo-config/policy/basePolicyModule.js

+15
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,21 @@ acl: {
424424
'@HTMLElement_prototype_reader': 'r--',
425425
'@Object_prototype_reader': 'r-x',
426426
'@window_enumerator': 'r--R-',
427+
/* @ifdef unchainAcl */
428+
$toString$: {
429+
[S_DEFAULT]: '---',
430+
'@Object_assign_reader': 'r--',
431+
'@Object_prototype_reader': 'r-x',
432+
'@chai_js': 'r--',
433+
'@deepcopy': 'r--',
434+
},
435+
$hasOwnProperty$: {
436+
[S_DEFAULT]: '---',
437+
'@firebase_auth': 'r--',
438+
'@firebase_app': 'r--',
439+
'@firebase_database': 'r--',
440+
},
441+
/* @endif */
427442
[S_INSTANCE]: {
428443
$__proto__$: 'rwx',
429444
$constructor$: 'rwxRW',

plugins/policy/Policy.js

+59
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,35 @@ Copyright (c) 2017, 2018, 2019, 2020 Tetsuya Mori <[email protected]>. All ri
817817
}
818818
chainAcl(acl);
819819
}
820+
/* @ifdef unchainAcl */
821+
static unchainAcl(acl) {
822+
const unchainAcl = function unchainAcl(_acl, path = [ [_acl, 'acl'] ]) {
823+
let properties = Object.getOwnPropertySymbols(_acl).concat(Object.getOwnPropertyNames(_acl));
824+
if (!_acl[S_CHAIN]) {
825+
Reflect.setPrototypeOf(_acl, null);
826+
}
827+
for (let property of properties) {
828+
if (property === S_CHAIN) {
829+
}
830+
else {
831+
let __acl = _acl[property];
832+
switch (typeof __acl) {
833+
case 'object':
834+
if (__acl) {
835+
path.push([__acl, property]);
836+
unchainAcl(__acl, path);
837+
path.pop();
838+
}
839+
break;
840+
default:
841+
break;
842+
}
843+
}
844+
}
845+
}
846+
unchainAcl(acl);
847+
}
848+
/* @endif */
820849
static mergeAcl(target, ...sources) {
821850
const originalTarget = target;
822851
const mergeAcl = function mergeAcl(target, source) {
@@ -1352,23 +1381,38 @@ Copyright (c) 2017, 2018, 2019, 2020 Tetsuya Mori <[email protected]>. All ri
13521381
case 'undefined':
13531382
_acl = Reflect.has(_acl, property)
13541383
? isGlobal
1384+
/* @ifndef unchainAcl */
13551385
? _acl[property] instanceof Object && Reflect.has(_acl[property], S_OBJECT)
1386+
/* @endif */
1387+
/* @ifdef unchainAcl */
1388+
? _acl[property] && typeof _acl[property] === 'object' && Reflect.has(_acl[property], S_OBJECT)
1389+
/* @endif */
13561390
? _acl[property][S_OBJECT]
13571391
: _acl[property]
13581392
: _acl[property]
13591393
: Reflect.has(_acl, context)
13601394
? context === S_DEFAULT
13611395
? isGlobal
13621396
? Reflect.has(acl, property)
1397+
/* @ifndef unchainAcl */
13631398
? acl[property] instanceof Object && Reflect.has(acl[property], S_OBJECT)
1399+
/* @endif */
1400+
/* @ifdef unchainAcl */
1401+
? acl[property] && typeof acl[property] === 'object' && Reflect.has(acl[property], S_OBJECT)
1402+
/* @endif */
13641403
? acl[property][S_OBJECT]
13651404
: acl[property]
13661405
: acl[S_GLOBAL]
13671406
: _acl[context]
13681407
: _acl[context]
13691408
: isGlobal
13701409
? Reflect.has(acl, property)
1410+
/* @ifndef unchainAcl */
13711411
? acl[property] instanceof Object && Reflect.has(acl[property], S_OBJECT)
1412+
/* @endif */
1413+
/* @ifdef unchainAcl */
1414+
? acl[property] && typeof acl[property] === 'object' && Reflect.has(acl[property], S_OBJECT)
1415+
/* @endif */
13721416
? acl[property][S_OBJECT]
13731417
: acl[property]
13741418
: acl[S_GLOBAL]
@@ -1395,23 +1439,38 @@ Copyright (c) 2017, 2018, 2019, 2020 Tetsuya Mori <[email protected]>. All ri
13951439
for (_property of property) {
13961440
__acl = Reflect.has(_acl, property)
13971441
? isGlobal
1442+
/* @ifndef unchainAcl */
13981443
? _acl[property] instanceof Object && Reflect.has(_acl[property], S_OBJECT)
1444+
/* @endif */
1445+
/* @ifdef unchainAcl */
1446+
? _acl[property] && typeof _acl[property] === 'object' && Reflect.has(_acl[property], S_OBJECT)
1447+
/* @endif */
13991448
? _acl[property][S_OBJECT]
14001449
: _acl[property]
14011450
: _acl[property]
14021451
: Reflect.has(_acl, context)
14031452
? context === S_DEFAULT
14041453
? isGlobal
14051454
? Reflect.has(acl, property)
1455+
/* @ifndef unchainAcl */
14061456
? acl[property] instanceof Object && Reflect.has(acl[property], S_OBJECT)
1457+
/* @endif */
1458+
/* @ifdef unchainAcl */
1459+
? acl[property] && typeof acl[property] === 'object' && Reflect.has(acl[property], S_OBJECT)
1460+
/* @endif */
14071461
? acl[property][S_OBJECT]
14081462
: acl[property]
14091463
: acl[S_GLOBAL]
14101464
: _acl[context]
14111465
: _acl[context]
14121466
: isGlobal
14131467
? Reflect.has(acl, property)
1468+
/* @ifndef unchainAcl */
14141469
? acl[property] instanceof Object && Reflect.has(acl[property], S_OBJECT)
1470+
/* @endif */
1471+
/* @ifdef unchainAcl */
1472+
? acl[property] && typeof acl[property] === 'object' && Reflect.has(acl[property], S_OBJECT)
1473+
/* @endif */
14151474
? acl[property][S_OBJECT]
14161475
: acl[property]
14171476
: acl[S_GLOBAL]

plugins/policy/__hook__.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ Copyright (c) 2017, 2018, 2019, 2020 Tetsuya Mori <[email protected]>. All ri
328328
}
329329
}
330330
}
331-
if (!name && normalizedThisArg instanceof Object) {
331+
if (!name && normalizedThisArg instanceof Object/* @ifdef unchainAcl */ || normalizedThisArg === Object.prototype/* @endif */) {
332332
[name, isStatic, isObject] = detectName(normalizedThisArg, boundParameters);
333333
}
334334
let rawProperty = _args[0];

plugins/policy/__hook__acl.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ Copyright (c) 2017, 2018, 2019, 2020 Tetsuya Mori <[email protected]>. All ri
243243
}
244244
}
245245
}
246-
if (!name && normalizedThisArg instanceof Object) {
246+
if (!name && normalizedThisArg instanceof Object/* @ifdef unchainAcl */ || normalizedThisArg === Object.prototype/* @endif */) {
247247
[name, isStatic, isObject] = detectName(normalizedThisArg, boundParameters);
248248
}
249249
let rawProperty = _args[0];

plugins/policy/hook-callback.js

+3
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@ else {
245245
'hookBenchmark',
246246
]);
247247
Policy.chainAcl(acl);
248+
/* @ifdef unchainAcl */
249+
Policy.unchainAcl(acl);
250+
/* @endif */
248251
Policy.proxyAcl(acl);
249252
Policy.resolveBareSpecifierAcl(acl);
250253
Policy.generatePrefixedModuleNames(acl);

0 commit comments

Comments
 (0)