Secure Session Variables


#1

tl;dr : How do I prevent the client from accessing the Session variable?

Long version: I am creating a “Question of the Day” web app and I want to allow anonymous users to answer the question and then provide a “Login/Create An Account to Save Your Answer” dialogue.

However, I do not want the user to be able to guess an answer, close the tab, and keep guessing until he/she gets the right answer then logs in/ creates an account and has a perfect score every time.

So I am looking for a way to store a persistent hasAnswered boolean on the client side. Or perhaps is they a way to store the IP addresses of devices that have answered each question on the server-side?

I tried using the u2622:persistent-session package, but that still allows the user to change Session key-value pairs through the console.

Any ideas?

Thank you for reading and helping. =)


#2

UPDATE: This is not a working solution

I think I might have found a solution. With this answer: Secure, persistent server side variables?

It’s using Meteor.onConnection


#3

I’m not a fan of that solution, as Sessions is not reactive.

If the variables don’t need to be global, use ReactiveVar. The client cannot access those via the web console (if that’s what you’re concerned about). Otherwise, you could use an unmanaged (temporary) collection:

Things = new Mongo.Collection(null);

#4

But is ReactiveVar persistent across tabs and sessions?


#5

Tabs, not sure. Session vars do not survive hot code pushes, while ReactiveVar does.


#6

Other way around, Sessions survive hot code pushes, not ReactiveVars.


#7

IMO, I think you should just persist this in the database.


#8

The connection object has a clientAddress property that has the IP address of the person too.


#9

Woops! Thanks for the correction.


#10

I think that is what I will do. Just store an array of IP addresses inside each “question object” of the Questions Collection and make a template helper that checks if the current clientAddress is already in the list

Thanks for the recommendations. =)


#11

I think that most of internet user are behind DHCP server which rotate IP address on per day basis and that you can always request new IP address so… maybe not a good idea to record IP.

Is there any way to get MAC address of client’s network device? (MAC can be spoofed also but it’s harder)


#12

just store it in browser session, not meteor "Session"
both can be edited, but there is no way how to disable end user to manipulate these.

most you can do is to accept only answers from registered accounts - that way you can minimize risk of 1 person manipulating whole results. And some limits to answer counts per IP etc etc.


#13

Thank you all for the recommendations. In the Meteor Docs about the onConnection method is says:

Currently when a client reconnects to the server (such as after temporarily losing its Internet connection), it will get a new connection each time. The onConnection callbacks will be called again, and the new connection will have a new connection id.

In the future, when client reconnection is fully implemented, reconnecting from the client will reconnect to the same connection on the server: the onConnection callback won’t be called for that connection again, and the connection will still have the same connection id.

I guess we will just have to wait for MDG to release this update. In the meantime, I don’t want to force users to log-in to answer their questions, so I guess I will just use the persistent-session package to keep key-values pairs. Honestly, I think I am focusing too much on the 1% of users who will actually try to hack their way around in the Dev Tools. Plus, this is a personal project, so I expect around 30 users. =P So it’s no big deal. =)