@@ -42,7 +42,6 @@ function makeHelpers() {
42
42
function addProp ( o , name , path ) {
43
43
const prop = Object . getOwnPropertyDescriptor ( o , name ) ;
44
44
if ( typeof name === 'symbol' ) name = '!' + name . toString ( ) ;
45
- Object . setPrototypeOf ( prop , null ) ;
46
45
addObj ( prop . get , `${ path } >${ name } ` ) ;
47
46
addObj ( prop . set , `${ path } <${ name } ` ) ;
48
47
addObj ( prop . value , `${ path } .${ name } ` ) ;
@@ -622,7 +621,7 @@ describe('VM', () => {
622
621
if (o && o.constructor !== Function) throw new Error('Shouldnt be there.');
623
622
` ) , '#3' ) ;
624
623
625
- assert . doesNotThrow ( ( ) => vm2 . run ( `
624
+ assert . throws ( ( ) => vm2 . run ( `
626
625
let method = () => {};
627
626
let proxy = new Proxy(method, {
628
627
apply: (target, context, args) => {
@@ -631,16 +630,16 @@ describe('VM', () => {
631
630
}
632
631
});
633
632
proxy
634
- ` ) ( 'asdf' ) , '#4' ) ;
633
+ ` ) ( 'asdf' ) , / P r o x y i s n o t a c o n s t r u c t o r / , '#4' ) ;
635
634
636
- assert . doesNotThrow ( ( ) => vm2 . run ( `
635
+ assert . throws ( ( ) => vm2 . run ( `
637
636
let proxy2 = new Proxy(function() {}, {
638
637
apply: (target, context, args) => {
639
638
if (args.constructor.constructor !== Function) throw new Error('Shouldnt be there.');
640
639
}
641
640
});
642
641
proxy2
643
- ` ) ( 'asdf' ) , '#5' ) ;
642
+ ` ) ( 'asdf' ) , / P r o x y i s n o t a c o n s t r u c t o r / , '#5' ) ;
644
643
645
644
assert . strictEqual ( vm2 . run ( `
646
645
global.DEBUG = true;
@@ -674,7 +673,7 @@ describe('VM', () => {
674
673
} catch ({constructor: c}) {
675
674
c.constructor('return process')();
676
675
}
677
- ` ) , / M a x i m u m c a l l s t a c k s i z e e x c e e d e d / , '#9' ) ;
676
+ ` ) , / P r o x y i s n o t a c o n s t r u c t o r / , '#9' ) ;
678
677
} ) ;
679
678
680
679
it ( 'internal state attack' , ( ) => {
@@ -729,21 +728,15 @@ describe('VM', () => {
729
728
}
730
729
} ) ;
731
730
732
- try {
733
- vm2 . run ( `
734
- func(() => {
735
- throw new Proxy({}, {
736
- getPrototypeOf: () => {
737
- throw x => x.constructor.constructor("return process;")();
738
- }
739
- })
740
- });
741
- ` ) ;
742
- } catch ( ex ) {
743
- assert . throws ( ( ) => {
744
- ex ( ( ) => { } ) ;
745
- } , / p r o c e s s i s n o t d e f i n e d / ) ;
746
- }
731
+ assert . throws ( ( ) => vm2 . run ( `
732
+ func(() => {
733
+ throw new Proxy({}, {
734
+ getPrototypeOf: () => {
735
+ throw x => x.constructor.constructor("return process;")();
736
+ }
737
+ })
738
+ });
739
+ ` ) , / P r o x y i s n o t a c o n s t r u c t o r / ) ;
747
740
} ) ;
748
741
749
742
it ( '__defineGetter__ / __defineSetter__ attack' , ( ) => {
@@ -815,40 +808,11 @@ describe('VM', () => {
815
808
return () => x => x.constructor("return process")();
816
809
}
817
810
})))(()=>{}).mainModule.require("child_process").execSync("id").toString()
818
- ` ) , / p r o c e s s i s n o t d e f i n e d / , '#2' ) ;
811
+ ` ) , / P r o x y i s n o t a c o n s t r u c t o r / , '#2' ) ;
819
812
820
813
vm2 = new VM ( ) ;
821
814
822
815
assert . throws ( ( ) => vm2 . run ( `
823
- var process;
824
- try {
825
- Object.defineProperty(Buffer.from(""), "y", {
826
- writable: true,
827
- value: new Proxy({}, {
828
- getPrototypeOf(target) {
829
- delete this.getPrototypeOf;
830
-
831
- Object.defineProperty(Object.prototype, "get", {
832
- get() {
833
- delete Object.prototype.get;
834
- Function.prototype.__proto__ = null;
835
- throw f=>f.constructor("return process")();
836
- }
837
- });
838
-
839
- return Object.getPrototypeOf(target);
840
- }
841
- })
842
- });
843
- } catch(e) {
844
- process = e(() => {});
845
- }
846
- process.mainModule.require("child_process").execSync("whoami").toString()
847
- ` ) , / C a n n o t r e a d p r o p e r t .* m a i n M o d u l e / , '#3' ) ;
848
-
849
- vm2 = new VM ( ) ;
850
-
851
- assert . doesNotThrow ( ( ) => vm2 . run ( `
852
816
Object.defineProperty(Buffer.from(""), "", {
853
817
value: new Proxy({}, {
854
818
getPrototypeOf(target) {
@@ -861,7 +825,7 @@ describe('VM', () => {
861
825
}
862
826
})
863
827
});
864
- ` ) , '#4' ) ;
828
+ ` ) , / P r o x y i s n o t a c o n s t r u c t o r / , '#4' ) ;
865
829
866
830
vm2 = new VM ( ) ;
867
831
@@ -988,7 +952,7 @@ describe('VM', () => {
988
952
}
989
953
}
990
954
}))}).mainModule.require("child_process").execSync("id").toString()
991
- ` ) , / p r o c e s s i s n o t d e f i n e d / , '#1' ) ;
955
+ ` ) , / P r o x y i s n o t a c o n s t r u c t o r / , '#1' ) ;
992
956
} ) ;
993
957
994
958
it ( 'throw while accessing propertyDescriptor properties' , ( ) => {
@@ -1045,17 +1009,13 @@ describe('VM', () => {
1045
1009
1046
1010
assert . throws ( ( ) => vm2 . run ( `
1047
1011
(function(){
1048
- try{
1049
- Buffer.from(new Proxy({}, {
1050
- getOwnPropertyDescriptor(){
1051
- throw f=>f.constructor("return process")();
1052
- }
1053
- }));
1054
- }catch(e){
1055
- return e(()=>{}).mainModule.require("child_process").execSync("whoami").toString();
1056
- }
1012
+ Buffer.from(new Proxy({}, {
1013
+ getOwnPropertyDescriptor(){
1014
+ throw f=>f.constructor("return process")();
1015
+ }
1016
+ }));
1057
1017
})()
1058
- ` ) , / p r o c e s s i s n o t d e f i n e d / ) ;
1018
+ ` ) , / P r o x y i s n o t a c o n s t r u c t o r / ) ;
1059
1019
} ) ;
1060
1020
1061
1021
if ( NODE_VERSION >= 10 ) {
@@ -1160,6 +1120,47 @@ describe('VM', () => {
1160
1120
` ) , / p r o c e s s i s n o t d e f i n e d / ) ;
1161
1121
} ) ;
1162
1122
1123
+ it ( 'allow regular async functions' , async ( ) => {
1124
+ const vm2 = new VM ( ) ;
1125
+ const promise = vm2 . run ( `(async () => 42)()` ) ;
1126
+ assert . strictEqual ( await promise , 42 ) ;
1127
+ } ) ;
1128
+
1129
+ it ( 'allow regular promises' , async ( ) => {
1130
+ const vm2 = new VM ( ) ;
1131
+ const promise = vm2 . run ( `new Promise((resolve) => resolve(42))` ) ;
1132
+ assert . strictEqual ( await promise , 42 ) ;
1133
+ } ) ;
1134
+
1135
+ it ( '[Symbol.species] attack' , async ( ) => {
1136
+ const vm2 = new VM ( ) ;
1137
+ const promise = vm2 . run ( `
1138
+ async function fn() {
1139
+ throw new Error('random error');
1140
+ }
1141
+ const promise = fn();
1142
+ promise.constructor = {
1143
+ [Symbol.species]: class WrappedPromise {
1144
+ constructor(executor) {
1145
+ executor(() => 43, () => 44);
1146
+ }
1147
+ }
1148
+ };
1149
+ promise.then();
1150
+ ` ) ;
1151
+ assert . rejects ( ( ) => promise , / r a n d o m e r r o r / ) ;
1152
+ } ) ;
1153
+
1154
+ it ( 'constructor arbitrary code attack' , async ( ) => {
1155
+ const vm2 = new VM ( ) ;
1156
+ assert . throws ( ( ) => vm2 . run ( `
1157
+ const g = ({}).__lookupGetter__;
1158
+ const a = Buffer.apply;
1159
+ const p = a.apply(g, [Buffer, ['__proto__']]);
1160
+ p.call(a).constructor('return process')();
1161
+ ` ) , / c o n s t r u c t o r i s n o t a f u n c t i o n / ) ;
1162
+ } ) ;
1163
+
1163
1164
after ( ( ) => {
1164
1165
vm = null ;
1165
1166
} ) ;
0 commit comments