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

IDs are predictable, should clarify in README #78

Closed
fta2012 opened this issue Apr 15, 2017 · 12 comments
Closed

IDs are predictable, should clarify in README #78

fta2012 opened this issue Apr 15, 2017 · 12 comments

Comments

@fta2012
Copy link

fta2012 commented Apr 15, 2017

I was looking through this project since it's a dependency for something else I was checking out.

I noticed that you are using Math.random(). This is fine but if so you shouldn't claim that the ids are unguessable:

Cuids contain enough random data and moving parts as to make guessing another id based on an existing id practically impossible.

Since Math.random() is not cryptographically secure it's easy to predict the next values. I would remove the two security/secure paragraphs completely and add a warning instead.

EDIT: Just for fun I wrote a proof of concept here that can predict all CUIDs(excluding timestamp portion) after seeing four consecutive ids. It's for node v4/v5 only since they've updated their RNG algorithm but the approach for later versions is similar.

@nealoke
Copy link

nealoke commented Apr 18, 2017

@fta2012 just out of interest, if you can't know the timestamp portion can you ever crack the whole thing?

@fta2012
Copy link
Author

fta2012 commented Apr 18, 2017

You just need to search upwards from the last known timestamp. Also if it's a batch insert the next id is likely to be within the same millisecond as the others.

@ericelliott
Copy link
Collaborator

ericelliott commented Apr 19, 2017

I'm open to a PR, with a caveat. For such an attack to work:

  1. You'd need to be running an old/buggy PRNG
  2. The thing you're searching for would need to be generated by the same client, during the same runtime instance as the known IDs. You'd also need to be able to search the ID space to land on the right millisecond.

Some older apps may be vulnerable to an ID guessing attack.

@fta2012
Copy link
Author

fta2012 commented Apr 19, 2017

The older PRNG is easier but the new one is similarly vulnerable. You need to switch to crypto.getRandomValues if you really want it to be unpredictable.

@ericelliott
Copy link
Collaborator

Agreed. Open to a PR.

@fta2012
Copy link
Author

fta2012 commented Apr 20, 2017

If it's just replacing Math.random with the crypto version it should be a small change. I probably won't get to it so this is up for grabs for anyone who wants to contribute.

@ericelliott
Copy link
Collaborator

The crypto API is not in the browser.

@MarkHerhold
Copy link
Contributor

I don't think that cuids being predictable is necessarily a bad thing.

@ericelliott
Copy link
Collaborator

@MarkHerhold For some apps, it could be a security risk.

@seangenabe
Copy link

FYI crypto is already available in most browsers.

@ericelliott
Copy link
Collaborator

ericelliott commented Aug 31, 2017

I'm open to a PR that uses the crypto API if it's available. Note that it is available in IE11 with the ms prefix, so fallback to that if you can.

In Node, we'll have to use the Node crypto API to avoid this vulnerability... note that it is NOT compatible with universal JS, so we'll have to continue to use different builds for Node and Browsers. We could write a facade around the different APIs using a getRandomValues() function and import a different implementation depending on the build.

@ericelliott
Copy link
Collaborator

This should be fixed now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants