Trying to pull from a redis cache - javascript

I am new-ish to programming and am developing an app that has an email verification step. I'm hoping to take information from input fields, save it in a cache, then pull it from the cache when users get to verfication page through a UUID in the email.
My steps so far are to:
Save the username and password they enter in the registration page to a redis cache called 'users' with username, password, and UUID keys and values
Set a cookie for the user containing the UUID so that when they return I can pull the username and password from cache based on a UUID-based query from the cookie. (This is where I am having trouble, as I can't figure out how to search the redis cache by a field value).
Once the username and password can be accessed via the cache with the UUID, I will be inserting them into a Postgres DB.
Any thoughts? Or links to good redis documentation?
Another thought is, should I be using a hash rather than a set?
Cachers to the rescue please!

You don't search a redis server, you access a key. This is a critical piece of understanding. Also, as you aren't using it as a cache it can be useful to not refer to it as one.
The trick to designing your redis data structure is to determine how you will use it when you pull data from it and store it that way, not store then figure it out.
Here is how, if I had to, I'd structure what you are doing in redis:
For a given UUID. Create a Redis hash with the UUID as the name of the hash. The hash will have the key/value pairs (or members) of username, password (please at least store it encrypted), and any other key/value pairs you use in the session.
This allows you to access precisely the data you are after, and you can look it up with the UUID. Basically the UUID identifies a particular collection of data.

Related

Role value in JWT payload

I am trying to setup a json web token based api authentication that will be used for various role based authorization in APIs.
Can I keep role value as a payload in Tokens ? Is is Safe ? If Not What is the what to save role like admin or user or merchant etc after successful login ?
Yes, you can safely store whatever you like in a JWT, if you use the right type of token and name your custom field properly.
If the information is public and you just want to make sure the users can't change it to cheat, then simply use JWS and verify the token's signature. You can even do this client-side if the signature algorithm is based on a public key (RSA or ECDSA).
If the information to be stored on the token is not to be read by users, you can set up JWE (encrypted) tokens.
Your "role" field should be named according to the spec, using a collision-resistant name such as "com.yourdomainname.role" unless you are certain that your tokens will never be used by another client which also needs a "role" field with different semantics.

firebase multi-location updates user authentication and database

I have a Form to signup new User with email, password, full name and phone number.
I can use firebase.auth().createUserWithEmailAndPassword to create new user if successfully. Then I use firebase.database().ref('users/..').set(..)to save fullname and phone number to firebase database.
But If the saving processing to database occur error (By rule write:false for example), I STILL have an user Identifier created in User Authentication. So an user exist without phone number and full number.
How can I can multi-location insert user authentication and database. If one of these two failed firebase auto reject inserting new identifier and inserting into database. (The processing only return success if both success).
There is no way to make the combined Auth and Database operation atomic. If you want to be atomic, you should use only one service: the database or authentication.
To make this atomic you could pass username, password, full name, and phone number to a HTTP function in Cloud Functions. This then creates a user with the email and password, then writes the full name and phone number to the database.
But note that this still isn't guaranteed to be atomic: the same glitch that you're anticipating on the phone, could happen on the server. While chances are much smaller, there's no guarantee.
This means you'll need to make sure that your code is robust enough to handle cases where the full name and phone number are missing. And if you need to do that in the server-side case, it will also work the same if you'd leave the cross-product code on the client.

App API design advice specifically around security

I'm building an app and would like some feedback on my approach to building the data sync process and API that supports it. For context, these are the guiding principles for my app/API:
Free: I do not want to charge people at all to use the app/API.
Open source: the source code for both the app and API are available to the public to use as they wish.
Decentralised: the API service that supports the app can be run by anyone on any server, and made available for use to users of the app.
Anonymous: the user should not have to sign up for the service, or submit any personal identifying information that will be stored alongside their data.
Secure: the user's data should be encrypted before being sent to the server, anyone with access to the server should have no ability to read the user's data.
I will implement an instance of the API on a public server which will be selected in the app by default. That way initial users of the app can sync their data straight away without needing to find or set up an instance of the API service. Over time, if the app is popular then users will hopefully set up other instances of the API service either for themselves or to make available to other users of the app should they wish to use a different instance (or if the primary instance runs out of space, goes down, etc). They may even access the API in their own apps. Essentially, I want them to be able to have the choice to be self sufficient and not have to necessarily rely on other's providing an instance on the service for them, for reasons of privacy, resilience, cost-saving, etc. Note: the data in question is not sensitive (i.e. financial, etc), but it is personal.
The user's sync journey works like this:
User downloads the app, and creates their data in the process of using the app.
When the user is ready to initially sync, they enter a "password" in the password field, which is used to create a complex key with which to encrypt their data. Their password is stored locally in plain text but is never sent to the server.
User clicks the "Sync" button, their data is encrypted (using their password) and sent to the specified (or default) API instance and responds by giving them a unique ID which is saved by the app.
For future syncs, their data is encrypted locally using their saved password before being sent to the API along with their unique ID which updates their synced data on the server.
When retrieving synced data, their unique ID is sent to the API which responds with their encrypted data. Their locally stored password is then used to decrypt the data for use by the app.
I've implemented the app in javascript, and the API in Node.js (restify) with MongoDB as a backend, so in practice a sync requests to the server looks like this:
1. Initial sync
POST /api/data
Post body:
{
"data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd..."
}
Response:
{
"id":"507f191e810c19729de860ea",
"lastUpdated":"2016-07-06T12:43:16.866Z"
}
2. Get sync data
GET /api/data/507f191e810c19729de860ea
Response:
{
"data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd...",
"lastUpdated":"2016-07-06T12:43:16.866Z"
}
3. Update synced data
POST /api/data/507f191e810c19729de860ea
Post body:
{
"data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd..."
}
Response:
{
"lastUpdated":"2016-07-06T13:21:23.837Z"
}
Their data in MongoDB will look like this:
{
"id":"507f191e810c19729de860ea",
"data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd...",
"lastUpdated":"2016-07-06T13:21:23.837Z"
}
Encryption is currently implemented using CryptoJS's AES implementation. As the app provides the user's password as a passphrase to the AES "encrypt" function, it generates a 256-bit key which which to encrypt the user's data, before being sent to the API.
That about sums up the sync process, it's fairly simple but obviously it needs to be secure and reliable. My concerns are:
As the MongoDB ObjectID is fairly easy to guess, it is possible that a malicious user could request someone else's data (as per step 2. Get sync data) by guessing their ID. However, if they are successful they will only retrieve encrypted data and will not have the key with which to decrypt it. The same applies for anyone who has access to the database on the server.
Given the above, is the CryptoJS AES implementation secure enough so that in the real possibility that a user's encrypted data is retrieved by a malicious user, they will not realistically be able to decrypt the data?
Since the API is open to anyone and doesn't audit or check the submitted data, anyone could potentially submit any data they wish to be stored in the service, for example:
Post body:
{
"data":"This is my anyold data..."
}
Is there anything practical I can do to guard against this whilst adhering to the guiding principles above?
General abuse of the service such as users spamming initial syncs (step 1 above) over and over to fill up the space on the server; or some user's using disproportionately large amounts of server space. I've implemented some features to guard against this, such as logging IPs for initial syncs for one day (not kept any longer than that) in order to limit a single IP to a set number of initial syncs per day. Also I'm limiting the post body size for syncs. These options are configurable in the API however, so if a user doesn't like these limitations on a public API instance, they can host their own instance and tweak the settings to their liking.
So that's it, I would appreciate anyone who has any thoughts or feedback regarding this approach given my guiding principles. I couldn't find any examples where other apps have attempted a similar approach, so if anyone knows of any and can link to them I'd be grateful.
I can't really comment on whether specific AES algorithms/keys are secure or not, but assuming they are (and the keys are generated properly), it should not be a problem if other users can access the encrypted data.
You can maybe protect against abuse, without requiring other accounts, by using captchas or similar guards against automatic usage. If you require a catcha on new accounts, and set limits to all accounts on data volume and call frequency, you should be ok.
To guard against accidental clear-text data, you might generate a secondary key for each account, and then check on the server with the public secondary key whether the messages can be decrypted. Something like this:
data = secondary_key(user_private_key(cleartext))
This way the data will always be encrypted, and in worst case the server will be able to read it, but others wouldn't.
A few comments to your API :) If you're already using HTTP and POST, you don't really need an id. The POST usually returns a URI that points to the created data. You can then GET that URI, or PUT it to change:
POST /api/data
{"data": "..."}
Response:
Location: /api/data/12345
{"data": "...", "lastmodified": "..." }
To change it:
PUT /api/data/12345
{"data": "..."}
You don't have to do it this way, but it might be easier to implement on the client side, and maybe even help with caching and cache invalidation.

How to retrieve multiple users data based on userid in meteor js?

I have created a chat message functionality. The message stores the userid of sender and receiver. How can I get other details of the user just based on the userid?
Is creating a Meteor method the best way or I have to create publish/subscribe pattern for it.
I want to avoid sending all users data to client side.
I tried creating a meteor method but I don't think its the best approach.
Meteor.methods({
getUserInfoById: function (usrId) {
//console.log("BEGIN");
//console.log(usrId);
var user = Meteor.users.findOne(usrId);
//console.log(user);
//console.log("END");
return user;
}
});
Create a publisher (and also a subscriber) for the data about other users that you want a given user to see. You can restrict the fields returned using the {fields: ...} qualifier in the query.
This is a very common pattern. Using a method for this is an anti-pattern due to the extra round-trip delay for something you're likely to show quite often, i.e. another user's username or avatar.

Simple XOR a message (Javascript/Tcl)?

I need the username/password to be scrambled at the client-side before sending it over via HTTP GET/POST. And the server will decode it with Tcl, before the checks against database.
Currently I'm thinking about using JavaScript for the client-side. Java Applet will also do.
Is there any way, that I can easily achieve it, using Simple XOR or any other methods? (Examples would be much appreciated)
I've found the few samples in C/Python/.NET/Java... But not in JavaScript and Tcl.
SSL is not an option to use, sadly.
If ssl is not an option, then I suggest the following scheme, which many sites use instead of SSL:
On the client side, combine the user name and password, then calculate a hash from it (MD5 is a popular choice).
Send the user's name and hash over to the server
On the server side, retrieve the password for that user from the database.
From the user name and password, calculate the hash and compare it with the client's hash. If the two match, then the passwords match.
For added security, add a little random text to the user+password mix. This random text, AKA the "salt", must be known on both the client and server sides.
Here is a suggestion on how to calculate the hash using MD5:
package require md5
proc calculateHash {user password salt} {
return md5:md5 -hex "$user:$salt:$password"
}
How to use it:
set user "johnny"
set password "begood2mama"
set salt "myDog_is_meaner_than_yourDog"
set hash [calculateHash $user $password $salt]
superNobody,
You should consider alternatives to storing plain-text passwords in the database. See:
http://www.codinghorror.com/blog/2007/09/youre-probably-storing-passwords-incorrectly.html
Instead of encoding the password in Javascript, then decoding the password in Tcl to compare with the database, you should consider SHA1 hashing in Javascript, and storing SHA1 hashed values in the database.
There are several available examples of a SHA1 hash function in javascript (just Google 'sha1 javascript'). The tcllib Tcl library has SHA1 support.
As HaiVu mentioned, you should also consider hashing / storing more than just a straight password hash, but instead use something like SHA1( username + websitename + password ). You can calculate this on the client in Javascript, and store it in the db.

Categories