-
Notifications
You must be signed in to change notification settings - Fork 334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New CIP to add security fields to existing CIP-108 to prevent imposters and metadata copy #978
Comments
Actually, your first option gave me an idea that generalizes that approach: just to include the serialized gov_action exactly as it appears on chain, and require that tools verify that the details of this field match the on-chain governance action. The only thing I can see is that someone could duplicate the same governance action to themselves. For example, maybe malicious actor A creates a withdrawal proposal to build popular idea X for reasonable price P; they create two governance actions on chain, each paying P ADA to address A, and then advertise the two gov_action_id's in two separate places; on twitter they publish gov_action_id M, and on discord and tiktok they advertise gov_action_id N. If the proposal itself is popular, and their community is large, they may get lots of votes on both, and end up with 2P ADA. I think the risk of this attack vector is relatively low because:
Also, it doesn't need to be a modification to all three CIPs; in principle, CIP100 was intended to be extended by layering, rather than revision, so it could just be a new CIP that defines this field, and then gets adopted by tools (if the field is present, they validate that it matches; if it's absent, they display a warning to the user before displaying the contents of the proposal). An argument could be made for modifying CIP100 directly to make it more obvious and apply more social pressure for tools to adopt, but certainly we don't need to do so for all three, since CIP108 and CIP119 layer on top of CIP100. |
EDIT: I updated my original post at the top with an additional requirement to also list all receiving addresses for a "treasury-withdrawal" in the metadata itself. Makes it easy for existing cli tools to simply compare the content of not only the depositReturnAddress with the one that is used for the action, but also all fund receiving addresses in case of a treasury withdrawal. @Quantumplation i agree, it would be enough to enforce it in CIP-0100 so all "child" CIPs would automatically need to adopt it. |
That's not really how CIP-100 works; CIP-119 for example is not a replacement for CIP-100, so it wouldn't "need to adopt" anything. There's not much we can do to "force" something to be adopted; including it in CIP-100 would just create social pressure for existing tools to update (which should be considered a fairly dramatic step in general), and make it discoverable as a "default" for new parties that are only reading that one CIP. I think in 99% of the cases (likely including this one), a new CIP is just fine, and modifying CIP-100 should be an extreme step, only done to correct an outright error that makes the CIP un-adoptable, or to correct a security concern. The latter is why I think it might be appropriate to do it in CIP-100. It may seem like a sticking point, but if we just fall into the habit of updating the past CIPs to add new fields / change definitions / etc. then CIP-100 has completely failed it's goal, and we could do that with a lot less complexity than CIP-100 introduces. i.e. we will have paid for the added complexity of JSON-LD, and then burned the benefits immediately. |
Yes, if done in CIP-0100 or we define a new one with the changes and than basically every tooling jumps onto that CIP must be decided. |
The problem is that a new CIP that adds new fields (that may or may not be required) to CIP 100, 108, 119, 135, etc... How will implementors know where to look? Granted, I am working on a new common vocabulary home for all of these things which will hopefully become one of the canonical sources of truth so the question is does this rise to the level of a "security vulnerability" that warrants directly changing the underlying CIPs and we take this opportunity (while the ecosystem is still nascent) to update/alert all tooling creators to the changes? I like the idea of maybe taking a hash of the |
I agree that in the case of an overlooked security vulnerability, it's likely worth it. I just want to make sure to emphasize that it's against the grain of the design, because I've noticed people's natural inclination seems to be to want to "update" CIPs and create a new version, which is exactly what the design was trying to avoid. As for where implementors go to decide what to implement (outside of security bulletins):
See this post for a big writeup I just did about CIP-100, and how it embraces a stronger philosophy of actual decentralization of metadata, hosting, decision making, etc. As for using the hash, that would be fine with me too, but I doubt that size would be an issue in any case. Keep in mind that the absolute maximum size it could possibly be is 16kb because of the tx size limit, because it has to fit in a transaction 😅 Even if we updated the cost models for plutus v1, v2, and v3, that's only just over 1kb. Using a hash, or the details of the proposal, doesn't solve the "double spend" issue, as I described above, which may be worth adding an expiration date, TxIn, or nonce as well. For example, 10 years from now, when we have evolved the constitution a bunch, someone puts in a proposal to update the constitution back to the one that is currently being voted on today; the metadata attached would be very authoritative and convincing :) |
ok, es expected this blows up to find a solution on a way higher level. guys, keep it grounded on the things we already have. this proposal is an easy implementation which would drastically enhance the "attack vector" of a problem we have not even seen on the chain up until now. the solution works with the tooling we already have and only needs tweeks on how metadata is checked against the gov-state. the "normal" guys does not run specialized indexers on the linux instance. cardano-node and cardano-cli should be enough to get the needed information. not requiring plutus scripts and co just to get the info i want. changes to the node and cli take months now if they even come at all with the open roadmap. i understand you pi that you're looking at this from another angle from an environment pov that has access to all funky data you wanna use, with indexers, databases, db-sync, etc. in the background. i am seeing the problem from the "little guy" pov just having cardano-node and cli running on a small instance to fulfil his voting duty. i like the idea to do a CIP. "Governance Metadata Security Fields", lets try to enhance security with the things we can access right now. tools can use the information or not show it / prevent someone from voting. |
I'm a bit confused by your response for a number of reasons.
The only one that is difficult to achieve simply is specifying an explicit nonce, which I called out above as being a suboptimal solution for exactly that reason. I'm not arguing that we pick one of these solutions over the others and overcomplicate it. I'm saying that likely, at different points in time, different people will feel differently about what the "best" solution is, and so metadata will show up with different "ways" that it's secure, including the existing metadata that has no mechanism for preventing replays. I'm saying that it is too early to know what the "best" approach will be, if there even is one, and we should avoid painting ourselves into a corner by deciding that the "right" thing to do is definitely to use "depositReturnAddress" which is likely insufficient for all the types of governance metadata, etc. I'm saying that we should write down and document the different approaches that you might use to solve this problem precisely somewhere, along with the strengths and weaknesses of each (including documenting non-solutions), and provide some best practices for tools to adhere to, such as how to validate each type, which ones to prefer over others if producing governance metadata, and what to do if multiple are present, if they conflict, or if none of them are present. Doing so acknowledges the messyness of the real world fact that people can publish whatever metadata they want, and that the more we try to decide what people must do, the more we will turn a blind eye to this fact, and the more brittle the tooling ecosystem will become. |
I have never said that what i wrote is the "best" solution. I always focus on pratical solutions. It may also come down to the POV if you wanna have a self contained solution or if you rely on other online tools too as a decision maker. We are on the self page when it comes to "mandate" something, tooling is free to use whatever they think its appropriate to check. I am biased that i see things from the POV as an SPO, true, thats why i seek for solutions that would work on that level too. The overall goal would be to have this all somehow baked into the ledger itself to prevent bad behavior directly on that level. Lets keep that for the future 😄 I think we can agree to put things into a new CIP which adds more specific fields to the existing metadata with more or less user accessable data on the time of verification and the used tooling. Every tool can do its best to present valid information to the user based on its own capability of the design of the env itself its running in. |
Not sure how the workflow to take the The anchorURL and anchorHASH is part of the gov_action itself, like:
So you can't know the hash of it before you put a hash of this info again into the metadata itself that is referenced in the gov action itself 😄 Or do you mean without the last info about the anchorURL/HASH itself? |
I wasn't claiming you believed you had the best solution either, just that going hard on any one solution is probably a mistake. Also, what you posted is the serialized proposal_procedure, not the gov_action |
So including both the
I have to check with the api/cli team, i think there is currently no easy way to get the raw cbor for a gov action on the cli. But that could be maybe added to the new |
The |
That are the accounts to receive payout from the treasury withdrawals, not the rewardAccount that receives the depositAmount. Its called reward_account in the proposal. |
Ah, I see. I was thinking you meant the address that the treasury withdrawal was paid to, which wouldn't apply to all governance actions. Let me think for a bit, I'm on the fence about whether both are needed |
Let me first point everybody to this thread here:
Replay Vulnerability in Governance Action Metadata
Thanks to @Crypto2099 @Quantumplation @Ryun1 for the inputs.
In short: With the upcoming governance actions like treasury withdrawals there will be imposers to try and trick voters to vote for an action that has stolen/copied the metadata.
My proposal consists of a few changes/additions that makes it more unlikely that it would go thru undetected and to keep it managable also in environments that are not timesynced or that depend on the current slotnumber of the chain.
Needed additions in CIP100 and its childs (CIP108/119/etc)
1 - Add an additional field "depositReturnAddress"
A good indicator for the owner/submitter of an action is the depositReturnAddress (StakeAddress). Why? Because the 100kADA deposit amount are paid back to this address after the action got enacted/refused/timedout.
Therefore a new field should be included within the
body
to represent this address. f.e."depositReturnAddress": "stake1xxxxxx"
The deposit return StakeAddress is known to the author before the submit or the signing process. Its not slotnumber dependent it can be done in unsynced offline environments too. There is no timelimit on such a data, no need to submit the metadata within a given timeframe. It makes it easy to compare the set StakeAddress with the one in the action itself. No need to query other databases to figure out the slotnumber when the action was submitted or removed.
This alone is not enough, we also need to make sure that the body was not modified by a potential imposer at all. For that we also need point 2.
1b - Include all receiving addresses of a treasury withdrawal within the metadata
As @Crypto2099 pointed out, the treasury withdrawal actions are most likely the ones we have to take most care of.
So, for a treasury withdrawal we can than also require that all the Addresses that are supposed to receive treasury funds via that action, must be included in an extra array and listed in the metadata itself.
Again to bake this into the canonized body hash signature, we need the next step.
2 - Make the authors signature mandatory
In order to detect a modified
body
content an so change in the canonized hash, a signature is mandatory.We can discuss which kind of action metadata must contain at least one signature, like leaving it open for info-actions. But for actions like a hardfork-initation, committee-update, no-confidence and especially treasury withdrawal we need to have a signature as a must.
The used key for the signature is open to the choice of the author. It can be some key that is already public and known by the chain, or a totally different one.
There is no change needed in existing tooling that provide authors signing already. The important new information is in the new
depostiReturnAddress
field within thebody
Signing via the
CIP-0008/0030
method should be rolled out to all governance metadata content. TheauthorWitnessAlgorithm
should also be renamed intoCIP-0030
for those kinds of signatures, to make sure everyone uses the established set of parameters in the signing/verification process we already know from the CIP-0030 message-signing implementations. These are:There should be a way for DReps, SPOs and the CC-Members to try to verify the identity of the proposer. For that we need the next step.
3 - Provide an identity entry to make the verification possible
To make it somehow possible for the voters (DReps, SPOs and CC-Members) to verify the identity, there should be at least one
Identity
entry/link (we have those kinds already) which points to a source of truth to compare the usedpublicKey
of the signature(s). We could also do this vai anOther
entry.Steps to verify the used metadata
depositReturnAddress
within thebody
which is identical to the one that is set to be used in the governance action itself. If not -> invalid metadata -> voters should not voteIn case someone really tries to impose someone else by using the same metadata link or just copy and paste it as a whole, it also means that such an imposer used the same depositReturnAddress for the action proposal. So the deposit amount of 100kADA are than already lost and on its way to the original owner of the metadata. Its highly unlikely that someone would do this intentionally imo.
In case there is such an "imposer" action on the chain, the
Identity
entrie(s) come into play. These still point to the original destination of the original author. So the original author can f.e. host a list of submitted actions ids on there, or simply deny that he/she has submitted an imposer action. In such cases, the voters can deny to vote on such an action and it can also be marked as "scam" on the various platforms/explorers/social-channels.Adding also als receiving addresses for a treasury withdrawal within the metadata itself makes it basically impossible for an imposer to get funds.
Overall, its a very simple method to implement these enhancements without the need to host additional services on and/or offchain to track actions via nonce values, etc.
The text was updated successfully, but these errors were encountered: