CosmWasm security spotlight #2

JCsec
Oak Security
Published in
4 min readApr 17, 2023

Are you a CosmWasm Smart Contract developer? A random Cosmonaut peeking into this cool tech? A Solidity auditor looking for new knowledge? Then keep reading!

There are loads of great content about security findings and auditing of Solidity Smart Contracts. Sadly, that is not the case in CosmWasm… yet!

Access Controls

Access controls are one of the main concerns in software security. It doesn’t matter if you are talking about webapps, mobile APIs, network services, or Smart Contracts. Being able to restrict who can access specific functionality is key.

And of course, if you are protecting access to key functionality that means that untrusted parties would cause negative effects by operating them. The actual impact will depend on each individual case, of course. You probably already get a sense of how deadly this could be for your smart contract, but let’s look at the example below. What would happen if you spot the following function in some kind of staking protocol? An anonymous user could set their own address as the vault, receiving all the rewards accrued by the contract.

fn update_config(
deps: DepsMut,
msg: UpdateMsg
) -> Result<Response, ContractError> {
let config = CONFIG.load(deps.storage)?;

let new_config = Config {
rewards_vault_contract: msg.vault_address
.map(|human| deps.api.addr_validate(&human))
.transpose()?
.unwrap_or(config.rewards_vault_contract)
};
CONFIG.save(deps.storage, &new_config)?;

Ok(Response::new().add_attribute("action", "update_config"))
}

A Broken Access Control issue happens either when: access control is missing, it is in place but can be bypassed or the guard in place does not restrict access to the expected actor exclusively.

Let’s take a look at the following real-life issues:

[CRITICAL] Report 1 finding #1 “Task contract execute_update_config is permissionless”

This is one of those “from the book” cases: missing access control in an administrative function. It allowed anonymous users to modify critical parameters to disrupt the contract in different ways, for example, triggering the emergency break.

The developers knew about Access Controls, of course. Indeed they are very skilled coders that created a high-quality product, in my opinion. But tiny mistakes happen to the best, which could lead to disastrous situations if exploited in the wild. That is why auditors are part of the Secure Development Lifecycle, to act as additional security-focused pairs of eyes. Three pairs of eyes in the case of Oak Security audits ;)

[MAJOR] Report 2 finding #1 “Incorrect permissioning of IbcExecuteProposal execution leads to failure of proposal execution and elevated owner privileges”

In this case, there was access control in place! Just not the correct one. Instead of restricting access to the contract expected to submit proposals through IBC, access was granted to the owner.

This results in two different risks: the protocol was not able to properly operate as it will error out on each new proposal, and the owner could freely submit proposals. The second one does not just go against decentralization principles but opens up for a more dramatic impact in case the owner keys get compromised.

[CRITICAL] Report 3 finding #6 “Emergency ShutDownVamms messages are not able to execute SetOpen transactions due to lack of permissions”

As in the above finding, incorrect access controls were in place. In this case, the affected functionality was an emergency feature to pause virtual AMMs in case of need. This was not possible at all as instead of accepting interactions from the key insurance_fund contract, the guard only allowed the owner to use the emergency pause feature.

Hunt the bug!

Go practice in the second challenge of Oak Security CosmWasm Security Dojo created by Richie, and hunt this bug in a small lending contract. Peeking into the exploit too soon counts as cheating! :P

How to avoid this issue?

This vulnerability should be approached at different stages: design, implementation, and testing.

During the design phase, you should thoroughly brainstorm and document who should access each entry point or feature following the “least privilege” principle. That is, being as restrictive as possible to reduce the attack surface exposed to external actors.

The next step may sound obvious to all of you… but well, actually implement what you have documented. Double-check it! Still, you should add a safeguard in the form of thorough testing to ensure that everything is in place.

Someone probably told you already, but your testing should not be limited to happy paths and expected use cases. Years ago I read a statement that looked like this: “a system can be considered secure if and only if it does what is supposed to and nothing else” — it is a good principle to follow while designing your test cases.

Going back to testing access controls, the following may act as a non-exhaustive cheat sheet. Explicitly test that:

  1. The expected caller, the one you noted down during the design, can successfully access the feature.
  2. An “Unauthorized” error (or any other custom and descriptive error) is returned when calling from a random address. Unless the function is expected to be used by anonymous users, of course.
  3. An “Unauthorized” error is returned when calling from any other of the privileged addresses defined in your contract.

Contact me!

If you have any questions or comments or want to know more about Oak Security and Solidified, feel free to drop a line to @jcr_auditor on Telegram or email me at jcr@oaksecurity.io

Check out my Github profile for further educational content on Smart Contract security and auditing. For example, the CosmWasm Security and Audits roadmap!

Telegram | Email | Twitter | Github | LinkedIn

Disclaimer! Although most of the reports I will link are of audits I took part in, I will also include others. I do not claim ownership of any kind of the external resources included in these articles :)

--

--

JCsec
Oak Security

Smart Contract security auditor specialized in CosmWasm. Follow me on Twitter @jcsec_audits and Github https://github.com/jcsec-security