Oak Security Audit Report
We want to give a big shout-out to Oak Security for their awesome work in auditing the Wasmd module for us at Confio. They conducted an in-depth analysis, identifying vulnerabilities and offering valuable suggestions to enhance code safety and readability.
This is Scope 3 of the CosmWasm audit, following cosmwasm and wasmvm.
Now that the security report has been published, it is our turn to explain how we tackled its findings. We will not discuss the severity levels but just focus on the technical and motivation side.
Gzipped wasm binaries with invalid CRC could be used to DOS the chain
This issue has been resolved by introducing gas charges even when the uncompress operation fails. We cannot prevent anybody from uploading invalid archives, but we can make it more expensive in fees. This raises the barrier higher than what is charged by DefaultTxSizeCostPerByte
costs in the SDK already. See Charge gas to unzip wasm code by alpe · Pull Request #898 · CosmWasm/wasmd (github.com) for more details.
This fix was included in the Wasmd v0.29.0 (2022–10–10) release.
Contract admins can bypass code ID instantiation permission when migrating contracts
This bug is relevant for permissioned chains as contract admins could bypass code ID instantiate permissions by specifying restricted code IDs during contract migration. The issue has been resolved by preventing migration to a restricted code. See Prevent migration to a restricted code by alpe · Pull Request #900 · CosmWasm/wasmd (github.com) for more details.
This fix was included in the Wasmd v0.29.0 (2022–10–10) release.
IBC Querier plugin’s unbounded loop could lead to DoS
This issue can impact all contracts using ListChannels in scenarios with numerous registered channels. To address it, the query now returns only the channels bound to the contract’s port when the port_id is omitted. While this doesn’t completely resolve the problem, it significantly reduces the attack vector through a more efficient query implementation. See Bug in IbcQuery::ListChannels implementation when port is unset · Issue #1597 · CosmWasm/wasmd (github.com) for more details.
This fix was included in the Wasmd v0.42.0 (2023–09–20) release.
See the security advisory advisories/CWAs/CWA-2023–003.md at main · CosmWasm/advisories (github.com) for more details.
Governance permissioned chains are not supporting CosmWasm contracts that dynamically instantiate other contracts
This design choice was made to handle complexity in Wasmd and was never challenged by the community before. With the mesh-security contract setup, the need for this feature became visible in order to address the contract dependencies in a real scenario. Oak Security did very well to spot this early and report to us.
It has been implemented to enable contracts to instantiate other contracts. See Gov: support contracts that dynamically instantiate other contracts · Issue #1207 · CosmWasm/wasmd (github.com) for more details.
This feature was included in the Wasmd v0.41.0 (2023–07–28) release.
When updating a contract’s AccessConfig subset, conditions are not enforced
The AccessConfig was previously stored without any further checks. However, this feature was initially available only to the governance process and included a manual gate where people voted on updates.
We introduced the suggested changes to prepare for cases where Wasmd is used as a library with direct access to keeper methods. This has been addressed by imposing restrictions on code access configuration modifications. This adjustment also proved valuable when we migrated to govv1, as it allowed us to make the AccessConfig update generally available to users without a governance process. See Restrict code access config modifications by alpe · Pull Request #901 · CosmWasm/wasmd (github.com) for more details.
This feature was included in the Wasmd v0.29.0 (2022–10–10) release.
Attribute keys starting with underscores lead to errors, causing smart contract runtime errors
This is a design decision in Wasmd to reserve a unique namespace in attributes that can not be set by contracts. Events and attributes are specifically designed as logging mechanisms and should not be employed for logic handling. It’s crucial to ensure that communication between contracts is carried out through messaging and the data
response field, as this is the proper way to use CosmWasm, preventing any potential issues or bugs. See wasmd/EVENTS.md at main · CosmWasm/wasmd (github.com) for more details.
Updating access configurations can render existing contracts non-compliant
This finding is correct. Changes to the chain settings do not affect existing AccessConfigs. This is a design decision in Wasmd.
Every AccessConfig was valid at the time of creation. If there’s a need to enforce a more restrictive AccessConfig, the recommended approach is to execute this change through a chain upgrade that includes a store migration. This migration process would systematically go through all code instances and apply the necessary changes.
This chain upgrade should come with a communication strategy to ensure that contract developers are well informed about the changes, particularly when restricting access.
Possible key collision in appendToContractHistory function
This is a false positive, not an actual bug. Indeed, it is accurate that both keys have the same value due to iota=0
. However, it is crucial to note that these keys belong to distinct types and reside in separate packages. The Go standard library’s context implementation takes into consideration this distinction when returning values. Consequently, this is a false positive in the report. For further clarification, you can refer to the following link: Go Playground Example.
autoIncrementID is a misleading variable name that may impact future maintainability
This issue was resolved by renaming the variable. See Rename `lastIDKey` key · Issue #1182 · CosmWasm/wasmd (github.com) for more details.
This fix was included in the Wasmd v0.40.0 (2023–05–25) release.
Input label validation can be bypassed using white space, label supports non-printable characters
This is a valuable improvement since label should be informative and human-readable. It was implemented in two steps:
- Trimming trailing whitespaces. See Trim label to prevent whitespaces · Issue #1183 · CosmWasm/wasmd (github.com) for more details. This fix was included in the Wasmd v0.41.0 (2023–07–28) release.
- Preventing non-printable characters. See Prevent non printable characters in label · Issue #1623 · CosmWasm/wasmd (github.com) for more details. The changes will be included in the upcoming Wasmd release v0.44.0.
Proposal validations can be improved
This improvement suggestion led to the addition of new checks for proposal validations. See Feat : Improved Proposal validations by ruthishvitwit · Pull Request #1402 · CosmWasm/wasmd (github.com) for more details.
This fix was included in the Wasmd v0.41.0 (2023–07–28) release. It’s worth noting that govv1beta1 proposals have been removed in Wasmd v0.43.0, making the fix no longer relevant.
Lack of event emission when storing code, updating, or clearing an admin through a proposal
This issue was connected to govv1beta1 proposals. However, once we upgraded to govv1, this was no longer relevant, and as a result, we didn’t address it. We started the process by deprecating govv1beta1 proposals in Wasmd release v0.40, and we completely removed them from the codebase in Wasmd v0.43.
Sudo contract interactions do not consume gas
The Sudo entry point is special compared to the others and exclusively used by Go code for direct access to a contract. It can not be called by an external user transaction directly. This is a building block for deep chain integration of contracts.
For fallback scenarios, the gov process has a sudo proposal type that integrates with the Cosmos SDK. Gov proposals in the SDK are executed in an end-blocker without a gas limit. This is a decision made by the SDK team for the governance module. This behavior cannot be modified by the Wasmd module because gas limits are externally managed. Additionally, it’s worth noting that executing a sudo callback into a contract using a governance proposal isn’t the sole method; there are alternative options, as seen in projects like Tgrade or Osmosis, where the callback occurs at the transaction level. In such cases, the gas consumed becomes a significant consideration.