Merge pull request #1 from unicornultrafoundation/fix/prevent_xss_injection

Purify DOM to prevent XSS injection
This commit is contained in:
lewtran
2023-09-06 01:27:05 +07:00
committed by GitHub
8 changed files with 35 additions and 14 deletions
+2 -1
View File
@@ -79,7 +79,8 @@
"swagger-ui-react": "^5.1.0",
"use-font-face-observer": "^1.2.1",
"viem": "^1.1.8",
"wagmi": "^1.3.3"
"wagmi": "^1.3.3",
"xss": "^1.0.14"
},
"devDependencies": {
"@playwright/experimental-ct-react": "1.35.1",
+6 -4
View File
@@ -1,5 +1,6 @@
import { Flex, Grid, Icon, Image, Box, Text, Skeleton, useColorMode } from '@chakra-ui/react';
import React from 'react';
import xss from 'xss';
import type { SearchResultItem } from 'types/api/search';
@@ -64,7 +65,7 @@ const SearchResultListItem = ({ data, searchTerm, isLoading }: Props) => {
>
<Skeleton
isLoaded={ !isLoading }
dangerouslySetInnerHTML={{ __html: highlightText(name, searchTerm) }}
dangerouslySetInnerHTML={{ __html: xss(highlightText(name, searchTerm)) }}
whiteSpace="nowrap"
overflow="hidden"
textOverflow="ellipsis"
@@ -100,14 +101,14 @@ const SearchResultListItem = ({ data, searchTerm, isLoading }: Props) => {
isLoading={ isLoading }
onClick={ handleLinkClick }
>
<span dangerouslySetInnerHTML={{ __html: highlightText(data.name, searchTerm) }}/>
<span dangerouslySetInnerHTML={{ __html: xss(highlightText(data.name, searchTerm)) }}/>
</LinkInternal>
</Flex>
);
}
case 'app': {
const title = <span dangerouslySetInnerHTML={{ __html: highlightText(data.app.title, searchTerm) }}/>;
const title = <span dangerouslySetInnerHTML={{ __html: xss(highlightText(data.app.title, searchTerm)) }}/>;
return (
<Flex alignItems="center">
<Image
@@ -251,7 +252,8 @@ const SearchResultListItem = ({ data, searchTerm, isLoading }: Props) => {
case 'contract':
case 'address': {
const shouldHighlightHash = data.address.toLowerCase() === searchTerm.toLowerCase();
return data.name ? <span dangerouslySetInnerHTML={{ __html: shouldHighlightHash ? data.name : highlightText(data.name, searchTerm) }}/> : null;
// eslint-disable-next-line max-len
return data.name ? <span dangerouslySetInnerHTML={{ __html: shouldHighlightHash ? xss(data.name) : xss(highlightText(data.name, searchTerm)) }}/> : null;
}
default:
+5 -4
View File
@@ -1,5 +1,6 @@
import { Tr, Td, Text, Flex, Icon, Image, Box, Skeleton, useColorMode } from '@chakra-ui/react';
import React from 'react';
import xss from 'xss';
import type { SearchResultItem } from 'types/api/search';
@@ -67,7 +68,7 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading }: Props) => {
overflow="hidden"
textOverflow="ellipsis"
whiteSpace="nowrap"
dangerouslySetInnerHTML={{ __html: highlightText(name, searchTerm) }}
dangerouslySetInnerHTML={{ __html: xss(highlightText(name, searchTerm)) }}
/>
</LinkInternal>
{ data.is_verified_via_admin_panel && <Icon as={ verifiedToken } boxSize={ 4 } ml={ 1 } color="green.500"/> }
@@ -118,7 +119,7 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading }: Props) => {
</Flex>
</Td>
<Td colSpan={ 2 } fontSize="sm" verticalAlign="middle">
<span dangerouslySetInnerHTML={{ __html: shouldHighlightHash ? data.name : highlightText(data.name, searchTerm) }}/>
<span dangerouslySetInnerHTML={{ __html: shouldHighlightHash ? xss(data.name) : xss(highlightText(data.name, searchTerm)) }}/>
</Td>
</>
);
@@ -150,7 +151,7 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading }: Props) => {
isLoading={ isLoading }
onClick={ handleLinkClick }
>
<span dangerouslySetInnerHTML={{ __html: highlightText(data.name, searchTerm) }}/>
<span dangerouslySetInnerHTML={{ __html: xss(highlightText(data.name, searchTerm)) }}/>
</LinkInternal>
</Flex>
</Td>
@@ -168,7 +169,7 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading }: Props) => {
}
case 'app': {
const title = <span dangerouslySetInnerHTML={{ __html: highlightText(data.app.title, searchTerm) }}/>;
const title = <span dangerouslySetInnerHTML={{ __html: xss(highlightText(data.app.title, searchTerm)) }}/>;
return (
<>
<Td fontSize="sm">
@@ -1,5 +1,6 @@
import { Box, Text, Grid, Flex, Icon } from '@chakra-ui/react';
import React from 'react';
import xss from 'xss';
import type { SearchResultAddressOrContract } from 'types/api/search';
@@ -24,7 +25,7 @@ const SearchBarSuggestAddress = ({ data, isMobile, searchTerm }: Props) => {
whiteSpace="nowrap"
textOverflow="ellipsis"
>
<span dangerouslySetInnerHTML={{ __html: highlightText(data.name, searchTerm) }}/>
<span dangerouslySetInnerHTML={{ __html: xss(highlightText(data.name, searchTerm)) }}/>
</Text>
);
const isContractVerified = data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 1 }/>;
@@ -1,6 +1,7 @@
import { Icon, Image, Flex, Text, useColorModeValue } from '@chakra-ui/react';
import NextLink from 'next/link';
import React from 'react';
import xss from 'xss';
import type { MarketplaceAppOverview } from 'types/client/marketplace';
@@ -40,7 +41,7 @@ const SearchBarSuggestApp = ({ data, isMobile, searchTerm, onClick }: Props) =>
textOverflow="ellipsis"
ml={ 2 }
>
<span dangerouslySetInnerHTML={{ __html: highlightText(data.title, searchTerm) }}/>
<span dangerouslySetInnerHTML={{ __html: xss(highlightText(data.title, searchTerm)) }}/>
</Text>
{ data.external && <Icon as={ arrowIcon } boxSize={ 4 } verticalAlign="middle"/> }
</Flex>
@@ -70,7 +71,7 @@ const SearchBarSuggestApp = ({ data, isMobile, searchTerm, onClick }: Props) =>
w="200px"
flexShrink={ 0 }
>
<span dangerouslySetInnerHTML={{ __html: highlightText(data.title, searchTerm) }}/>
<span dangerouslySetInnerHTML={{ __html: xss(highlightText(data.title, searchTerm)) }}/>
</Text>
<Text
variant="secondary"
@@ -1,5 +1,6 @@
import { Grid, Text, Flex, Icon } from '@chakra-ui/react';
import React from 'react';
import xss from 'xss';
import type { SearchResultLabel } from 'types/api/search';
@@ -24,7 +25,7 @@ const SearchBarSuggestLabel = ({ data, isMobile, searchTerm }: Props) => {
whiteSpace="nowrap"
textOverflow="ellipsis"
>
<span dangerouslySetInnerHTML={{ __html: highlightText(data.name, searchTerm) }}/>
<span dangerouslySetInnerHTML={{ __html: xss(highlightText(data.name, searchTerm)) }}/>
</Text>
);
@@ -1,5 +1,6 @@
import { Grid, Text, Flex, Icon } from '@chakra-ui/react';
import React from 'react';
import xss from 'xss';
import type { SearchResultToken } from 'types/api/search';
@@ -25,7 +26,7 @@ const SearchBarSuggestToken = ({ data, isMobile, searchTerm }: Props) => {
whiteSpace="nowrap"
textOverflow="ellipsis"
>
<span dangerouslySetInnerHTML={{ __html: highlightText(data.name + (data.symbol ? ` (${ data.symbol })` : ''), searchTerm) }}/>
<span dangerouslySetInnerHTML={{ __html: xss(highlightText(data.name + (data.symbol ? ` (${ data.symbol })` : ''), searchTerm)) }}/>
</Text>
);
+13
View File
@@ -6486,6 +6486,11 @@ cssesc@^3.0.0:
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
[email protected]:
version "0.0.10"
resolved "https://registry.yarnpkg.com/cssfilter/-/cssfilter-0.0.10.tgz#c6d2672632a2e5c83e013e6864a42ce8defd20ae"
integrity sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==
csso@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529"
@@ -12938,6 +12943,14 @@ xmlchars@^2.2.0:
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
xss@^1.0.14:
version "1.0.14"
resolved "https://registry.yarnpkg.com/xss/-/xss-1.0.14.tgz#4f3efbde75ad0d82e9921cc3c95e6590dd336694"
integrity sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==
dependencies:
commander "^2.20.3"
cssfilter "0.0.10"
xtend@^4.0.0, xtend@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"