Skip to content
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

Closed
wants to merge 6 commits into from

Conversation

whyrusleeping
Copy link
Member

@whyrusleeping whyrusleeping commented Feb 22, 2018

This is a WIP solution to ipfs/kubo#4371

validate.go Outdated
mh.ID: true,

// insecure
mh.SHA1: false,
Copy link
Member

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

mmm, youre right.

Copy link
Member Author

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.

Copy link
Contributor

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?

Copy link
Member Author

Choose a reason for hiding this comment

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

yep

Copy link
Contributor

@kevina kevina Feb 23, 2018

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?

Copy link
Member Author

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.

Copy link
Contributor

@kevina kevina Feb 23, 2018

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 {
Copy link
Member

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).

Copy link
Member Author

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?

Copy link
Contributor

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.

Copy link
Member

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!

Copy link
Member Author

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.

Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member

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.

Copy link
Member

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).

@Kubuxu
Copy link
Member

Kubuxu commented Feb 24, 2018

@whyrusleeping I can work with this API if in future we want to swap this out for multihash-secruity-bits.

@ghost ghost assigned Kubuxu Feb 27, 2018
@kevina

This comment has been minimized.

@whyrusleeping

This comment has been minimized.

@kevina

This comment has been minimized.

@Kubuxu

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")
Copy link
Member Author

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

Copy link
Member

@magik6k magik6k left a 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")
Copy link
Member

Choose a reason for hiding this comment

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

ErrCidV0Format?

@kevina

This comment has been minimized.

@kevina
Copy link
Contributor

kevina commented Apr 18, 2018

This will likely require a repo migration, to cleanly upgrade as I suggested in ipfs/kubo#4766.

@kevina kevina changed the title add function to check if a given cid is safe Only allow crypto-safe hashes to be used in CIDs Apr 21, 2018
@hsanjuan
Copy link
Contributor

Is this going to be merged, or is it blocked by something?

@whyrusleeping
Copy link
Member Author

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.

@kevina
Copy link
Contributor

kevina commented Jun 16, 2018

@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 go-cid version considering that it is used almost everywhere and will require a lot of package updates?

@Stebalien
Copy link
Member

@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 {
Copy link
Member

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
Copy link
Member

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?

Copy link
Contributor

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.

Copy link
Member

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 {
Copy link
Member

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).

@kevina
Copy link
Contributor

kevina commented Jun 24, 2018

@whyrusleeping @Kubuxu is it okay if I take over this p.r.? For now I pushed my work on #50.

@kevina kevina added the status/blocked Unable to be worked further until needs are met label Jun 25, 2018
Copy link
Contributor

@kevina kevina left a 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.

@lidel
Copy link
Member

lidel commented Sep 15, 2021

This PR never landed and got out of date,
I am closing it as it is most likely easier to create new one if we ever want to move beyond current solution (blocking at bockstore instead in go-cid – continued in ipfs/kubo#4371 (comment) ++

@lidel lidel closed this Sep 15, 2021
@lidel lidel deleted the feat/safe-hash-whitelist branch September 15, 2021 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status/blocked Unable to be worked further until needs are met status/in-progress In progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants