@@ -128,6 +128,54 @@ describe("WasmScopeAbi", () => {
128128 expect ( rootScope . filters . status ) . toBeUndefined ( ) ;
129129 } ) ;
130130
131+ it ( "rejects prototype-polluting write paths" , ( ) => {
132+ const scope = abi . createScope ( rootScope , { name : "todoList:main" } ) ;
133+ const value = guest . writeJson ( "polluted" ) ;
134+ const poisoned = [
135+ "__proto__.wasmPolluted" ,
136+ "safe.constructor.prototype.wasmPolluted" ,
137+ "safe.prototype.wasmPolluted" ,
138+ ] ;
139+
140+ for ( const pathValue of poisoned ) {
141+ const path = guest . write ( pathValue ) ;
142+
143+ expect (
144+ imports . scope_set (
145+ scope . handle ,
146+ path . ptr ,
147+ path . len ,
148+ value . ptr ,
149+ value . len ,
150+ ) ,
151+ ) . toBe ( 0 ) ;
152+ }
153+
154+ expect ( rootScope . safe ) . toBeUndefined ( ) ;
155+ expect ( ( { } as Record < string , unknown > ) . wasmPolluted ) . toBeUndefined ( ) ;
156+ } ) ;
157+
158+ it ( "rejects prototype-polluting read and delete paths" , ( ) => {
159+ const scope = abi . createScope ( rootScope , { name : "todoList:main" } ) ;
160+ const path = guest . write ( "__proto__.wasmPolluted" ) ;
161+
162+ ( Object . prototype as Record < string , unknown > ) . wasmPolluted = "inherited" ;
163+
164+ try {
165+ const result = imports . scope_get ( scope . handle , path . ptr , path . len ) ;
166+
167+ expect (
168+ guest . readJson ( imports . buffer_ptr ( result ) , imports . buffer_len ( result ) ) ,
169+ ) . toBeNull ( ) ;
170+ expect ( imports . scope_delete ( scope . handle , path . ptr , path . len ) ) . toBe ( 0 ) ;
171+ expect ( ( { } as Record < string , unknown > ) . wasmPolluted ) . toBe ( "inherited" ) ;
172+
173+ imports . buffer_free ( result ) ;
174+ } finally {
175+ delete ( Object . prototype as Record < string , unknown > ) . wasmPolluted ;
176+ }
177+ } ) ;
178+
131179 it ( "runs bridge sync callbacks asynchronously" , async ( ) => {
132180 const scope = abi . createScope ( rootScope , { name : "todoList:main" } ) ;
133181 const name = guest . write ( "todoList:main" ) ;
0 commit comments