Canto Identity Subprotocols contest - reassor's results

Subprotocols for Canto Identity Protocol.

General Information

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

Canto Identity Subprotocols

Findings Distribution

Researcher Performance

Rank: 26/98

Findings: 3

Award: $128.33

QA:
grade-b

🌟 Selected for report: 1

πŸš€ Solo Findings: 0

Findings Information

Awards

25.8317 USDC - $25.83

Labels

bug
2 (Med Risk)
disagree with severity
downgraded by judge
primary issue
selected for report
M-04

External Links

Lines of code

https://github.com/code-423n4/2023-03-canto-identity/blob/077372297fc419ea7688ab62cc3fd4e8f4e24e66/canto-bio-protocol/src/Bio.sol#L103-L115

Vulnerability details

Impact

The Bio Protocol allows users to mint Bio NFTs that represent user's bio. Once NFT is minted anyone can trigger tokenURI to retrieve JSON data with the bio and generated svg image. Example JSON content (decoded from Base64):

{"name": "Bio #1", "description": "Test", "image": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaW5ZTWluIG1lZXQiIHZpZXdCb3g9IjAgMCA0MDAgMTAwIj48c3R5bGU+dGV4dCB7IGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmOyBmb250LXNpemU6IDEycHg7IH08L3N0eWxlPjx0ZXh0IHg9IjUwJSIgeT0iNTAlIiBkb21pbmFudC1iYXNlbGluZT0ibWlkZGxlIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj48dHNwYW4geD0iNTAlIiBkeT0iMjAiPlRlc3Q8L3RzcGFuPjwvdGV4dD48L3N2Zz4="}

The issue is that function Bio.tokenURI is vulnerable to JSON injection and it is possible to inject " character into bio completely altering the integrity of JSON data. User sends following data as bio:

Test\", \"name\": \"Bio #999999999

This is will result in following JSON data (new name key was injected):

{"name": "Bio #1", "description": "Test", "name": "Bio #999999999", "image": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaW5ZTWluIG1lZXQiIHZpZXdCb3g9IjAgMCA0MDAgMTAwIj48c3R5bGU+dGV4dCB7IGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmOyBmb250LXNpemU6IDEycHg7IH08L3N0eWxlPjx0ZXh0IHg9IjUwJSIgeT0iNTAlIiBkb21pbmFudC1iYXNlbGluZT0ibWlkZGxlIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj48dHNwYW4geD0iNTAlIiBkeT0iMjAiPlRlc3QiLCAibmFtZSI6ICJCaW8gIzk5OTk5OTk5OTwvdHNwYW4+PC90ZXh0Pjwvc3ZnPg=="}

Depending on the usage of Bio Protocol by frontend or 3rd party applications this will have serious impact on the security. Some examples of the attacks that can be carried:

  1. Attacker might create a Bio NFT that mimics copies the name of different Bio NFT.
  2. Attacker might change the generated svg image to completely different one.
  3. Attacker might point image to external URL.
  4. Attacker might trigger cross-site scripting attacks if the data from JSON is not properly handled.

Proof of Concept

https://github.com/code-423n4/2023-03-canto-identity/blob/077372297fc419ea7688ab62cc3fd4e8f4e24e66/canto-bio-protocol/src/Bio.sol#L103-L115

Tools Used

Manual Review / Foundry / VSCode

It is recommended to properly encode user's bio to make sure it cannot alter returned JSON data.

#0 - c4-judge

2023-03-28T00:40:07Z

0xleastwood marked the issue as primary issue

#1 - c4-judge

2023-03-28T00:41:24Z

0xleastwood marked the issue as selected for report

#2 - c4-judge

2023-03-28T00:41:42Z

0xleastwood marked the issue as unsatisfactory: Overinflated severity

#3 - c4-judge

2023-03-28T00:42:19Z

0xleastwood marked the issue as selected for report

#4 - c4-sponsor

2023-03-29T19:24:48Z

OpenCoreCH marked the issue as disagree with severity

#5 - OpenCoreCH

2023-03-29T19:27:43Z

Good point that will be fixed, have some doubts about the severity. The attacks that are mentioned on the frontend in various issues (XSS / external resources) should be handled there in any case because the payload of a NFT should not be considered trusted. And if a user manipulates his own NFT, the impact is limited to him.

#6 - 0xleastwood

2023-03-30T20:11:49Z

Good point that will be fixed, have some doubts about the severity. The attacks that are mentioned on the frontend in various issues (XSS / external resources) should be handled there in any case because the payload of a NFT should not be considered trusted. And if a user manipulates his own NFT, the impact is limited to him.

It doesn't seem like this sort of tokenURI() sanitisation can be made within the contract but instead must be handled by front-ends right?

#7 - OpenCoreCH

2023-03-30T20:18:22Z

Good point that will be fixed, have some doubts about the severity. The attacks that are mentioned on the frontend in various issues (XSS / external resources) should be handled there in any case because the payload of a NFT should not be considered trusted. And if a user manipulates his own NFT, the impact is limited to him.

It doesn't seem like this sort of tokenURI() sanitisation can be made within the contract but instead must be handled by front-ends right?

I implemented some sanitisation in the mean time (escaping all characters that need to be escaped for the JSON / SVG) using Solady's escape functions. But that's mainly to ensure that the produced JSON / SVG will always be valid (and the user does not accidentally produce an invalid one by choosing some characters in his bio). I think perfect sanitisation on-chain is not feasible in practice and the frontends should generally treat this payload as untrusted and sanitise it. Otherwise, you could also actively deploy malicious NFTs to e.g. target NFT marketplace users.

#8 - 0xleastwood

2023-03-30T20:26:48Z

Completely agree. I think medium severity would make more sense then.

#9 - c4-judge

2023-03-30T20:27:02Z

0xleastwood changed the severity to 2 (Med Risk)

Findings Information

Awards

25.8317 USDC - $25.83

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
duplicate-212

External Links

Lines of code

https://github.com/code-423n4/2023-03-canto-identity/blob/077372297fc419ea7688ab62cc3fd4e8f4e24e66/canto-bio-protocol/src/Bio.sol#L97-L102

Vulnerability details

Impact

It is possible to inject bio that is a valid javascript code into generated on-chain SVG image. Attacker might pass following payload as bio:

<script>alert(1234)</script>

which will result in generation of SVG image with the code:

<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(1234)</script></tspan></text></svg>

SVG image like that included anywhere on a website will trigger javascript code of the attacker (in this case alert(1234)) that can compromise browser of every user viewing the image.

Following scenario is particularly dangerous:

  1. Website allows viewing users bio's and generated SVG images.
  2. Attacker creates bio that is a javascript code that redirects users to malicious copy of the website.
  3. Any user that visits the website executes attacker's code and gets redirected to malicious website.
  4. Users loose funds because of interactions with malicious website.

Proof of Concept

https://github.com/code-423n4/2023-03-canto-identity/blob/077372297fc419ea7688ab62cc3fd4e8f4e24e66/canto-bio-protocol/src/Bio.sol#L97-L102

Tools Used

Manual Review / Foundry / VSCode

It is recommended to properly encode user's bio to make sure it will not alter SVG image and inject Javascript code.

#0 - c4-judge

2023-03-28T03:53:15Z

0xleastwood marked the issue as duplicate of #212

#1 - c4-judge

2023-03-30T20:26:59Z

0xleastwood changed the severity to 2 (Med Risk)

#2 - c4-judge

2023-04-11T19:31:38Z

0xleastwood marked the issue as satisfactory

Findings Information

🌟 Selected for report: juancito

Also found by: Chom, J4de, Ruhum, adriro, igingu, leopoldjoy, luxartvinsec, pipoca, popular00, reassor

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
duplicate-130

Awards

79.7314 USDC - $79.73

External Links

Lines of code

https://github.com/code-423n4/2023-03-canto-identity/blob/077372297fc419ea7688ab62cc3fd4e8f4e24e66/canto-namespace-protocol/src/Tray.sol#L150-L168

Vulnerability details

Impact

Function buy of Tray contract allows buying specified amount of trays. Algorithm used for generating tiles per tray is deterministic to allow users to see what trays he/she will receive. This is also stipulated in the documentation README.md:

The 7 tiles per tray are then generated according to a deterministic algorithm. A user can therefore precompute which trays he will get.

Implementation of such a feature could be presented to the user in the frontend by displaying trays will tiles that will be minted if the user buys it.

The issue is that the call to Tray.buy can be frontrunned making this assumption incorrect and resulting with user spending $NOTE tokens on trays with tiles she didn't expect/want. Moreover this might happen also in the situation where there are no malicious actors but only two users buying trays at the same time.

Proof of Concept

https://github.com/code-423n4/2023-03-canto-identity/blob/077372297fc419ea7688ab62cc3fd4e8f4e24e66/canto-namespace-protocol/src/Tray.sol#L150-L168

Tools Used

Manual Review / VSCode

It is recommended to add _lastHash parameter to Tray.buy function and compare it with the current saved lastHash. In case these values are different the transaction should be reverted.

#0 - c4-judge

2023-03-28T18:52:07Z

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:55:09Z

0xleastwood marked the issue as satisfactory

#3 - c4-judge

2023-04-11T20:03:22Z

0xleastwood marked the issue as duplicate of #121

#4 - c4-judge

2023-04-12T00:55:00Z

0xleastwood marked the issue as duplicate of #130

Awards

22.7749 USDC - $22.77

Labels

bug
grade-b
QA (Quality Assurance)
Q-25

External Links

List

Low Risk

  1. Bio Protocol - Discrepancies between docs and implementation
  2. Namespace Protocol - Not following checks-effects-interactions pattern
  3. Namespace Protocol - Critical address change
  4. Namespace Protocol - Frontrunning buy with change of NOTE address

Non-Critical Risk

  1. Bio Protocol - Usage of _mint instead of _safeMint
  2. Profile Picture Protocol - Can mint multiple PFP NFT pointing to the same NFT
  3. Profile Picture Protocol - Can mint PFP NFT to PFP NFT
  4. Namespace Protocol - revenueAddress is private
  5. Namespace Protocol - missing delete of nftCharacters
  6. Missing natspec
  7. Missing pause functionality

1. Bio Protocol - Discrepancies between docs and implementation

Risk

Low

Impact

Bio Protocol documentation README.md states that bio has to be shorter than 200 characters:

Any user can mint a Bio NFT by calling Bio.mint and passing his biography. It needs to be shorter than 200 characters.

but the implementation allows bio with 200 characters and only reverts if the bio is longer than 200 characters:

if (bytes(_bio).length == 0 || bytes(_bio).length > 200) revert InvalidBioLength(bytes(_bio).length);

Proof of Concept

https://github.com/code-423n4/2023-03-canto-identity/blob/077372297fc419ea7688ab62cc3fd4e8f4e24e66/canto-bio-protocol/src/Bio.sol#L123

Tools Used

Manual Review / VSCode

It is recommended to either fix documentation to reflect that bio can be maximum of 200 characters or adjust implementation and revert if bio length is 200 or more characters.

2. Namespace Protocol - Not following checks-effects-interactions pattern

Risk

Low

Impact

Functions Tray.buy and Namespace.fuse do not follow checks-effects-interactions pattern which might lead to reentrancy attacks.

Proof of Concept

Tray.sol:

Namespace.sol:

Tools Used

Manual Review / VSCode

It is recommended to first set the effects of Tray.buy and Namespace.fuse functions and then charge the cost in the end of execution via SafeTransferLib.safeTransferFrom.

3. Namespace Protocol - Critical address change

Risk

Low

Impact

Changing critical addresses such as ownership should be a two-step process where the first transaction (from the old/current address) registers the new address (i.e. grants ownership) and the second transaction (from the new address) replaces the old address with the new one. This gives an opportunity to recover from incorrect addresses mistakenly used in the first step. If not, contract functionality might become inaccessible.

Proof of Concept

Tray.sol:

Namespace.sol:

Tools Used

Manual Review / VSCode

It is recommended to implement two-step process for changing ownership.

4. Namespace Protocol - Frontrunning buy with change of NOTE address

Risk

Low

Impact

Functions Tray.buy and Namespace.fuse allow buying specified amount of trays or fusing by paying with $NOTE token. The issue is that the address of $NOTE token can be changed at any time by the owner which might cause issue if the user approved contract Tray or Namespace to spend any other token than $NOTE. Owner might frontrun user and change the address of $NOTE token to address of the token user didn't intend to spend.

Proof of Concept

Tray.sol:

Namespace.sol:

Tools Used

Manual Review / VSCode

It is recommended to add _noteAddr parameter to Tray.buy and Namespace.fuse and revert if _noteAddr is different than note address.

5. Usage of _mint instead of _safeMint

Risk

Non-Critical

Impact

Functions Bio.mint and ProfilePicture.mint are using _mint internal function instead of _safeMint to mint ERC721 tokens. This might lead to issue if the function is triggered by another smart contract that does not support ERC721 tokens and tokens will get stuck in Bio or ProfilePicture contracts.

Proof of Concept

Bio.sol:

ProfilePicture.sol:

Tools Used

Manual Review / VSCode

Consider using _safeMint instead of _mint but make sure to not expose contracts to reentrancy attacks.

6. Profile Picture Protocol - Can mint multiple PFP NFT pointing to the same NFT

Risk

Non-Critical

Impact

The Profile Picture Protocol allows minting multiple PFP NFTs pointing to the same underlying NFT. This might cause issues if there will be any authorization mechanism implemented by 3rd party protocol that uses PFP NFTs.

Proof of Concept

Tools Used

Manual Review / VSCode

Consider adding check that will prohibit minting new PFP NFTs in case there is already one owned by the user.

7. Profile Picture Protocol - Can mint PFP NFT to PFP NFT

Risk

Non-Critical

Impact

Function ProfilePicture.mint allows minting PFP NFTs of another PFP NFTs. Since ProfilePicture.tokenURI points to the tokenURI of the underlying NFT it creates chain of NFTs. This might cause issues if there will be any authorization mechanism implemented by 3rd party protocol that uses PFP NFTs.

Proof of Concept

Tools Used

Manual Review / VSCode

Consider adding check that will prohibit minting PFP NFTs of the PFP NFTs.

8. Namespace Protocol - revenueAddress is private

Risk

Non-Critical

Impact

Storage variable revenueAddress of Tray and Namespace contracts is private which makes it difficult to query its value.

Proof of Concept

Tray.sol:

Namespace.sol:

Tools Used

Manual Review / VSCode

It is recommended to make revenueAddress public so it will be easy to query its value and add transparency to the protocol.

9. Namespace Protocol - missing delete of nftCharacters

Risk

Non-Critical

Impact

Function Namespace.burn allows burning specified Namespace NFT. It deletes tokenToName and nameToToken storage variables and then triggers internal _burn function. The issue is that its missing deleting nftCharacters.

Proof of Concept

Tools Used

Manual Review / VSCode

It is recommended to delete nftCharacters for the specified Namespace NFT in Namespace.burn function.

10. Missing natspec

Risk

Non-Critical

Impact

Multiple contracts are missing natspec comments which makes code more difficult to read and prone to errors.

Proof of Concept

Bio.sol:

ProfilePicture.sol:

Tray.sol:

Namespace.sol:

Utils.sol:

Tools Used

Manual Review / VSCode

It is recommended to add missing natspec comments.

11. Missing pause functionality

Risk

Non-Critical

Impact

Protocols Bio, Profile Picture and Namespace are missing pause functionality that could be used in case of security incidents and would block executing selected functions while the contracts are paused.

Proof of Concept

Namespace protocol:

Bio protocol:

Profile picture protocol:

Tools Used

Manual Review / VSCode

It is recommended to add functionality for pausing contracts and go through all publicly/externally accessible functions to decide which one should be forbidden from running while the contracts are paused.

#0 - c4-judge

2023-04-11T15:58:00Z

0xleastwood marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax Β© 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter