Skip to content

Commit 853beff

Browse files
authored
Merge pull request #10758 from marmelab/alert-autofix-52
Fix potential prototype-polluting assignment in `ra-data-local-storage`
2 parents 5a5d410 + 31dba2c commit 853beff

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

packages/ra-data-local-forage/src/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ export default (params?: LocalForageDataProviderParams): DataProvider => {
166166
resource: string,
167167
params: UpdateParams<any>
168168
) => {
169+
checkResource(resource);
169170
await initialize();
170171
if (!data) {
171172
throw new Error('The dataProvider is not initialized.');
@@ -185,6 +186,7 @@ export default (params?: LocalForageDataProviderParams): DataProvider => {
185186
return baseDataProvider.update<RecordType>(resource, params);
186187
},
187188
updateMany: async (resource: string, params: UpdateManyParams<any>) => {
189+
checkResource(resource);
188190
await initialize();
189191
if (!baseDataProvider) {
190192
throw new Error('The dataProvider is not initialized.');
@@ -209,6 +211,7 @@ export default (params?: LocalForageDataProviderParams): DataProvider => {
209211
resource: string,
210212
params: CreateParams<any>
211213
) => {
214+
checkResource(resource);
212215
await initialize();
213216
if (!baseDataProvider) {
214217
throw new Error('The dataProvider is not initialized.');
@@ -232,6 +235,7 @@ export default (params?: LocalForageDataProviderParams): DataProvider => {
232235
resource: string,
233236
params: DeleteParams<RecordType>
234237
) => {
238+
checkResource(resource);
235239
await initialize();
236240
if (!baseDataProvider) {
237241
throw new Error('The dataProvider is not initialized.');
@@ -247,6 +251,7 @@ export default (params?: LocalForageDataProviderParams): DataProvider => {
247251
return baseDataProvider.delete<RecordType>(resource, params);
248252
},
249253
deleteMany: async (resource: string, params: DeleteManyParams<any>) => {
254+
checkResource(resource);
250255
await initialize();
251256
if (!baseDataProvider) {
252257
throw new Error('The dataProvider is not initialized.');
@@ -269,6 +274,13 @@ export default (params?: LocalForageDataProviderParams): DataProvider => {
269274
};
270275
};
271276

277+
const checkResource = resource => {
278+
if (['__proto__', 'constructor', 'prototype'].includes(resource)) {
279+
// protection against prototype pollution
280+
throw new Error(`Invalid resource key: ${resource}`);
281+
}
282+
};
283+
272284
export interface LocalForageDataProviderParams {
273285
defaultData?: any;
274286
prefixLocalForageKey?: string;

packages/ra-data-local-storage/src/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ export default (params?: LocalStorageDataProviderParams): DataProvider => {
9898

9999
// update methods need to persist changes in localStorage
100100
update: <RecordType extends RaRecord = any>(resource, params) => {
101+
checkResource(resource);
101102
updateLocalStorage(() => {
102103
const index = data[resource]?.findIndex(
103104
record => record.id == params.id
@@ -110,6 +111,7 @@ export default (params?: LocalStorageDataProviderParams): DataProvider => {
110111
return baseDataProvider.update<RecordType>(resource, params);
111112
},
112113
updateMany: (resource, params) => {
114+
checkResource(resource);
113115
updateLocalStorage(() => {
114116
params.ids.forEach(id => {
115117
const index = data[resource]?.findIndex(
@@ -127,6 +129,7 @@ export default (params?: LocalStorageDataProviderParams): DataProvider => {
127129
resource,
128130
params
129131
) => {
132+
checkResource(resource);
130133
// we need to call the fakerest provider first to get the generated id
131134
return baseDataProvider
132135
.create<RecordType>(resource, params)
@@ -141,6 +144,7 @@ export default (params?: LocalStorageDataProviderParams): DataProvider => {
141144
});
142145
},
143146
delete: <RecordType extends RaRecord = any>(resource, params) => {
147+
checkResource(resource);
144148
updateLocalStorage(() => {
145149
const index = data[resource]?.findIndex(
146150
record => record.id == params.id
@@ -150,6 +154,7 @@ export default (params?: LocalStorageDataProviderParams): DataProvider => {
150154
return baseDataProvider.delete<RecordType>(resource, params);
151155
},
152156
deleteMany: (resource, params) => {
157+
checkResource(resource);
153158
updateLocalStorage(() => {
154159
const indexes = params.ids.map(id =>
155160
data[resource]?.findIndex(record => record.id == id)
@@ -161,6 +166,13 @@ export default (params?: LocalStorageDataProviderParams): DataProvider => {
161166
};
162167
};
163168

169+
const checkResource = resource => {
170+
if (['__proto__', 'constructor', 'prototype'].includes(resource)) {
171+
// protection against prototype pollution
172+
throw new Error(`Invalid resource key: ${resource}`);
173+
}
174+
};
175+
164176
export interface LocalStorageDataProviderParams {
165177
defaultData?: any;
166178
localStorageKey?: string;

0 commit comments

Comments
 (0)