Light ModeLight
Light ModeDark

One Bug Per Day

One H/M every day from top Wardens

Checkmark

Join over 1120 wardens!

Checkmark

Receive the email at any hour!

Ad

can impersonate another high value rental because token_uri is arbitrary and supplied by user.

mediumCode4rena

Lines of code

https://github.com/code-423n4/2024-10-coded-estate/blob/97efb35fd3734676f33598e6dff70119e41c7032/contracts/codedestate/src/execute.rs#L255

Vulnerability details

Impact

because token_uri value is not sanitized and is arbitrary/provided by a user, a malicious user can provide a token uri which may have " or , or simply a fake url which points to a different higher value rental property in order to phish unsuspecting users.

Proof Of Concept

rust
pub fn mint( &self, deps: DepsMut, info: MessageInfo, token_id: String, owner: String, token_uri: Option<String>, extension: T, ) -> Result<Response<C>, ContractError> { //@audit no money collected to mint a token? do they mint for free? // cw_ownable::assert_owner(deps.storage, &info.sender)?; let longterm_rental = LongTermRental { islisted: None, price_per_month: 0u64, available_period:vec![], deposit_amount: Uint128::from(0u64), withdrawn_amount: Uint128::from(0u64), denom:"ibc/F082B65C88E4B6D5EF1DB243CDA1D331D002759E938A0F5CD3FFDC5D53B3E349".to_string(), auto_approve:false, cancellation:vec![], minimum_stay:0u64, }; let shortterm_rental = ShortTermRental { islisted: None, price_per_day: 0u64, available_period: vec![], deposit_amount: Uint128::from(0u64), withdrawn_amount: Uint128::from(0u64), denom: "ibc/F082B65C88E4B6D5EF1DB243CDA1D331D002759E938A0F5CD3FFDC5D53B3E349".to_string(), auto_approve: false, cancellation:vec![], minimum_stay:0u64, }; let sell = Sell { islisted:None, auto_approve:false, price:0u64, denom:"ibc/F082B65C88E4B6D5EF1DB243CDA1D331D002759E938A0F5CD3FFDC5D53B3E349".to_string(), }; // create the token let token = TokenInfo { owner: info.sender.clone(), approvals: vec![], rentals:vec![], bids:vec![], longterm_rental, shortterm_rental, sell, token_uri, extension, }; self.tokens .update(deps.storage, &token_id, |old| match old { Some(_) => Err(ContractError::Claimed {}), None => Ok(token), })?; self.increment_tokens(deps.storage)?; Ok(Response::new() .add_attribute("action", "mint") .add_attribute("minter", info.sender) .add_attribute("owner", owner) //@audit here owner arg is used but in the token object owner is set to info.sender. owner may not be info.sender .add_attribute("token_id", token_id)) }

lets say a malicious user wants to make a rental that impersonates another high value rental, the attacker can set his own token's uri to be an exact copy of the high value rental and display attributes/json metadata which is the same. Unsuspecting users might then be tricked into renting from the wrong landlord or buying the wrong rental, because the frontend will display same rental property image and same attributes. All this is possible because token_uri is arbitrary.

To prevent your project from becoming a hotbed for phishing, the token_uri should not be arbitrary, it can be generated by the code. There are a few similar implementations like this here. The token uri is constructed into a json string and its then modified into a base64 json.

Recommened Mitigation

dont make token uri arbitrary, generate it in code. Ensure your generation logic rejects strings that contain " and , as these can also be exploited by attackers to do json injection of false fields.

Assessed type

Context