File tree 4 files changed +82
-2
lines changed
4 files changed +82
-2
lines changed Original file line number Diff line number Diff line change @@ -134,3 +134,40 @@ test("key and value getters", () => {
134
134
rec . valueSchema . parse ( 1234 ) ;
135
135
rec . element . parse ( 1234 ) ;
136
136
} ) ;
137
+
138
+ test ( "is not vulnerable to prototype pollution" , async ( ) => {
139
+ const rec = z . record (
140
+ z . object ( {
141
+ a : z . string ( ) ,
142
+ } )
143
+ ) ;
144
+
145
+ const data = JSON . parse ( `
146
+ {
147
+ "__proto__": {
148
+ "a": "evil"
149
+ },
150
+ "b": {
151
+ "a": "good"
152
+ }
153
+ }
154
+ ` ) ;
155
+
156
+ const obj1 = rec . parse ( data ) ;
157
+ expect ( obj1 . a ) . toBeUndefined ( ) ;
158
+
159
+ const obj2 = rec . safeParse ( data ) ;
160
+ expect ( obj2 . success ) . toBe ( true ) ;
161
+ if ( obj2 . success ) {
162
+ expect ( obj2 . data . a ) . toBeUndefined ( ) ;
163
+ }
164
+
165
+ const obj3 = await rec . parseAsync ( data ) ;
166
+ expect ( obj3 . a ) . toBeUndefined ( ) ;
167
+
168
+ const obj4 = await rec . safeParseAsync ( data ) ;
169
+ expect ( obj4 . success ) . toBe ( true ) ;
170
+ if ( obj4 . success ) {
171
+ expect ( obj4 . data . a ) . toBeUndefined ( ) ;
172
+ }
173
+ } ) ;
Original file line number Diff line number Diff line change @@ -136,7 +136,10 @@ export class ParseStatus {
136
136
if ( key . status === "dirty" ) status . dirty ( ) ;
137
137
if ( value . status === "dirty" ) status . dirty ( ) ;
138
138
139
- if ( typeof value . value !== "undefined" || pair . alwaysSet ) {
139
+ if (
140
+ key . value !== "__proto__" &&
141
+ ( typeof value . value !== "undefined" || pair . alwaysSet )
142
+ ) {
140
143
finalObject [ key . value ] = value . value ;
141
144
}
142
145
}
Original file line number Diff line number Diff line change @@ -133,3 +133,40 @@ test("key and value getters", () => {
133
133
rec . valueSchema . parse ( 1234 ) ;
134
134
rec . element . parse ( 1234 ) ;
135
135
} ) ;
136
+
137
+ test ( "is not vulnerable to prototype pollution" , async ( ) => {
138
+ const rec = z . record (
139
+ z . object ( {
140
+ a : z . string ( ) ,
141
+ } )
142
+ ) ;
143
+
144
+ const data = JSON . parse ( `
145
+ {
146
+ "__proto__": {
147
+ "a": "evil"
148
+ },
149
+ "b": {
150
+ "a": "good"
151
+ }
152
+ }
153
+ ` ) ;
154
+
155
+ const obj1 = rec . parse ( data ) ;
156
+ expect ( obj1 . a ) . toBeUndefined ( ) ;
157
+
158
+ const obj2 = rec . safeParse ( data ) ;
159
+ expect ( obj2 . success ) . toBe ( true ) ;
160
+ if ( obj2 . success ) {
161
+ expect ( obj2 . data . a ) . toBeUndefined ( ) ;
162
+ }
163
+
164
+ const obj3 = await rec . parseAsync ( data ) ;
165
+ expect ( obj3 . a ) . toBeUndefined ( ) ;
166
+
167
+ const obj4 = await rec . safeParseAsync ( data ) ;
168
+ expect ( obj4 . success ) . toBe ( true ) ;
169
+ if ( obj4 . success ) {
170
+ expect ( obj4 . data . a ) . toBeUndefined ( ) ;
171
+ }
172
+ } ) ;
Original file line number Diff line number Diff line change @@ -136,7 +136,10 @@ export class ParseStatus {
136
136
if ( key . status === "dirty" ) status . dirty ( ) ;
137
137
if ( value . status === "dirty" ) status . dirty ( ) ;
138
138
139
- if ( typeof value . value !== "undefined" || pair . alwaysSet ) {
139
+ if (
140
+ key . value !== "__proto__" &&
141
+ ( typeof value . value !== "undefined" || pair . alwaysSet )
142
+ ) {
140
143
finalObject [ key . value ] = value . value ;
141
144
}
142
145
}
You can’t perform that action at this time.
0 commit comments