-
-
Notifications
You must be signed in to change notification settings - Fork 269
fix: improved validation for types sign message in package eth-json-rpc-middleware #7732
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
7e81aac
e81ac09
3a4dd23
ed61d9c
d9407e6
1fd6d8a
8f1791f
0a6ec9b
1dbb1d9
a644725
b34b2a8
9611103
869ea4a
3908b7c
93df923
abc11cd
9355180
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ import type { Struct, StructError } from '@metamask/superstruct'; | |
| import { validate } from '@metamask/superstruct'; | ||
| import type { Hex } from '@metamask/utils'; | ||
|
|
||
| import { parseTypedMessage } from './normalize'; | ||
| import type { WalletMiddlewareContext } from '../wallet'; | ||
|
|
||
| /** | ||
|
|
@@ -96,3 +97,93 @@ function formatValidationError(error: StructError, message: string): string { | |
| ) | ||
| .join('\n')}`; | ||
| } | ||
|
|
||
| export const DANGEROUS_PROTOTYPE_PROPERTIES = [ | ||
| '__proto__', | ||
| 'constructor', | ||
| 'prototype', | ||
| '__defineGetter__', | ||
| '__defineSetter__', | ||
| '__lookupGetter__', | ||
| '__lookupSetter__', | ||
| ] as const; | ||
|
|
||
| /** | ||
| * Checks if a property name is dangerous for prototype pollution. | ||
| * | ||
| * @param key - The property name to check | ||
| * @returns True if the property name is dangerous | ||
| */ | ||
| function isDangerousProperty(key: string): boolean { | ||
| return (DANGEROUS_PROTOTYPE_PROPERTIES as readonly string[]).includes(key); | ||
| } | ||
|
|
||
| /** | ||
| * Recursively checks an object for dangerous prototype pollution properties. | ||
| * | ||
| * @param obj - The object to check | ||
| * @throws rpcErrors.invalidInput() if a dangerous property is found | ||
| */ | ||
| function checkObjectForPrototypePollution(obj: unknown): void { | ||
| if (obj === null || obj === undefined) { | ||
| return; | ||
| } | ||
|
|
||
| if (Array.isArray(obj)) { | ||
| for (const item of obj) { | ||
| checkObjectForPrototypePollution(item); | ||
| } | ||
| return; | ||
| } | ||
|
|
||
| if (typeof obj === 'object') { | ||
| for (const key of Object.getOwnPropertyNames( | ||
| obj as Record<string, unknown>, | ||
| )) { | ||
| if (isDangerousProperty(key)) { | ||
| throw rpcErrors.invalidInput(); | ||
| } | ||
| checkObjectForPrototypePollution((obj as Record<string, unknown>)[key]); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Validates V1 typed data (array format) for prototype pollution attacks. | ||
| * V1 format: [{ type: 'string', name: 'fieldName', value: 'data' }, ...] | ||
| * | ||
| * @param data - The V1 typed data array to validate | ||
| * @throws rpcErrors.invalidInput() if prototype pollution is detected | ||
| */ | ||
| export function validateTypedDataV1ForPrototypePollution( | ||
| data: Record<string, unknown>[], | ||
| ): void { | ||
| if (!data || !Array.isArray(data)) { | ||
| return; | ||
| } | ||
|
|
||
| for (const item of data) { | ||
| if (item && typeof item === 'object') { | ||
| // Only check the 'value' field (the message data) for dangerous properties | ||
| if (item.value !== null && typeof item.value === 'object') { | ||
| checkObjectForPrototypePollution(item.value); | ||
| } | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. V1 validation misses item-level dangerous propertiesMedium Severity The |
||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Validates V3/V4 typed data (EIP-712 format) for prototype pollution attacks. | ||
| * Only checks the message field for dangerous properties. | ||
| * | ||
| * @param data - The stringified typed data to validate | ||
| * @throws rpcErrors.invalidInput() if prototype pollution is detected | ||
| */ | ||
| export function validateTypedDataForPrototypePollution(data: string): void { | ||
| const { message } = parseTypedMessage(data); | ||
|
|
||
| // Check message recursively for dangerous properties | ||
| if (message !== undefined) { | ||
| checkObjectForPrototypePollution(message); | ||
| } | ||
| } | ||
jpuri marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Uh oh!
There was an error while loading. Please reload this page.