How to avoid that a user removes his session - php

The use case
Currently, I am trying to build a page where users can vote on content (up/downvote, similar to the function on the StackExchange network). But the users shouldn't need to register themselves to vote on content. So it would be a kind of "anonymous" voting page. It is built with Laravel5 and uses a MySQL database to store the votes. The user sessions are stored in flat-files, but can be also stored in a database table (L5 is quite flexible here).
The problem
How to make it secure?.
I am storing restrictions and already voted contents in the user sessions, e.g. when the user has voted on content XYZ (so the user cannot vote again on the specific content for now). Those restrictions are time-based, mostly 24 to 48h. This works well, as long as the user does not throw away/delete his cookies, which would cause to create a new session and remove the time restrictions, which could lead to easy vote fraud.
So, how to avoid that the user "loses" his session? The focus is on how to let the restrictions and limitations of each "anonymous" user persist! Shared PCs or voting on different locations cannot be avoided when voting anonymous, but "botting" or a vote fraud in large numbers needs to be avoided with a given solution.
Solution attempts
Setting the sessionId of each users session to a combination of IP and
User-Agent
I've asked a question about this attempt (linked below), but it'd open up more problems then it'd solve (e.g. easy session spoofing). Also, I couldn't achieve to set the sessionID manually by using Laravel5.
Solutions that doesn't fit
Let every user register themself (it's simply too much effort for each user in my use case)
Related
How to remember an anonymous vote
Retrieve or reassign user session from ip and user-agent

as users are not stored and maintained its very difficult and can't be made 100% sure.
how i try to achieve this most closely is using request ip address and csrf token.
you can get ip address from request and csrf_token() from anywhere inside your laravel application.
here is an example of how i am going to implement
create a table named votes having following fields
votable_type
votable_id
ip_address
csrf_token
i would check whether a client does not have an existing record for same votable type and id. client is a the csrf_token. ip is for guaranteeing whether the requests are legit.
votable type and id is the polymorphic relationship between either may be comments, posts etc.
note
without persisting user identification in anyway some users might not be either vote or some might vote twice. it can't be done
perfectly.
some users might vote from different user agents multiple
times.
some users might spoof ip. clear cookies
different users might be using same
system to login.
some users might be using different connections or
system logins.
so either we take any information it wouldn't be 100%
accurate.

My solution was combination of implementing evercookie to assign a "Identification Cookie" per user, detecting privacy browsing and restrict access when having Incognito mode or private browsing enabled, and finally restrict several actions (voting in my case) when not having the evercookie.

Related

PHP Server options and voting system

I am currently creating a website that allows anonymous users to input data (or comments) into a database and allows other anonymous users to the site to vote up or down the comments presented on the site.
I have already created the functionality to allow a user to create a comment and allow another user to vote on the comment. The problem I'm having though is thinking how I can limit each visitor to the site to only vote on each comment once.
My idea was to create a session ID when the user votes and then when they try and vote again to try and compare if a session ID already exists. This would work but only until the session is destroyed. Does anyone have any other ideas of how this could be achieved?
I am assuming I might be able to use some of the $_SERVER options available
Thanks in advance
Just restrict the voting with IP's or either Cookies, i also created 3 websites in which i had to take the public voting, earlier i did it with IP's but then i changed back to cookies, i also saved IP's along with setting cookies to check if the users are deleting cookies again and again to vote, but i never had such problem, so my opinion in just go with cookies, because not everyone can find that we are doing it with cookies.
It's impossible to enforce a one-vote policy on an anonymous user system. Like said in a comment above:
Trying to control "Anonymous" is nearly impossible. IP's are shared,
sessions are temporary, cookies can be deleted
You can't identify your clients at 100%, if a user would want, he will be able to bypass whatever means you attempt to use and vote more than once.
Your only reliable option is to enforce registration and only allow registered users to vote.
If you still insist, you can try to make it difficult for users to bypass your enforcing system. Use a combination of the user's IP address, and a lasting cookie, and cross-validate against both to ensure the user doesn't vote twice. But again, do note that a user can easily delete cookies and on most cases, change his IP address.
When you are inserting comments for specific article, store the member (who is commenting) id or name or any thing unique. Put the verification code before inserting the comments ....
Select * from articles where member_commented_id = [current_member_id_from_querystring) and article_id = member_commented_on_article_id
//a check point
if result is > 0 .. its mean member already has commented on this article
//otherwise
add comments on article and insert member id as well for checking
// if you are using seperate table for comments then you have to make additional field in table like
comment_id, comment, com_date, member_id_who_commented, article_id_on_which_commented
Making IP or Cookies check point is not reliable because IPs are changed by the ISP (if set to dynamic IP) and Cookies can be cleared by visitor
Hope this helps you

How can I track a unique user in PHP? (Prevent user from voting more than once) (Please read details for the complications)

I want to keep track of a user so they don't vote twice in a poll. I don't want to use an IP address because the application I'm creating is targeted towards a campus and many people will have the same IP address because the wireless network uses NAT. Also, I don't want to use cookies or Session ID because those can easily be deleted.
How can I do this? Or am I out of luck?
I've looked at this question: How to identify unique user?. There are some answers that say that browser fingerprinting could be a way that Urban Dictionary prevents multiple votes. How would I accomplish this?
EDIT: One thing I certainly can't have in this application is user login. It defeats the purpose of the app.
I'm going to assume browser fingerprinting is reading the user agent string, which is not reliable as the user agent string can be changed in most browsers these days.
If you're wanting to uniquely identify a user, then only allow voting by logged in users, and if it's targeting to a campus only then all students will have an email address, i.e. first.last#schoolname.sch.uk or whatever your domain is.
Individual techniques may not be powerful enough, but combined, they could be very useful.
For example, you could say:
if IP is the same AND browser is the same AND operating system is the same
OR
cookies are present
Then disallow voting. Obviously, There are many more techniques that could be used in conjunction with this (such as browser fingerprinting).
Another option would be to simply require users to be logged in to vote, and ensure that each has a distinct email address.

How can I prevent users from voting more than once in 1 hour?

At the moment I have a script with CAPTCHA, which on submit logs the users IP address to prevent a user from voting more than once per hour.
However, many people are using proxies to get around this vote restriction and I would like to employ additional protection.
I realize there are other questions about this topic, but they always involve people wanting users to only be able to vote once, rather than a timed restriction.
Thank you for any help
EDIT: I do not want to force users to login
There is no 100% secure way of avoiding people to vote more than once an hour, but here are few methods to make it harder for the users to circumvent it:
Place cookies on the users computer
Log their IP
Store content into their localStorage (only for users with HTML5 browsers)
If you really want to start digging deeper, you can start putting restrictions based on the users session length, how many pages they navigated prior to voting, i.e. starting to profile the users that try to circumvent the system, and start putting restrictions on those profiled users.
You could use cookies, but people can delete them. Simplest answer without forcing them to login (for which they can create more than one account if they have multiple Emails etc) it would be hard to limit them without them being able to sneak round it somehow.
MEMORY tables on server with ip addresses
evercookie
browser fingerprinting
required registration
cron job to clear tables once a hour
http://code.google.com/p/mailvalidator/
make list of banned domains
visit 10minutemail and copy e-mail domain and add to the list
Are you against having users register on your site in order to vote? I would say make it based on account, not IP. Many users can be behind a NAT which would assign them all the same external IP (think work or school). In this case I'd say a table with four columns would suffice: user id, poll id, vote time, choice. If the same user id/poll id combination exists and time is greater than now minus one hour don't allow them to vote
If the "bad" people are clever enough to use proxies to vote against your will, or the rules, chances are that they will be able to circumvent other protections, too...
But here are the things you can do:
1) Set up a cookie on the machine after the vote, but users could remove the cookie manually
2) Enforce user accounts to vote, validated by an email address, but users could create alternate user accounts
2bis) A user account could get the right to vote only after 24h, might not be suitable for your app
3) Like stack overflow, implements a reputation mechanism on user accounts so they will be able to vote only after having proved they're not just bots or alternate identities

rating system: storing username/ip in db or cookies?

I'm creating a simple thumbs up/down rating system. A user can simply click up or down, and total number of thumb ups/down is stored in db. I don't want the user to be able to vote multiple times However, I don't want to store the IP address or username of the user to check if it has already voted or not, because i think it will be pretty much mess in database. I'm confused, if I can use some alternative approach (for example storing the username,and item name in the cookies, so that it can prevent at least for some time.
Please let me know if storing (username, item-id) in db is good approach or storing in browser cookies? Thanks.
If you want to prevent multiple votes from the same user then you have no choice but to store their vote state on your server, anything on the client can be edited.
You refer to username which indicates that users have an account. If that is the case then you can store the item id and the user id in a table and use that to block any subsequent votes, hiding the vote options or showing the users current vote status.
You would only have to store IP addresses if users don't have accounts. However it is worth mentioning that an IP does not uniquely identify a single person/pc. For example any of the 1000+ people surfing the net from my office will use the same internet facing IP address.
As cookies can be trivially culled/edited you really need to use a database for this purpose and force each user to login before they can vote. (It sounds like you're already doing this from your use of the term "username".) Sadly, IP addresses aren't much use these days for uniquely identifying users in a reliable manner.
Additionally, in the database "votes" table schema you should have a UNIQUE KEY in place that ensures there can only be one vote per user on each "parent" object.
Database would be more secure in general.

How to prevent multiple authentication in a web app / site?

There's a site with registered users area, they all have their own user/pass.
The problem is, some of then try to share the authentication info with others to help them finish their job.
There's no posibility to restrict by ip adress because there's a dynamic-ip provided for everyone.
What could be the best solution? store sessions in the database? how to restore if they don't logout properly?
Thanks
I usually let them ping-pong: A custom session_save_handler which stores the session in a database, with an extra field for user-id (session_id char, session_data blob, session_user int or char). A successful login-attempt destroys / deletes all other other sessions with that specific user-id, and you could even log the number of times this DELETE statement actually deletes rows, with a counter somewhere to block people clearly excessively 'deleting' sessions. People switching computers / locations / browsers still can get work done instantly after login, users sharing authentication will keep on logging each other out, and increasing your counter until some arbitrary limit you deem appropriate, in which case you can disable / lock out the account.
If some people are sharing their ilogin/password then there is little you can do.
You could detect that someone is connected from two different locations and then close both sessions, but that wouldn't solve the full problem.
I agree with Loïc Février that there is little you can do when they are sharing logins.
If you really want to restrict user access from multiple locations, when you detect 2 sessions of the same user you could send some sort of a code/passkey thru email and only the real owner of the account could continue.
There is no particularly efficient way. That said, one technique could also be to use a DB to store the last IP used to sign in on an account, ping the DB every X amount of time and if the client IP doesnt match the last IP used to login, end their session..
You could also track IPs used to access an account, and limit each user to say, three. If they want another (as may legitimately happen), or if they exceed this amount- you have to be contacted/approve. This is a passive method, but will ensure you are notified over suspected account sharing..
Business solution
Make guidelines that it's not allowed to share logins to anyone. Track all login operations and if you see concurrent access, block the user.
a) The blocked user will call you, crying his login won't work: Give second and last chance. If it's not taken -> tell the boss. If you're the boss -> fire.
b) The blocked user will not call you. I wonder how he could work now. -> tell the boss. If you're the boss -> fire.
Programming solution
On the login screen, set a flag (the IP address?) in the database that the user is logged in at the moment. On logout, reset the flag. If the user is logged in, don't allow login. If the user does not log out correctly, the flag will still be set. So define a timeout for the flag to. About 5 min should be OK. It would be no gain for anyone to share login, as he would always have to login again, when you perform a check on every page access.

Categories