coral-xyz / sealevel-attacks Goto Github PK
View Code? Open in Web Editor NEW☠️ Common Security Exploits and Protections on Solana
☠️ Common Security Exploits and Protections on Solana
I think that the following snippet from 7-bump-seed-canonicalization
let (address, expected_bump) =
Pubkey::find_program_address(&[key.to_le_bytes().as_ref(), &[bump]], ctx.program_id);
implies that expected_bump != bump
.
The reason is that while the Pubkey::create_program_address
expects the bump
as the last item in the seeds
argument, the find_program_address
would just use it as another seed and result in a different bump. (See also find_program_address, and create_program_address).
So I think this should be changed to
let (address, expected_bump) =
Pubkey::find_program_address(&[key.to_le_bytes().as_ref()], ctx.program_id);
Each example contains 3 folders: insecure
, recommended
, and secure
. It might be the alphabetical ordering, but it isn't quite clear which folder is "best".
One interpretation is that recommended
means the minimum recommendation and that secure
is better. The other is that secure
is the minimum required to stop the attack but recommended
is better.
Is recommended
> secure
or is secure
> recommended
.
edit: lol I'm not looking for an answer, I'm looking for a discussion whether it's just me having these thoughts and on how to make it more clear (if needed). My initial thoughts are adding a number to the folder name, or replacing secure
with minimum
, or a simple note on the README.md.
In this example, the account was deserialized with the SplTokenAccount util and owner check is performed after. Why is this example insecure other than not deserializing with the Anchor TokenAccount struct?
I believe there are couple issues with the secure example for 4-initialization attack.
discriminator
field in the User
struct is a misleading field name. It is not used in the code as a discriminator, in the sense that type-cosplay calls for, ie, to uniquely differentiate accounts. Further, a bool
cannot even be used as a proper discriminant. It seems like the field should be renamed to is_initialized
, because that is what it seems like it is being used for, an initialization flag.discriminator
field is indeed intended to be used as an "initialization flag", there should not be a boolean NOT operator on line 13. If user.discriminator
is false, ie, uninitialized, then it should be initialized. However, the logic dictates that if it is false, then the code returns an error. If it is true (initialized), then it is reinitialized. This is the opposite of what we want I believe.Sorry if I am being dense, but what are the differences between the subdirectories "recommended" and "secure"? (Presumably, "secure" code would also be "recommended"?)
We should have some examples showing how to implement mathematical operations using checked_add, checked_sub, saturating_pow etc
I believe the secure is missing the seeds and bumbs account checks on WithdrawTokens
@armaniferrante we should add one/two liner comments or doc comments on every example
explaining
unsafe - why it's unsafe
recommended - why this practice is recommended
secure - why it's secure.
It'll definitely help new repo visitor understand the moto behind the different approaches and will help get deeper understanding overall.
In the ui tests, for example for recommended: https://github.com/project-serum/sealevel-attacks/blob/master/programs/1-account-data-matching/recommended/src/lib.rs, it refers to ProgramResult
but doesn't import it.
Need to import it somehow like: use anchor_lang::solana_program::entrypoint::ProgramResult;
. This goes for all ui tests for this particular attack.
Sorry I don't quite see what the purpose of the force_defund()
instruction is or how it makes it secure in contrast to insecure-still-still
. From its naming it seems like it's supposed to force the defunding of closed accounts? If so, should it be
if discriminator != CLOSED_ACCOUNT_DISCRIMINATOR
Is the fact that it's a different instruction supposed to demonstrate that the only way to force the defunding of a closed account is to start a new transaction that calls force_defund()
after close()
has been called in a previous transaction (because otherwise users are free to append TransferLamports
instructions to the same transaction in which close()
was called)?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.