Ref predictability

Would you suggest passing ref to the frontend or should I create an id field that has uuid and use that instead? but then that would be redundancy because you’ll have two fields that you consider unique/primary keys…

I asked this because we created a web app in the past and had a team of “security specialist/white hat hackers" check the app for vulnerability and this was one of their concerns:

session ID values for database entities were assigned by using a method that was predictable. This could leave the application open to direct object or session prediction attacks. When an object is created in MongoDB, a driver is used to generate an _id field automatically. These values, if leaked, can be used to derive information about the internal state of the database, and could be used to predict additional id values, including those which are not directly exposed by the interface. By default, this value is comprised of the following hexadecimal encoded values:
• Unix Epoch/Timestamp (4 bytes)
• Machine ID (3 bytes)
• Process ID (2 Bytes)
• An incremental counter (3 Bytes)
An unauthenticated attacker could potentially determine the session identifier for other users, and use this knowledge to gain access to their session. Additionally, they may be used to obtain illegitimate access to this data.

Conclusion: There’s no choice but to expose the primary key to the frontend.

What are you calling “primary key” here? The Ref? Just not typically referred to as such for Fauna, so I want to make sure.

Someone like @ben would need to confirm the (un)predictability of the ref.id value.

But I’ll also note you could come up with your own algorithm and save your own special ID in as the ref.id.

q.Create(
  q.Ref(q.Collection('SomeCollection'), YOUR_ID),
  {
    data: {  name: 'Something'   }
  }
)

where YOUR_ID is a stringified 64-bit integer.

Other caveat: If using ABAC roles, history_write permission is required for the user or function

Yes, I think ref in fauna and primary key in MySQL are about the same and serves the same purpose, locating a particular record from a collection/table.

I came from MySQL background, so I’m sorry about the incorrectness of my analogy…

essentially, is it okay to use this ref.id in URLs and requests like

post {
  targetRef: userId
}

where the targetRef could later be used like so:

Get(Ref(Collection('users'), userId))

Along with the others like Update or even Replace, but I guess I don’t have a choice.

Refs are not secure, are not intended to be secure, and (probably) will never be secure. Knowing when a ref was generated narrows down the space of values significantly (although guessing one isn’t free). If you want to control who can use a ref, we have a whole security system for that. If you rely on the non-discoverability of refs for security your application will be compromised by a determined attacker.

I just read that article. I’m not sure what it is you are asking or trying to achieve. The article says “don’t expose internal identifiers in case you need to re-key”. Ok. That’s fine advice. You can expose whatever you’d like your users and get back to refs via an index. Yes there is redirection, yes there is extra data. In return you get some flexibility.

This conclusion doesn’t seem to follow to me? Other than maybe “I have to do this because I don’t want the indirection”. Which is fine, but that’s a self-imposed constraint.

See above.

It’s a good point that while the ref.id of a UserSession document (for example) might be discoverable, it would have to be used in conjunction with a Key or a Token with sufficient privileges to be of any use.

I guess the imperative, then, is to make sure server Keys and user Tokens have appropriately limited privileges and are kept safe.

Well in my case I would really only be using the ref.id to get records, for example, when you edited the post, which post was that? I would answer that question by using the ref.id, also which user is logged in that’s trying to make this request? I would also use ref.id for that but with JWT, I guess the only way as stated in the article above, is to just make the endpoints as secure as possible.

What’s the worst that could happen if the ref.id is predictable? other than them trying to edit someone else’s post, which then can be checked out by checking data ownership, that is, do you actually own this post and can you actually do that to this post? other than that, JWT should take care of the sessions, I can’t think of anything else they could do with the ref.id.