-
Notifications
You must be signed in to change notification settings - Fork 47
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
Only allow crypto-safe hashes to be used in CIDs #40
Conversation
validate.go
Outdated
mh.ID: true, | ||
|
||
// insecure | ||
mh.SHA1: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will, of course, break the git plugin.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mmm, youre right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As suggested by @magik6k we should probably set SHA1 as secure, but add the check described here: multiformats/go-multihash#57 to detect insecure hashes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@whyrusleeping this would still break the git plugin, but only in the very rare case when the content so happens to hash to one of the insure hashes, or am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@whyrusleeping yep to what? Am I missing something or will this still break the git plugin in the very rare case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. This will still break the git plugin in that case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From IRC (slightly edited for clarity):
whyrusleeping: juan wants this to make it into the next release
kevina: whyrusleeping: I vote we allow "sha1" for now to avoid breaking the git plugin until we think of a better solution
whyrusleeping: yeah, maybe.
whyrusleeping: I think most of the concern we want to fix here is preimage attacks
whyrusleeping: and theres no preimage attack for sha1
whyrusleeping: just a collision
kevina: whyrusleeping, stebalien: so let's allow it with a note that it will eventually be marked insure once we implement something like /ipfs-insecure/
return ErrPossiblyInsecureHashFunction | ||
} | ||
|
||
if pref.MhType != mh.ID && pref.MhLength < minimumHashLength { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather check if the hash length >= the default. Alternatively, make goodset
map hash function to minimum length (where we'd use -1 for ID).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hrm... I still want to allow some truncation. Ethereum truncates a lot of things down to 20 bytes (from 32). I can go with a mapping, but maybe default 20 and have a special cases for anything else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should set this per hash as @Stebalien suggested to allow a little more flexibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@whyrusleeping WTF? That's 80 bits of security! No!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Stebalien hold up, 8 * 20 is 160.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hash functions have bits/2 security for collision attacks (I assumed this was a general property and applied to preimage attacks but it turns out this is due to the birthday attack and only applies to collisions; thanks for catching me on that).
However, unlike eth, we do care about collisions attacks. Eth doesn't because it only uses 160 bit hashes for account IDs so, at most, you can steal money from yourself by creating two colliding keys.
Now, whether or not a birthday attack against an 160 bit hash will likely be feasible in the foreseeable future is an interesting question (there are time/memory tradeoffs one can make to reduce the otherwise obscene memory complexity) but, if our answer is no, we should just truncate all of our CIDs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Stebalien the whole point of multiformats in general is to allow users to use what fits their needs best. We should continue using 256bit hashes for our important things, but shouldnt begrudge users who want to use 160bit hashes. I'm primarily concerned about preventing pre-image attacks, general collision birthday problem attacks are still a concern, but less so for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I've come to agree on this. It still annoys me, but we don't have much of a choice.
If we ever need to set different minimum lengths for different hashes, we can change that later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, users can implement custom DAGServices for validating additional properties (we may want won for unixfs that has stricter requirements).
@whyrusleeping I can work with this API if in future we want to swap this out for multihash-secruity-bits. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
cid.go
Outdated
return &Cid{ | ||
func NewCidV0(mhash mh.Multihash) (*Cid, error) { | ||
if mhash[0] != mh.SHA2_256 && mhash[1] != byte(mh.DefaultLengths[mh.SHA2_256]) { | ||
return nil, errors.New("NewCidV0 accepts only SHA256 hashes of standard length") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would pull this error message out into a global
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 minor nitpick, LGTM
@@ -51,6 +51,8 @@ var ( | |||
// ErrInvalidEncoding means that selected encoding is not supported | |||
// by this Cid version | |||
ErrInvalidEncoding = errors.New("invalid base encoding") | |||
|
|||
ErrCid0OnlySHA256 = errors.New("cidv0 accepts only SHA256 hashes of standard length") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ErrCidV0Format
?
This comment has been minimized.
This comment has been minimized.
This will likely require a repo migration, to cleanly upgrade as I suggested in ipfs/kubo#4766. |
Is this going to be merged, or is it blocked by something? |
we implemented a workaround in go-ipfs for now. This change could brick peoples repos if they already had bad hashes in them, so we removed the ability to create bad hashes, we're working on a migration to remove any existing bad hashes, and then once that is done, we can merge this. |
@whyrusleeping @Stebalien is the only hold of this my repo migration? Or is this blocked on anything else. In particular how quickly can go-ipfs update a new |
@kevina as far as I know, nothing is blocking a go-cid update. I can do it in a few hours with gx-workspace and a stress ball. |
return ErrPossiblyInsecureHashFunction | ||
} | ||
|
||
if pref.MhType != mh.ID && pref.MhLength < minimumHashLength { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I've come to agree on this. It still annoys me, but we don't have much of a choice.
If we ever need to set different minimum lengths for different hashes, we can change that later.
mh.KECCAK_512: true, | ||
mh.ID: true, | ||
|
||
mh.SHA1: true, // not really secure but still useful |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we restrict this to git only somehow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't necessary agree with this unless we are 100% sure SHA-1 are not used anywhere outside of git. Otherwise we could break things, badly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only reason we want to call SHA1 a "secure" hash because we want git compatibility. SHA1 is not a secure hash function. I know there are no other existing IPLD formats using SHA1 by default. If users have chosen to use SHA1 with IPLD, well, I'm not exactly sympathetic.
If we find some existing merkledag format that uses SHA1 and want to add compatibility, we can add that to the list later.
Note: I'm fine pushing this patch through as-is and fixing this later as this patch is a strict improvement.
return ErrPossiblyInsecureHashFunction | ||
} | ||
|
||
if pref.MhType != mh.ID && pref.MhLength < minimumHashLength { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, users can implement custom DAGServices for validating additional properties (we may want won for unixfs that has stricter requirements).
@whyrusleeping @Kubuxu is it okay if I take over this p.r.? For now I pushed my work on #50. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Blocking as I have outstanding changing on #50. Once I get the all clear to take over this P.R. I will unblock.
This PR never landed and got out of date, |
This is a WIP solution to ipfs/kubo#4371