Platform: Code4rena
Start Date: 17/03/2023
Pot Size: $36,500 USDC
Total HM: 10
Participants: 98
Period: 3 days
Judge: leastwood
Total Solo HM: 5
Id: 223
League: ETH
Rank: 32/98
Findings: 3
Award: $82.51
🌟 Selected for report: 0
🚀 Solo Findings: 0
19.8705 USDC - $19.87
// https://github.com/code-423n4/2023-03-canto-identity/blob/main/canto-bio-protocol/src/Bio.sol#L43-L117
The function
will generate SVG data and insert the bioText
of the specified NFT into it. Front-end developers are likely to insert this SVG data to the webpage, and attackers may use this to carry out XSS attack.
Attackers may use this to carry out XSS attack.
function testXssString() public { string memory XssString = unicode"<script>alert('XSS');</script>"; uint256 len = bytes(XssString).length; bio.mint(XssString); uint256 tokenId = bio.numMinted(); string memory uri = bio.tokenURI(tokenId); string memory json = string(Base64.decode(slice(uri, 29, bytes(uri).length))); string memory svg = string(Base64.decode(slice(json, 74 + bytes(XssString).length, bytes(json).length - 2))); }
The return of tokenURI
function is:
data:application/json;base64,eyJuYW1lIjogIkJpbyAjMSIsICJkZXNjcmlwdGlvbiI6ICI8c2NyaXB0PmFsZXJ0KCdYU1MnKTs8L3NjcmlwdD4iLCAiaW1hZ2UiOiAiZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCNGJXeHVjejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpSUhCeVpYTmxjblpsUVhOd1pXTjBVbUYwYVc4OUluaE5hVzVaVFdsdUlHMWxaWFFpSUhacFpYZENiM2c5SWpBZ01DQTBNREFnTVRBd0lqNDhjM1I1YkdVK2RHVjRkQ0I3SUdadmJuUXRabUZ0YVd4NU9pQnpZVzV6TFhObGNtbG1PeUJtYjI1MExYTnBlbVU2SURFeWNIZzdJSDA4TDNOMGVXeGxQangwWlhoMElIZzlJalV3SlNJZ2VUMGlOVEFsSWlCa2IyMXBibUZ1ZEMxaVlYTmxiR2x1WlQwaWJXbGtaR3hsSWlCMFpYaDBMV0Z1WTJodmNqMGliV2xrWkd4bElqNDhkSE53WVc0Z2VEMGlOVEFsSWlCa2VUMGlNakFpUGp4elkzSnBjSFErWVd4bGNuUW9KMWhUVXljcE96d3ZjMk55YVhCMFBqd3ZkSE53WVc0K1BDOTBaWGgwUGp3dmMzWm5QZz09In0=
The base64 decoded SVG data is:
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 400 100"><style>text { font-family: sans-serif; font-size: 12px; }</style><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle"><tspan x="50%" dy="20"><script>alert('XSS');</script></tspan></text></svg>
After opening this data in a brower, an XSS bullet box pops up.
Manual
Do XSS verification when converting to uri or implement the conversion logic externally (such as the front-end).
#0 - c4-judge
2023-03-28T03:50:47Z
0xleastwood marked the issue as duplicate of #212
#1 - c4-judge
2023-03-30T20:27:00Z
0xleastwood changed the severity to 2 (Med Risk)
#2 - c4-judge
2023-04-11T19:31:31Z
0xleastwood marked the issue as satisfactory
39.8657 USDC - $39.87
// https://github.com/code-423n4/2023-03-canto-identity/blob/main/canto-namespace-protocol/src/Tray.sol#L150-L168 /// @notice Buy a specifiable amount of trays /// @param _amount Amount of trays to buy function buy(uint256 _amount) external { uint256 startingTrayId = _nextTokenId(); if (prelaunchMinted == type(uint256).max) { // Still in prelaunch phase if (msg.sender != owner) revert OnlyOwnerCanMintPreLaunch(); if (startingTrayId + _amount - 1 > PRE_LAUNCH_MINT_CAP) revert MintExceedsPreLaunchAmount(); } else { SafeTransferLib.safeTransferFrom(note, msg.sender, revenueAddress, _amount * trayPrice); } for (uint256 i; i < _amount; ++i) { TileData[TILES_PER_TRAY] memory trayTiledata; for (uint256 j; j < TILES_PER_TRAY; ++j) { lastHash = keccak256(abi.encode(lastHash)); trayTiledata[j] = _drawing(uint256(lastHash)); } tiles[startingTrayId + i] = trayTiledata; } _mint(msg.sender, _amount); // We do not use _safeMint on purpose here to disallow callbacks and save gas }
Each NFT tiles is hashed from the previous NFT tile, so all tiles are predictable.
Tiles are used to generate SVG with a fixed algorithm. If tiles are predictable, so are all SVGs. The SVG of each Tray NFT is the only factor that distinguishes it from other NFTs. Whether the SVG looks good or not is an important factor affecting the price of each NFT.
If all SVGs are predictable, the attacker can buy their favorite (higher value) NFT at a base price based on the predicted value.
Manual
Add some random factors when generating tiles.
#0 - c4-judge
2023-03-28T18:46:15Z
0xleastwood marked the issue as duplicate of #121
#1 - c4-judge
2023-04-10T13:28:25Z
0xleastwood changed the severity to 2 (Med Risk)
#2 - c4-judge
2023-04-11T19:54:01Z
0xleastwood marked the issue as satisfactory
#3 - c4-judge
2023-04-11T20:03:19Z
0xleastwood marked the issue as duplicate of #121
#4 - c4-judge
2023-04-12T00:54:57Z
0xleastwood marked the issue as duplicate of #130
#5 - c4-judge
2023-04-12T00:56:32Z
0xleastwood marked the issue as partial-50