Create a single use link - web-services

I'm writing a database front end for a website. Next to the records I want to include a link likes this:
Record 1 - [Add][1] [Edit][2] [Delete][3]
But I want to protect these links from being used more than once. My thinking is to pass a hash value then store a list of valid HASH values in a table somewhere and only process requests with valid hash values. Is there a better way to do is?
Update: The answer to this question led me to ask this question: What is the difference between a "nonce" and a "GUID"?. Why exactly would you use a nonce instead of a GUID?

Your idea is correct, except that you should use cryptographically secure random bytes (a "nonce") instead of a hash.

Related

User Friendly Unique Identifier For DynamoDB

In my DynamoDB table named users, I need a unique identifier, which is easy for users to remember.
In a RDBMS I can use auto increment id to meet the requirement.
As there is no way to have auto increment id in DynamoDB, is there a way to meet this requirement?
If I keep last used id in another table (lastIdTable) retrieve it before adding new document, increment that number and save updated numbers in both tables (lastIdTable and users), that will be very inefficient.
UPDATE
Please note that there's no way of using an existing attribute or getting users input for this purpose.
Since it seems you must create a memorable userId without any information about the user, I’d recommend that you create a random phrase of 2-4 simple words from a standard dictionary.
For example, you might generate the phrase correct horse battery staple. (I know this is a userId and not a password, but the memorability consideration still applies.)
Whether you use a random number (which has similar memorability to a sequential number) or a random phrase (which I think is much more memorable), you will need to do a conditional write with the condition that the ID does not already exist, and if it does exist, you should generate a new ID and try again.
email address seems the best choice...
Either as a partition key, or use a GUID as the partition key and have a Global Secondary Index over email address.
Or as Matthew suggested in a comment, let the users pick a user name.
Docker container naming strategy might give you some idea. https://github.com/moby/moby/blob/master/pkg/namesgenerator/names-generator.go
It will result in unique (limited) yet human friendly
Examples
awesome_einstein
nasty_weinstein
perv_epstein
A similar one: https://github.com/jjmontesl/codenamize

Regularized Dynamo Secondary Keys?

I am working with a data set that has a secondary index with a sort key that ultimately has user entered information in it. For the sake of the question, consider it a "postal address" field. This model is to permit quick queries of this data for a particular postal address.
Because it is user entered I am finding myself wanting to regularize it before using it as a key. For instance, by stripping spaces and making it a common case. My thinking being that if someone made a trivial capitalization or spacing error it wouldn't be identified as a different address.
Is this a pattern that people typically do if they are creating a key on user entered data? Are "user entered keys" considered harmful? Any obvious pitfalls?
Just make sure you get your normalization function right. Simply stripping spaces might not be a great idea. For example, Hight Railroad and High Trail Road might both normalize to hightrailroad which probably isn't what you want. Instead, you might want to replace one or more consecutive spaces with a single dash or something along those lines.
If you get the normalization right, you should be fine. Others have mentioned vulnerabilities related to overwriting data but you said that this is a Global Secondary Index. You can't write to a GSI so you don't need to worry about this. Also, the user entered data is the sort key. As long as you control the hash key, you will be fine.
One thing I would be cautious of is the data distribution. Any time there is a user-influenced key whether it be direct user input or a side effect of a user action such as a timestamp, you need to take care to avoid unbalanced data distributions which could lead to hot shards and/or throttling

Unique alpha-numeric string from a unique integer? (masking IDs in a game server?)

I have a multiplayer mobile game out in the wild, it's backed by a sql database. Each game gets an ID which is just an auto-increment field. I can look up a game with a url like:
http://www.example.com/gameId=123
That url is not visible to players at the moment, but I was thinking of displaying it so users can invite friends and let non-players look on in the game as they play (through a browser - at the moment everyone plays through a native app).
But the fact that I'm putting the game ID out there in the open seems like a bad idea. If someone guessed an endpoint for say deleting a game, they could do bad stuff knowing the ID (of course my endpoints are protected by user auth, but still).
Do most services mask IDs of this sort, should I send out a url like:
http://www.example.com/gameId=maskedIdAbc
and then my game server has to translate that ID into the corresponding ID in my database?
Not sure if that's overkill. If not, what's a good way to generate a unique alpha-numeric string based off a unique integer?
Thanks
Why not change the primary key of the game from an incremental ID to a GUID? The game is out in the wild but you should be able to get there in a number of steps. Add the Guid as a Field and allow games to be looked up either by ID or GUID. Update your clients to use the GUID, phase out the ID, and finally change the primary key to be the GUID.
You could hash the int, or even use the hex, but its breakable. Better to implement a complete fix, if you don't want to use a GUID you could implement your equivalent random characters that you store against each db record but why go to the trouble when GUIDs are usually Nativity supported by databases.
If range of the integers is not big, you may define tabble with unique, random alpha-num strings. I think it's the best way.
I has a similar situation and did not want to use the gameID (using your example here) in the url, as someone can use any number. I can still use the ID's, but need to add additional checking for authorizing the users.
You could use UUID to generate gameID's but I see few problems with this;
- non numeric ID will have an impact on the performance
- if this is the primary key and want to use it as FK on other tables, space
What I did;
In addition to gameID in my table, I added another column WebGameID varchar (32). After the game ID was generated, updated the WebGameID = MD5(gameID). This will be a unique 32 char string for the specific gameID. With this I was able to use gameID for internal keys and FK's ad only use WebGameID for the URL for limiting user manipulation.

Google Plus user id representation technique

What kind of technique does use Google Plus to generate users' unique ids?
Example
https://plus.google.com/102766325060234825733/posts
You can only assume that they are randomly generated ID's that are large enough to be generated non-sequentially with sufficient entropy.
The ID's are too big to be stored in a bigint field which is interesting, again probably due to the required entropy and non-sequential requirement (so that nothing can be inferred by comparing userid's).
A simple encryption of a serially generated number, with a secret key can be used to generate the IDs. It can be a 1 way hash, or a decryptable encryption.
The reason for not using serial numbers directly is obvious: You can easily guess userids of other users on the network, which can result in Bots scraping the content of the network.

Suitable alternative to CryptEncrypt

We have a situation in our product where for a long time some data has been stored in the application's database as SQL string (choice of MS SQL server or sybase SQL anywhere) which was encrypted via the Windows API function CryptEncrypt. (direct and de-cryptable)
The problem is that CryptEncrypt can produce NULL's in the output, meaning that when it's stored in the database, the string manipulations will at some point truncate the CipherText.
Ideally we'd like to use an algo that will produce CipherText that doesn't contain NULLs as that will cause the least amount of change to the existing databases (changing a column from string to binary and code to deal with binary instead of strings) and just decrypt existing data and re-encrypt with the new algorithm at database upgrade time.
The algorithm doesn't need to be the most secure, as the database is already in a reasonably secure environment (not an open network / the inter-webs) but does need to be better than ROT13 (which I can almost decrypt in my head now!)
edit: btw, any particular reason for changing ciphertext to cyphertext? ciphertext seems more widely used...
Any semi-decent algorithm will end up with a strong chance of generating a NULL value somewhere in the resulting ciphertext.
Why not do something like base-64 encode your resulting binary blob before persisting to the DB? (sample implementation in C++).
Storing a hash is a good idea. However, please definitely read Jeff's You're Probably Storing Passwords Incorrectly.
That's an interesting route OJ.
We're looking at the feasability of a non-reversable method (still making sure we don't explicitly retrieve the data to decrypt) e.g. just store a Hash to compare on a submission
It seems that the developer handling this is going to wrap the existing encryption with yEnc to preserve the table integrity as the data needs to be retrievable, and this save all that messy mucking about with infinite-improbab.... uhhh changing column types on entrenched installations.
Cheers Guys