I'm building a small application that highly depends on anonymous user voting on some sort of items. It's so small that requiring registration would be tedious and could not be justified.
Anyway, I did some research on this, including a search here on stackoverflow (https://stackoverflow.com/search?q=anonymous+votes), and doesn't seem that there's a satisfying answer.
My question is: are there any security measures that I can apply to prevent gaming anonymous votes?
One thing comes to mind is CAPTCHA, but I'd like to avoid that since users will vote on multiple items in a very short period of time, and CAPTCHAs will just annoy them.
Another thing I thought of is limiting the number of votes per minutes from a single IP (in addition to a cookie), but not sure how this is going to work.
Any thoughts?
There are a few ways I've seen work:
Email registration : you get their email, they need to confirm their vote. The combination of their IP + email makes a unique record that they can't then use to vote again (for the same poll).
Captcha : without having additional checks (IP, etc), it's easy enough for a team of monkeys to successfully enter a lot of captchas.
Site Registration : without account creation level limits (e.g. a non-free email account required for signing up) people can just create multiple accounts.
Depending on how you weigh up the cost of getting users to vote vs making sure their votes are for them and them alone, you can use a different level of vote-spam-protection.
You can use the CAPTCHA once to both confirm the vote and create a session with the IP and cookie.
Any time you are dealing with anonymous voting you are going to have an imperfect solution but you can shoot for "pretty good". Consider dropping a cookie on the client computer to prevent multiple/frequent voting and back this up by performing server side IP tracking to do the same. Do not allow anyone to vote that has cookies blocked.
Of course, if you require complete accuracy or if the voting involves awarding of something of monetary value, registration is really the way to go.
Related
First of all, sorry for the long text. Second, I decided to ask this on Stack Overflow rather than somewhere like Law Stack Exchange because the reason for the question is GDPR but the question itself is about software architecture.
I've been trying to pay attention regarding what one must do concerning GDPR and everything I find always seems to assume that one is working with user accounts, i.e. that users register on your website and that everything or almost everything you need to care about GDPR in terms of safeguarding your users' data starts here. It is also my understanding that one must be able to prove that their users gave their consent to you using their data as per in a privacy policy and even to which version of the privacy policy they consented to (since these sometimes get updated). This necessarily means that the data regarding this proof of consent must be stored server-side. This is easy to do when you have a user account to bind this data to but what about when you work with non-registered or guest users?
Let me give you a little background for my actual question: as a personal project I'm currently building a small website which will allow users to add comments to certain pages and even submit photos. The thing is, this is the only interaction users can do at all, so I don't want nor need them to have an account, making it also one less thing to worry about and allowing for easier engagement with the site. For the comments the only thing that's really needed is the comment text itself and some user name (which can be anything from their real name to some alias, it doesn't really matter). I'll also add an optional field for the user to state where they're from -- say, "Paris, France" -- if they so wish to share that.
Anyway, all of this just begs for spam to come my way, so I was thinking of integrating Akismet and Google's reCAPTCHA, since that has worked very well for me in the past. The problem is that Akismet requires an email address to also be passed on to it in order for it to check if the comment is spam, so I would also need to ask users for their email address on the comments form. Since I literally only need their email while checking for spam and would never make it public anyway, I would save it in the database and get rid of it after a few days or so and communicate this on the site's privacy policy.
So, here comes the question. I think email addresses together with the other info above count as PII and since I'm storing email address and sharing them with a third party, it seems clear to me that I have to ask users for their consent to do so, and not allow for their comment to be submitted if they don't give their consent, of course. But there are no actual user accounts in place here so there's no central location for such consent to be stored as proof. So how does one go about this? The only thing I can think of is having a checkbox on the comment form and storing its value together with the comment. Of course, with proper validation in place the stored value will always be 1, but still, it needs to be explicitly stored for it to be GDPR-compliant. I don't love the idea of a user having to check a checkbox agreeing with the privacy policy everytime they want to comment on something, but I don't think I see another way around this. Do you?
Many thanks in advance and, again, sorry for the long text.
So the following which I'm writing is just to discuss whether something like this is even possible or if any of you would have any better ideas/suggestions or understanding how this might work. I thank anyone who takes time to read this in advance and I hope I don't explain myself too incoherently:
Let's say I have a page in WordPress which has a little bit of text and a video. Basicly I would like to share that page's link or I'd want to forward that page via e-mail to a certain group of people (let's say 10-50 specifically chosen people) and I want to track who of them opened the link and for how long they were on the page or watched the video.
I would like to make this happen in a way that I wouldn't have to make 50 different pages or 50 different URLs for each person (or 50 different tracking strings for that matter). Or that I wouldn't have to take a newsletter-mailer type page in between this process.
Basicly, I would like to make the sharing/forwarding and analytics overview process as easy as possible, so that an admin or moderator wouldn't have to check too many different pages to get the info.
I really appreciate any and all feedback.
[Also really sorry if I posted this in the wrong place. Please feel free to redirect me to a corresponding slot].
Technically, Google Analytics isn't meant to be used to track this specifically- it's typically meant to track groups of anonymized users. That being said, it is capable of doing this (but may not be as automated as you had hoped).
You are correct in thinking that you'd either need to duplicate the pages or create multiple different campaign URLs.
The other thing to keep in mind is that as emails are forwarded, there is no way to update the URL after the email has been sent, so if you email me and I forward it to someone else who clicks through, you're going to think someone else is me.
One way around this would be if you know your users IP addresses (not only is that a big "if", but it can also be spoofed), or some other uniquely identifying feature (any chance these people have signed-up through your website and have actual user IDs? That'd make things infinitely easier!).
Maybe you could customize the email to add their email address as a query string? That could still require a lot of work (and you couldn't just share a single link).
Now, you can not store personally identifiable info in GA (including IP and email addresses), but at the server-level you could assign a custom dimension with a uniquely generated ID and send that to GA. Now you've got all the info you need!
Unfortunately this method only works if you can detect some kind of "fingerprint" of your users.
Unfortunately what you described isn't quite what Google Analytics was designed to do. If you wanted to get into detailed user-specific tracking, I'd advise you look into a CRM. Those systems are designed specifically for user tracking as you described.
Hope that gets you pointed in the right direction.
I'm working on a web-based academical evaluation project (VS2010,C#,ASP.NET). Users can enter the web site and evaluate personnel of a company (or the company managers). Then my clients (company owners) should be able to view results of the evaluation (appraisal). As this process involves people and there is always risk of re-voting by some users, I'm searching for ways to minimize number of re-evaluations by similar users, i.e. I'm going to prevent a user from voting for more than once as it can hugely affect results of the appraisal process, I'm asking user about his name, surname and national ID; I'll store these data in my database, and the next time a user trying to login with the same data will get a warning, but anyone can change his data and vote for several times! Also I save user IP and will check it on later logins but it can also be faked easily! what else can I do? using cookies? sessions? how should I technically prevent users can from voting for several times?
thanks
You can't avoid it but can minimize it. Take a look at this similar question/answers:
multiple voting.
Hunting Cheaters.
Prevent Users from Voting Multiple times
I want to count the visits on a web page, and this page represents an element of my model, just like the Stack Overflow question page views.
How to do this in a reliable (one visit, one pageview, without repetitions) and robust (thinking on performance, not just a new table attribute 'visits_count')
You can't.
Multiple people can visit your site from the same IP (makes ip storage useless)
Multiple people can visit your site from the same PC
Multiple people can visit your site from the same browser (makes cookies useless)
The closest you can get is to store the visitors IP in combination with a cookie to not count those in the future. Here is a tradeoff, if they clear the cookie, they are a new visitor. If you only store the IP, you count whole proxies as one visitor.
Another option is to use user accounts and track exactly which user viewed what page, but this is not really a good option for public sites.
I would suggest, actually, using Google Analytics. While nothing will ever be truly accurate, they do take a pretty gosh-darn good stab at it, and the level of reporting and useful information you can extract is amazing.
Not to mention being free for up to 4,000,000 page views a month.
http://www.google.com/analytics
One way to handle the performace issue, is to do the calculations on insert. Something like
UPDATE stat SET viewcount = viewcount+1 WHERE date = CURDATE()
It isn't the perfect solution but could get you some of the way.
To do it without repetitions is potentially a tricky problem. I would simply rely on using sessions or cookies, but you could come up with all kinds of strategies for filtering crawlers, clients with out cookie-support and so on.
I'm working on a web-based contest which is supposed to allow anonymous users to vote, but we want to prevent them from voting more than once. IP based limits can be bypassed with anonymous proxies, users can clear cookies, etc. It's possible to use a Silverlight application, which would have access to isolated storage, but users can still clear that.
I don't think it's possible to do this without some joker voting himself up with a bot or something. Got an idea?
The short answer is: no. The longer answer is: but you can make it arbitrarily difficult. What I would do:
Voting requires solving a captcha (to avoid as much as possible automated voting). To be even more effective I would recommend to have prepared multiple types of simple captchas (like "pick the photo with the cat", "what is 2+2", "type in the word", etc) and rotate them both by the time of the day and by IP, which should make automatic systems ineffective (ie if somebody using IP A creates a bot to solve the captcha, this will become useless the next day or if s/he distributes it onto other computers/uses proxies)
When filtering by IP you should be careful to consider situations where multiple hosts are behind one public IP (AFAIK AOL proxies all of their customers through a few IPs - so such a limitation would effectively ban AOL users). Also, many proxies send along headers pointing to the original IP (like X-Forwarded-For), so you can take a look at that too.
Finally, using something like FSO (Flash Shared Objects - "Flash cookies") is obscure enough for 99.99% of the people not to know about. Silverlight is even more obscure. To be even sneakier, you could buy an other domain and set the FSO from that domain (so, if the user is looking for FSO's set by your domain, they won't see any)
None of these methods is 100%, but hopefully combined they give you the level of assurance you need. If you want to take this a level higher, you need to add some kind of user registration (which can be as simple as asking a valid e-mail address when the vote occurs and sending a confirmation link to the given address and not counting the votes for which the link wasn't clicked - so it doesn't need to be a full-fledged "create an account with username / password / firs name / last name / etc").
No, you can't, and it only takes one person and a willing forum to change the outcome of an online vote.
You have to realize the inherent flaws of an online vote and rather than attempting to get around them try to use them to your advantage.
-Adam
You can certainly make it difficult.
What about building a user profile with such things as ip address, browser useragent, machine name, and whatever other information you can get.
Store the profile for each user, then if you receive a profile which is similar enough to one already in the database (you'll have to tweak that) you can throw out that vote.
I imagine you can probably build a better profile using silverlight, though I'm not sure what information that gives you access to.
Client-side solutions are out for the reasons you listed -- they can be manipulated by the user. Server-side solutions -- as you said -- can be fooled and bypassed.
If you're willing to accept the fact that you can't really be 100% sure that you're getting exactly one vote per person, then there are some measures you can take to reduce the noise.
Use a CAPTCHA in your vote-submission form to make it harder for bots and scripts to vote.
Limit the number of votes per IP address to one.
Consider requiring registration in order to vote. (I know this defeats part of your original question, but it gives you a greater degree of control over the voting.)
That's a good start.
my personal experience in contest developing and monitoring tells me that no, there is no reliable way to avoid cheating if you let anonymous users vote (or do anything that lets them participate in the contest).
you could play with IP, introduce delays between an action and the next, but it's really difficult: the best way is introduce a captcha or something similar, if applicable in your particular situation.
best of all, don't let anonymous users participate: let them "play" and access to a simulation, but the contest needs a login.
Nope, it's the user's computer and they're in control.
Unfortunately the only solution is to bring it back on your court so to speak and require authentication.
However, a CAPTCHA helps limit the votes to human users at least.
Of course even with authentication you can't enforce single voting because then they teach the bots to register...
I have to agree that the short answer is no...though if you look at my recent answer here: How to anonymously identify a user and store that information you certainly can get it within a 6 percent margin of error.