Open c4-bot-9 opened 9 months ago
Picodes marked the issue as primary issue
othernet-global (sponsor) confirmed
confirm_ is now prepended to automatic confirmation ballots form setWebsiteURL and setContract proposals.
https://github.com/othernet-global/salty-io/commit/5aa1bc1ddadd67cd875de932633948af25ff8957
Picodes marked the issue as satisfactory
Picodes changed the severity to QA (Quality Assurance)
This previously downgraded issue has been upgraded by Picodes
Picodes marked the issue as selected for report
Hi @Picodes,
this issue is also a duplicate of #956 / #980 and exploits the exactly same attack path of appending "_confirm" to the name.
Hi @Picodes, thanks for the judging so far.
I am just curious about why this issue is currently of Medium risk. Considering it completely prevents the DAO from setting new price feed and access manager contracts. I'd argue it should be high because of those reasons.
The stablecoin framework: /stablecoin, /price_feed, WBTC/WETH collateral, PriceAggregator, price feeds and USDS have been removed: https://github.com/othernet-global/salty-io/commit/88b7fd1f3f5e037a155424a85275efd79f3e9bf9
I don't think the severity of a finding depends on changes made after the contest. It depends on how it affects the codebase at the time of the contest.
@nonseodion isn't it clear from the definitions of severities under C4?
"2 — Med: Assets not at direct risk, but the function of the protocol or its availability could be impacted, or leak value with a hypothetical attack path with stated assumptions, but external requirements. 3 — High: Assets can be stolen/lost/compromised directly (or indirectly if there is a valid attack path that does not have hand-wavy hypotheticals)."
Here assets are not at direct risk but a "function of the protocol or its availability could be impacted"
@J4X-98 sorry I am not sure to understand, the findings you are referring to are already flagged as duplicates?
@Pico, sorry that was a mistake on my side. I only saw that both were still open and missed the duplicate tag. Sry for the inconvenience.
No worries! Thanks for flagging in case it was a mistake
Lines of code
https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/dao/Proposals.sol#L103
Vulnerability details
Impact
An adversary can prevent the creation of
setContract
andwebsiteUpdate
proposals by creating a poisonous proposal with the same ballot name +_confirm
. This attack can be performed repeatedly every few days (when the voting period ends).Affected proposals:
setContract:priceFeed1
->setContract:priceFeed1_confirm
setContract:priceFeed2
->setContract:priceFeed2_confirm
setContract:priceFeed3
->setContract:priceFeed3_confirm
setContract:accessManager
->setContract:accessManager_confirm
setURL:{{newWebsiteURL}}
->setURL:{{newWebsiteURL}}_confirm
This is especially worrisome for the
setContract
proposals, as it prevents changing the price feed contracts, which are used for USDS borrowing and liquidations.Note: This Impact fits into the Attack Ideas: "Any issue that would prevent the DAO from functioning correctly."
Vulnerability Details
setContract
andwebsiteUpdate
proposals are executed in multiple steps.Here's the process for changing the Price Feed 1, as an example:
setContract:priceFeed1
_confirm
to the ballot name, resulting insetContract:priceFeed1_confirm
.The problem is that there is a check in
_possiblyCreateProposal()
that can be exploited:Proposals.sol#L103
This check is intended to prevent creating new proposals if there is a pending confirmation proposal being voted for the same change, but an adversary can use it to create a proposal with a ballot name
setContract:priceFeed1_confirm
, by settingpriceFeed1_confirm
as the contract name.If someone tries to create a legit
priceFeed1
proposal later, it willrevert
, leading to a DOS.This holds for all proposals mentioned in the
Impact
section.Proof of Concept
src/dao/tests/Proposals.t.sol
COVERAGE="no" NETWORK="sep" forge test -vv --rpc-url https://1rpc.io/sepolia --mt "testProposeSetContractAddress_confirm"
Recommended Mitigation Steps
Given the current implementation, the most straightforward fix would be to prevent the creation of proposals with ballot names ending in
_confirm
for proposals that need a confirmation.This would mean checking the
contractName
inproposeSetContractAddress()
, and thenewWebsiteURL
inproposeWebsiteUpdate()
.But, as a recommendation, I would suggest refactoring
createConfirmationProposal()
to pass a "confirmation" parameter to_possiblyCreateProposal()
, so that confirmation proposals don't rely on the ballot name.Assessed type
Governance