why
- you want to allow User to reference Keys in your KV store
and
- you don’t want to
- expose the literal Keys to User (avoids some issues with Enumeration Attacks, leaking internal naming scheme)
- pass User-provided Keys directly to KV queries (avoids issues with malformed/malicious input)
- store a mapping of “internal” Keys to “external” (stateless, stable, portable)
how
via hashing (uses md5
for wide support and simplicity)
import crypto from 'crypto'
const make_kvsafe_stable_key_for_ns = function (str_ns, x) {
const hash = crypto.createHash('md5').update(x).digest('hex')
const out_key = str_ns + ':' + hash
return out_key
}
const user_provided_key = 'aUserProvidedKeyThatMapsToAnInternalKeyInYourKVStore'
const literal_kv_key = make_kvsafe_stable_key_for_ns('UserKeys', user_provided_key)
//{ literal_kv_key: "UserKeys:3ab3e0255e4495de92e95f1ea08a0420" }
- you can now use
literal_kv_key
in your KV queries safely *- i.e. you know it won’t be excessively long or contain unexpected characters
- a User might still guess what other Keys exist, but at least their access could be limited to your chosen namespace (bring your own Validation and Access Control schemes)
- you can change
UserKeys
to any namespace you want, could even be unique per User - ⚠️ WARNING ⚠️
- assumes there won’t be issues with hashing collisions (likelihood and severity depends on your specific use case)