{"record":{"id":"f56f7fa1ad45bf5c","repo":"marmelab/react-admin","slug":"invalid-resource-key-resource-f56f7f","errorCode":null,"errorMessage":"Invalid resource key: ${resource}","messagePattern":"Invalid resource key: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/ra-data-local-storage/src/index.ts","lineNumber":172,"sourceCode":"            return baseDataProvider.delete<RecordType>(resource, params);\n        },\n        deleteMany: (resource, params) => {\n            checkResource(resource);\n            updateLocalStorage(() => {\n                const indexes = params.ids.map(id =>\n                    data[resource]?.findIndex(record => record.id == id)\n                );\n                pullAt(data[resource], indexes);\n            });\n            return baseDataProvider.deleteMany(resource, params);\n        },\n    };\n};\n\nconst checkResource = resource => {\n    if (['__proto__', 'constructor', 'prototype'].includes(resource)) {\n        // protection against prototype pollution\n        throw new Error(`Invalid resource key: ${resource}`);\n    }\n};\n\nexport interface LocalStorageDataProviderParams {\n    defaultData?: any;\n    localStorageKey?: string;\n    loggingEnabled?: boolean;\n    localStorageUpdateDelay?: number;\n}\n","sourceCodeStart":154,"sourceCodeEnd":182,"githubUrl":"https://github.com/marmelab/react-admin/blob/051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0/packages/ra-data-local-storage/src/index.ts#L154-L182","documentation":"The ra-data-local-storage provider throws this error to protect against prototype pollution. Resource keys in JavaScript objects are stored as object properties, so keys like '__proto__', 'constructor', or 'prototype' could overwrite Object.prototype and corrupt every object in the app. checkResource is called by the provider's data methods before any storage access to reject such keys.","triggerScenarios":"Calling any provider method (getList, getOne, create, update, delete, etc.) with resource set to '__proto__', 'constructor', or 'prototype', e.g. dataProvider.getList('__proto__', ...) or a List resource name=\"__proto__\" propagated into provider calls.","commonSituations":"Dynamic resource names derived from URL path segments or user input that reach the data provider unvalidated; accidentally passing a variable that is undefined-adjacent or a literal meta-property; security tests probing for prototype pollution in a localStorage-backed admin.","solutions":["Audit where the resource argument comes from and stop passing '__proto__', 'constructor', or 'prototype' as resource names","Validate resource names against your app's known resource list before calling the provider","Sanitize dynamic resource identifiers extracted from URLs or user input with an allowlist"],"exampleFix":"// before\nconst resource = window.location.hash.slice(1);\ndataProvider.getList(resource, params);\n// after\nconst resource = window.location.hash.slice(1);\nconst allowed = ['posts', 'comments', 'users'];\nif (!allowed.includes(resource)) throw new Error(`Unknown resource: ${resource}`);\ndataProvider.getList(resource, params);","handlingStrategy":"validation","validationCode":"const FORBIDDEN = ['__proto__', 'constructor', 'prototype'];\nconst assertSafeResource = resource => {\n    if (typeof resource !== 'string' || FORBIDDEN.includes(resource)) {\n        throw new Error(`Invalid resource key: ${resource}`);\n    }\n};\nassertSafeResource(resource);\ndataProvider.getList(resource, params);","typeGuard":"const isSafeResource = (r: unknown): r is string =>\n    typeof r === 'string' && !['__proto__', 'constructor', 'prototype'].includes(r);","tryCatchPattern":"try {\n    await dataProvider.getList(resource, params);\n} catch (e) {\n    if (e instanceof Error && e.message.startsWith('Invalid resource key')) {\n        console.error('Blocked unsafe resource key:', resource);\n        return;\n    }\n    throw e;\n}","preventionTips":["Validate dynamic resource names against an allowlist before provider calls","Never derive resource names directly from user/URL input without sanitization","Add a unit test asserting provider calls with '__proto__' are rejected","Keep resource names as static string constants where possible"],"tags":["security","prototype-pollution","validation","localstorage"],"backgroundTag":"prototype-pollution","analyzedSha":"051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0","analyzedAt":"2026-08-30T02:28:14.926Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}