Skip to content

Conversation

@anishnaik
Copy link
Contributor

No description provided.

anishnaik added 29 commits July 5, 2022 17:54
1. Added a pallet that does not comply with Verify first, write last principle.
2. Added a pallet that has an integer overflow / underflow
3. Added README.md for both pallets with almost no content
1. Renamed transfer.rs to pallet-overflow.rs to comply with substrate naming convention
2. pallet-overflow.rs will compile in substrate-node-template and the bug is exploitable
TotalSupplyDefaultValue is not the actual total supply but instead the default one. So changed comment to note that accordingly.
This pallet is no longer insecure after polkadot-v0.9.25. However, it is still considered best practice so I'm including it in here.
This pallet demonstrates the difficulty in creating proper weight functions. If the length of useful_amounts is zero, the weight for DoWork is zero.
This also demonstrates the need for benchmarking.
Decided to add an error type so that `ensure!()` can be used to cause the out-of-bounds check
@anishnaik anishnaik requested a review from 0xicingdeath August 15, 2022 20:27
@anishnaik anishnaik requested a review from montyly August 15, 2022 20:27

Weights and transaction fees are the two main ways to regulate the consumption of blockchain resources. The overuse of blockchain resources can allow a malicious actor to spam the network to cause a denial-of-service (DoS). Weights are used to manage the time it takes to validate the block. The larger the weight, the more "resources" / time the computation takes. Transaction fees provide an economic incentive to limit the number of resources used to perform operations; the fee for a given transaction is a function of the weight required by the transaction.

Weights can be fixed or a custom "weight annotation / function" can be implemented. A weight function can calculate the weight, for example, based on the number of database read / writes and the size of the input paramaters (e.g. a long `Vec<>`). To optimize the weight such that users do not pay too little or too much for a transaction, benchmarking can be used to empirically determine the correct weight in worst case scenarios.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the other issue, we explain how it works, not what the issue is

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


However, if the length of the `useful_amounts` vector is zero, the weight to call `do_work` would be zero. A weight of zero implies that calling this function is financially cheap. This opens the opportunity for an attacker to call `do_work` a large number of times to saturate the network with malicious transactions without having to pay a large fee and could cause a DoS attack.

One potential fix for this is to set a fixed weight if the length of `useful_amounts` is zero.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or a static fee? Like static fee + len * price. This would reduce the complexity by having no branching condition

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the issue with this is that if len == 1 then you have to pay static_fee * 2 where i specified the weight function to be static_fee * length. Although the branching is not ideal, I think it represents the fix a bit more clearly. what do you think?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also leaning towards branching, even if it's not the best looking solution.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@0xicingdeath
Copy link

@anishnaik pallets lgtm


However, if the length of the `useful_amounts` vector is zero, the weight to call `do_work` would be zero. A weight of zero implies that calling this function is financially cheap. This opens the opportunity for an attacker to call `do_work` a large number of times to saturate the network with malicious transactions without having to pay a large fee and could cause a DoS attack.

One potential fix for this is to set a fixed weight if the length of `useful_amounts` is zero.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also leaning towards branching, even if it's not the best looking solution.

@montyly montyly merged commit 7d5cc5a into master Nov 3, 2022
@montyly montyly deleted the nss-substrate branch November 3, 2022 14:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants