Skip to content
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

Clustered and overlapped text in SVG NFT metadata images that are generated from ReceiptRender.sol block users from correctly valuing the NFT #126

Closed
code423n4 opened this issue Jan 27, 2023 · 4 comments
Labels
bug Something isn't working disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) downgraded by judge Judge downgraded the risk level of this issue grade-b QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/ReceiptRenderer.sol#L10

Vulnerability details

Impact

Clustered and overlapped text in SVG NFT metadata images that are generated from ReceiptRender.sol block users from correctly valuing the NFT

Proof of Concept

The POC attemps to generate a NFT metadata and extract the SVG image to render the image.

First, copy the whole code in the file below

https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/ReceiptRenderer.sol#L10

Then go to https://remix.ethereum.org/#optimize=false&runs=200&evmVersion=null&version=soljson-v0.8.7+commit.e28d00a7.js

paste the code, complie the smart contract and deploy the smart contract to the local test network in remix

Then we can supply the parameter and call generateTokenURI view function in remix

tokenId: 10,
QuestId: 100,
totalParticipants: 20
claimed: false,
rewardAmount: 1000000000000
rewardAddress: 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174

The string generated in base64 format is:

data:application/json;base64,eyJuYW1lIjogIlJhYmJpdEhvbGUuZ2cgUmVjZWlwdCAjMTAiLCJkZXNjcmlwdGlvbiI6ICJSYWJiaXRIb2xlLmdnIFJlY2VpcHRzIGFyZSB1c2VkIHRvIGNsYWltIHJld2FyZHMgZnJvbSBjb21wbGV0ZWQgcXVlc3RzLiIsImltYWdlIjogImRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5QjRiV3h1Y3owaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaUlIQnlaWE5sY25abFFYTndaV04wVW1GMGFXODlJbmhOYVc1WlRXbHVJRzFsWlhRaUlIWnBaWGRDYjNnOUlqQWdNQ0F6TlRBZ016VXdJajQ4YzNSNWJHVStMbUpoYzJVZ2V5Qm1hV3hzT2lCM2FHbDBaVHNnWm05dWRDMW1ZVzFwYkhrNklITmxjbWxtT3lCbWIyNTBMWE5wZW1VNklERTBjSGc3SUgwOEwzTjBlV3hsUGp4eVpXTjBJSGRwWkhSb1BTSXhNREFsSWlCb1pXbG5hSFE5SWpFd01DVWlJR1pwYkd3OUltSnNZV05ySWlBdlBqeDBaWGgwSUhnOUlqVXdKU0lnZVQwaU5EQWxJaUJqYkdGemN6MGlZbUZ6WlNJZ1pHOXRhVzVoYm5RdFltRnpaV3hwYm1VOUltMXBaR1JzWlNJZ2RHVjRkQzFoYm1Ob2IzSTlJbTFwWkdSc1pTSStVbUZpWW1sMFNHOXNaU0JSZFdWemRDQWpNVEF3UEM5MFpYaDBQangwWlhoMElIZzlJamN3SlNJZ2VUMGlOREFsSWlCamJHRnpjejBpWW1GelpTSWdaRzl0YVc1aGJuUXRZbUZ6Wld4cGJtVTlJbTFwWkdSc1pTSWdkR1Y0ZEMxaGJtTm9iM0k5SW0xcFpHUnNaU0krVW1GaVltbDBTRzlzWlNCUmRXVnpkQ0JTWldObGFYQjBJQ01BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUNqd3ZkR1Y0ZEQ0OEwzTjJaejQ9IiwiYXR0cmlidXRlcyI6IFt7InRyYWl0X3R5cGUiOiAiUXVlc3QgSUQiLCJ2YWx1ZSI6ICIxMDAifSx7InRyYWl0X3R5cGUiOiAiVG9rZW4gSUQiLCJ2YWx1ZSI6ICIxMCJ9LHsidHJhaXRfdHlwZSI6ICJUb3RhbCBQYXJ0aWNpcGFudHMiLCJ2YWx1ZSI6ICIyMCJ9LHsidHJhaXRfdHlwZSI6ICJDbGFpbWVkIiwidmFsdWUiOiAiZmFsc2UifSx7InRyYWl0X3R5cGUiOiAiUmV3YXJkIEFtb3VudCIsInZhbHVlIjogIjEwMDAwMDAwMDAwMDAifSx7InRyYWl0X3R5cGUiOiAiUmV3YXJkIEFkZHJlc3MiLCJ2YWx1ZSI6ICIweDI3OTFiY2ExZjJkZTQ2NjFlZDg4YTMwYzk5YTdhOTQ0OWFhODQxNzQifV19

Then we go to the website to decode the base64 string to a json object

https://onlinejsontools.com/convert-base64-to-json

The decodes json object is:

{"name": "RabbitHole.gg Receipt #10","description": "RabbitHole.gg Receipts are used to claim rewards from completed quests.","image": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaW5ZTWluIG1lZXQiIHZpZXdCb3g9IjAgMCAzNTAgMzUwIj48c3R5bGU+LmJhc2UgeyBmaWxsOiB3aGl0ZTsgZm9udC1mYW1pbHk6IHNlcmlmOyBmb250LXNpemU6IDE0cHg7IH08L3N0eWxlPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9ImJsYWNrIiAvPjx0ZXh0IHg9IjUwJSIgeT0iNDAlIiBjbGFzcz0iYmFzZSIgZG9taW5hbnQtYmFzZWxpbmU9Im1pZGRsZSIgdGV4dC1hbmNob3I9Im1pZGRsZSI+UmFiYml0SG9sZSBRdWVzdCAjMTAwPC90ZXh0Pjx0ZXh0IHg9IjcwJSIgeT0iNDAlIiBjbGFzcz0iYmFzZSIgZG9taW5hbnQtYmFzZWxpbmU9Im1pZGRsZSIgdGV4dC1hbmNob3I9Im1pZGRsZSI+UmFiYml0SG9sZSBRdWVzdCBSZWNlaXB0ICMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACjwvdGV4dD48L3N2Zz4=","attributes": [{"trait_type": "Quest ID","value": "100"},{"trait_type": "Token ID","value": "10"},{"trait_type": "Total Participants","value": "20"},{"trait_type": "Claimed","value": "false"},{"trait_type": "Reward Amount","value": "1000000000000"},{"trait_type": "Reward Address","value": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174"}]}

We copy the image data and go to

https://onlinejsontools.com/convert-base64-to-json

again to decode the image from base64 text to svg format

the image data:
data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaW5ZTWluIG1lZXQiIHZpZXdCb3g9IjAgMCAzNTAgMzUwIj48c3R5bGU+LmJhc2UgeyBmaWxsOiB3aGl0ZTsgZm9udC1mYW1pbHk6IHNlcmlmOyBmb250LXNpemU6IDE0cHg7IH08L3N0eWxlPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9ImJsYWNrIiAvPjx0ZXh0IHg9IjUwJSIgeT0iNDAlIiBjbGFzcz0iYmFzZSIgZG9taW5hbnQtYmFzZWxpbmU9Im1pZGRsZSIgdGV4dC1hbmNob3I9Im1pZGRsZSI+UmFiYml0SG9sZSBRdWVzdCAjMTAwPC90ZXh0Pjx0ZXh0IHg9IjcwJSIgeT0iNDAlIiBjbGFzcz0iYmFzZSIgZG9taW5hbnQtYmFzZWxpbmU9Im1pZGRsZSIgdGV4dC1hbmNob3I9Im1pZGRsZSI+UmFiYml0SG9sZSBRdWVzdCBSZWNlaXB0ICMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACjwvdGV4dD48L3N2Zz4=

is decoded to:

<style>.base { fill: white; font-family: serif; font-size: 14px; }</style>RabbitHole Quest #100RabbitHole Quest Receipt #

We go to the website to view and render the generated SVG:

https://www.svgviewer.dev/

The image is linked below:

https://drive.google.com/file/d/10QSTcJL0HSubkGIMAYXjWmdA9Sb_XAT-/view

As we can see ,the text in the NFT metadata image are clustered and overlapped, from user's prespective, it is difficult to value the NFT correctly just by look at the image.

The impact is severe, the third party marketplace relies on the tokenURI and the image to correctly display the NFT image to end user, end user may be confused and has no desire to trade the NFT if he see such clustered text in the metadata image.

Tools Used

Manual Review

Recommended Mitigation Steps

We recommend the protocol adjust the layout (parameter of x and y and width and height) of the text in SVG image to avoid clustered text.

'<rect width="100%" height="100%" fill="black" />',
'<text x="50%" y="40%" class="base" dominant-baseline="middle" text-anchor="middle">RabbitHole Quest #',
questId_,
'</text>',
'<text x="70%" y="40%" class="base" dominant-baseline="middle" text-anchor="middle">RabbitHole Quest Receipt #',
@code423n4 code423n4 added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working labels Jan 27, 2023
code423n4 added a commit that referenced this issue Jan 27, 2023
@waynehoover
Copy link

Same as #127 (comment)

@c4-sponsor
Copy link

waynehoover marked the issue as disagree with severity

@c4-sponsor c4-sponsor added the disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) label Feb 7, 2023
@c4-judge c4-judge added downgraded by judge Judge downgraded the risk level of this issue QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax and removed 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value labels Feb 16, 2023
@c4-judge
Copy link
Contributor

kirk-baird changed the severity to QA (Quality Assurance)

@c4-judge
Copy link
Contributor

kirk-baird marked the issue as grade-b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) downgraded by judge Judge downgraded the risk level of this issue grade-b QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax
Projects
None yet
Development

No branches or pull requests

5 participants