-
-
Notifications
You must be signed in to change notification settings - Fork 239
Fix prototype-polluting assignments #4041
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
Changes from all commits
cd8e488
08880ac
b1767ca
d85f0f5
d978fad
4d59ca1
a2a561a
a145237
64f0b6d
4d634ea
3a34215
1d09bee
03333af
bad6ed4
9e06ca4
f6c3c47
ca5d789
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 |
---|---|---|
@@ -1,4 +1,32 @@ | ||
export * from './constants'; | ||
export * from './util'; | ||
export type { NonEmptyArray } from './util'; | ||
export { | ||
BNToHex, | ||
convertHexToDecimal, | ||
fetchWithErrorHandling, | ||
fractionBN, | ||
fromHex, | ||
getBuyURL, | ||
gweiDecToWEIBN, | ||
handleFetch, | ||
hexToBN, | ||
hexToText, | ||
isNonEmptyArray, | ||
isPlainObject, | ||
isSafeChainId, | ||
isSafeDynamicKey, | ||
isSmartContractCode, | ||
isValidJson, | ||
isValidHexAddress, | ||
normalizeEnsName, | ||
query, | ||
safelyExecute, | ||
safelyExecuteWithTimeout, | ||
successfulFetch, | ||
timeoutFetch, | ||
toChecksumHexAddress, | ||
toHex, | ||
weiHexToGweiDec, | ||
} from './util'; | ||
export * from './types'; | ||
export * from './siwe'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,26 @@ import { MAX_SAFE_CHAIN_ID } from './constants'; | |
|
||
const TIMEOUT_ERROR = new Error('timeout'); | ||
|
||
export const PROTOTYPE_POLLUTION_BLOCKLIST = [ | ||
'__proto__', | ||
'constructor', | ||
'prototype', | ||
] as const; | ||
|
||
/** | ||
* Checks whether a dynamic property key could be used in | ||
* a [prototype pollution attack](https://portswigger.net/web-security/prototype-pollution). | ||
* | ||
* @param key - The dynamic key to validate. | ||
* @returns Whether the given dynamic key is safe to use. | ||
*/ | ||
export function isSafeDynamicKey(key: string): boolean { | ||
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. Not intending to block this PR, but this seems like it could be useful for 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. Not opposed to moving it down the line if it fits better there! |
||
return ( | ||
typeof key === 'string' && | ||
!PROTOTYPE_POLLUTION_BLOCKLIST.some((blockedKey) => key === blockedKey) | ||
); | ||
} | ||
|
||
/** | ||
* Checks whether the given number primitive chain ID is safe. | ||
* Because some cryptographic libraries we use expect the chain ID to be a | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ import type { ChainId } from '@metamask/controller-utils'; | |
import { | ||
normalizeEnsName, | ||
isValidHexAddress, | ||
isSafeDynamicKey, | ||
toChecksumHexAddress, | ||
CHAIN_ID_TO_ETHERS_NETWORK_NAME_MAP, | ||
convertHexToDecimal, | ||
|
@@ -194,6 +195,7 @@ export class EnsController extends BaseController< | |
delete(chainId: Hex, ensName: string): boolean { | ||
const normalizedEnsName = normalizeEnsName(ensName); | ||
if ( | ||
!isSafeDynamicKey(chainId) || | ||
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. Should we add a test for this? Seems important to check. 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. The type as well as the following code assumes that Maybe adding a runtime-check that the A function like 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. It's true that However, it seems worth it to implement more generalized blocklisting logic for this vulnerability (https://portswigger.net/web-security/prototype-pollution/preventing#sanitizing-property-keys), which will also directly placate the CodeQL scanner. 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. Sure, we could definitely make more improvements that would ensure we can protect against this vulnerability more generally. That seems unrelated to my comment, though. Should we add tests which attempt to call 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. I added tests for all three files here: a145237. Coverage is up to 100 for the three modules. I didn't test every string in the blocklist, but it seems like verifying that the validation works should be enough? 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. Testing that it essentially just gets called is fine. Do we need tests for the function itself, though? 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. Ah of course I'll add that right now. |
||
!normalizedEnsName || | ||
!this.state.ensEntries[chainId] || | ||
!this.state.ensEntries[chainId][normalizedEnsName] | ||
|
Uh oh!
There was an error while loading. Please reload this page.