1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Sanitising string on signature request pages (#17571)

This commit is contained in:
Jyoti Puri 2023-02-09 04:35:52 +05:30 committed by GitHub
parent 7e97ff2be4
commit 61a7850afc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 105 additions and 11 deletions

View File

@ -5,7 +5,7 @@ import { ObjectInspector } from 'react-inspector';
import LedgerInstructionField from '../ledger-instruction-field';
import { MESSAGE_TYPE } from '../../../../shared/constants/app';
import { getURLHostName } from '../../../helpers/utils/util';
import { getURLHostName, sanitizeString } from '../../../helpers/utils/util';
import { stripHexPrefix } from '../../../../shared/modules/hexstring-utils';
import Button from '../../ui/button';
import SiteOrigin from '../../ui/site-origin';
@ -177,8 +177,12 @@ export default class SignatureRequestOriginal extends Component {
className="request-signature__row"
key={`request-signature-row-${index}`}
>
<div className="request-signature__row-title">{`${name}:`}</div>
<div className="request-signature__row-value">{value}</div>
<div className="request-signature__row-title">
{sanitizeString(`${name}:`)}
</div>
<div className="request-signature__row-value">
{sanitizeString(value)}
</div>
</div>
);
})}

View File

@ -52,14 +52,17 @@ const props = {
},
};
const render = () => {
const render = (txData = props.txData) => {
const store = configureStore({
metamask: {
...mockState.metamask,
},
});
return renderWithProvider(<SignatureRequestOriginal {...props} />, store);
return renderWithProvider(
<SignatureRequestOriginal {...props} txData={txData} />,
store,
);
};
describe('SignatureRequestOriginal', () => {
@ -92,4 +95,24 @@ describe('SignatureRequestOriginal', () => {
fireEvent.click(signButton);
expect(screen.getByText('Your funds may be at risk')).toBeInTheDocument();
});
it('should escape RTL character in label or value', () => {
const txData = {
msgParams: {
from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
data: [
{
type: 'string',
name: 'Message \u202E test',
value: 'Hi, \u202E Alice!',
},
],
origin: 'https://happydapp.website/governance?futarchy=true',
},
type: MESSAGE_TYPE.ETH_SIGN_TYPED_DATA,
};
const { getByText } = render(txData);
expect(getByText('Message \\u202E test:')).toBeInTheDocument();
expect(getByText('Hi, \\u202E Alice!')).toBeInTheDocument();
});
});

View File

@ -19,6 +19,7 @@ import {
TypographyVariant,
TextColor,
} from '../../../../helpers/constants/design-system';
import { sanitizeString } from '../../../../helpers/utils/util';
function SignatureRequestData({ data }) {
const identities = useSelector(getMemoizedMetaMaskIdentities);
@ -42,7 +43,7 @@ function SignatureRequestData({ data }) {
typeof value === 'object' ? FONT_WEIGHT.BOLD : FONT_WEIGHT.NORMAL
}
>
{label.charAt(0).toUpperCase() + label.slice(1)}:{' '}
{sanitizeString(label.charAt(0).toUpperCase() + label.slice(1))}:{' '}
</Typography>
{typeof value === 'object' && value !== null ? (
<SignatureRequestData data={value} />
@ -68,7 +69,7 @@ function SignatureRequestData({ data }) {
/>
</Typography>
) : (
`${value}`
sanitizeString(`${value}`)
)}
</Typography>
)}

View File

@ -468,5 +468,55 @@ describe('Signature Request Data', () => {
expect(getByText('0xB0B...0000')).toBeInTheDocument();
});
it('should escape RTL character in label or value', () => {
const messageDataWithRTLCharacters = {
...messageData,
message: {
...messageData.message,
contents: 'Hello, \u202E Bob!',
from: {
'name\u202Ename': 'Cow \u202E Cow',
'wallets\u202Ewallets': [
'0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
'0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF',
'0x06195827297c7A80a443b6894d3BDB8824b43896',
],
},
to: [
{
'name\u202Ename': 'Bob \u202E Bob',
'wallets\u202Ewallets': [
'0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
'0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57',
'0xB0B0b0b0b0b0B000000000000000000000000000',
],
},
],
},
types: {
...messageData.message.types,
Person: [
{ name: 'name\u202Ename', type: 'string' },
{ name: 'wallets\u202Ewallets', type: 'address[]' },
],
},
};
const msgParams = {
data: JSON.parse(JSON.stringify(messageDataWithRTLCharacters)),
version: 'V4',
origin: 'test',
};
const { getByText, getAllByText } = renderWithProvider(
<SignatureRequestData data={msgParams} />,
store,
);
expect(getByText('Hello, \\u202E Bob!')).toBeInTheDocument();
expect(getByText('Cow \\u202E Cow')).toBeInTheDocument();
expect(getByText('Bob \\u202E Bob')).toBeInTheDocument();
expect(getAllByText('Name\\u202Ename:')).toHaveLength(2);
expect(getAllByText('Wallets\\u202Ewallets:')).toHaveLength(2);
});
});
});

View File

@ -5,10 +5,8 @@ import * as ethUtil from 'ethereumjs-util';
import { DateTime } from 'luxon';
import { getFormattedIpfsUrl } from '@metamask/assets-controllers';
import slip44 from '@metamask/slip44';
import * as lodash from 'lodash';
import bowser from 'bowser';
///: BEGIN:ONLY_INCLUDE_IN(flask)
import { isEqual } from 'lodash';
///: END:ONLY_INCLUDE_IN
import { CHAIN_IDS } from '../../../shared/constants/network';
import {
toChecksumHexAddress,
@ -540,9 +538,27 @@ export function isNullish(value) {
export function getSnapDerivationPathName(path, curve) {
const pathMetadata = SNAPS_DERIVATION_PATHS.find(
(derivationPath) =>
derivationPath.curve === curve && isEqual(derivationPath.path, path),
derivationPath.curve === curve &&
lodash.isEqual(derivationPath.path, path),
);
return pathMetadata?.name ?? null;
}
///: END:ONLY_INCLUDE_IN
/**
* The method escape RTL character in string
*
* @param {any} value
* @returns {(string|*)} escaped string or original param value
*/
export const sanitizeString = (value) => {
if (!value) {
return value;
}
if (!lodash.isString(value)) {
return value;
}
const regex = /\u202E/giu;
return value.replaceAll(regex, '\\u202E');
};