How do you ensure single submit to API without login - security

We're working on a new opensource tool that enabled users to vote. No login is required for this.
Now here's the challenge: how can we ensure the API is only called once per day from a specific machine without requiring the user to login?
We think this can be easily spoofed, but perhaps there are solutions that we haven't thought about.

There isn't a full proof solution if you're not going to require users to register on your site/app. Since you're not requiring them to register/login, then you're limited to two options: Unique votes by IP or by cookie.
IP Address
Easy to implement by storing the IP address of the vote in a data store then referencing that the next time a vote comes in from the same IP. However, many ISPs such as AOL could use the same IP address (via proxy) for multiple users. As a result you'll be preventing those who haven't cast a vote to be able to vote.
Cookie
This approach will be more client specific, meaning once they vote from that machine they won't be able to vote again. However, this is even less robust since the user can delete the cookie and vote again (or open a different browser on the same machine that doesn't have the cookie).
In short, if you can't force the user to register and establish uniqueness in your system, you could rely on either solution above but they won't be robust and will come with their own limitations.

Related

how to "dont vote twice" mechanism

I was thinking of creating a voting app. The general idea is
browse a gallery
an awesome pic grabs your attention
hit the vote button underneath it
code magic happens
vote is counted
at a certain date, vote buttons become non-active and the app counts
the votes
This will be a web app, which means html5-css3-express.js-redis framework, or something similar.
How can I ensure that the user cannot vote for the same pic twice? By making him sign up? Huge procedure for just a voting app, dont you think? Plus, I guess I will also need a CAPTCHA thing to avoid unwanted, mass sign up.
But if I use coockies of HTML5 local Storage API, what is stopping the same user to clear his/her coockies and vote for the same pic again and again?
What is the best method?
Thanks alot
The most secure way is by using accounts to keep track of who has voted. Accounts are easy to implement in your application and you don't even need to hold the account data yourself if you use a service like Passport.js. You'll likely have a database set up already which makes it easy to keep account data as well.
The other method is to keep track of IP addresses but this has some issues (say, if a user uses a proxy). Also an IP address will cover all clients on a network means if one person votes on an image, all others will be unable to afterwards.
Easy way may be using npm package mongoose-voting where all logic for voting is already implemented.
There is also requirement for keeping track of users, so if you don't want a user to sign-up, you can automatically create a user by using the visitor’s IP address as the user’s ID.
There are many ways to manipulate vote results, but at the level you described, most of them are unnecessary.
well you dont need to build a login system these days as you can use any of the open id login authentication.E.g providers are facebook, google, yahoo and twitter.

Possible solutions for keeping track of anonymous users

I'm currently developing a web application that has one feature while allows input from anonymous users (No authorization required). I realize that this may prove to have security risks such as repeated arbitrary inputs (ex. spam), or users posting malicious content. So to remedy this I'm trying to create a sort of system that keeps track of what each anonymous user has posted.
So far all I can think of is tracking by IP, but it seems as though it may not be viable due to dynamic IPs, are there any other solutions for anonymous user tracking?
I would recommend requiring them to answer a captcha before posting, or after an unusual number of posts from a single ip address.
"A CAPTCHA is a program that protects websites against bots by generating and grading tests >that humans can pass but current computer programs cannot. For example, humans can read >distorted text as the one shown below, but current computer programs can't"
That way the spammers are actual humans. That will slow the firehose to a level where you can weed out any that does get through.
http://www.captcha.net/
There's two main ways: clientside and serverside. Tracking IP is all that I can think of serverside; clientside there's more accurate options, but they are all under user's control, and he can reanonymise himself (it's his machine, after all): cookies and storage come to mind.
Drop a cookie with an ID on it. Sure, cookies can be deleted, but this at least gives you something.
My suggestion is:
Use cookies for tracking of user identity. As you yourself have said, due to dynamic IP addresses, you can't reliably use them for tracking user identity.
To detect and curb spam, use IP + user browser agent combination.

How to Check for Shared Accounts

We have an application that includes a voting component.
To try and minimise voter fraud we allow N number of votes from the same IP address within a specific period. If this limit is hit we ignore the IP address for a while.
The issue with this approach is if a group of people from a school or similar vote they quickly hit the number. Their voting can also occur very quickly (e.g. a user in the class asks his classmates to vote which causes a large number in a short period).
We can look to set a cookie on the user's computer to help determine if they are sharing accounts or check the user agent string and use that too.
Apart from tracking by IP, what other strategies do people use to determine if a user is a legitimate or a shared account when the actual IP is shared?
If your goal is to prevent cheating in on-line voting, the answer is: you can't, unless you use something like SSL client certificates (cumbersome).
Some techniques to make it harder would be using some kind of one time token sent trough e-mail or SMS. Every smart kid knows how to cheat control cookies using privacy mode of modern web browsers.

Is this a reasonable way to implement 'remember me' functionality

If a user logs into the site, and says 'remember me', we get the unique identifier for the user, encrypt this with RijndaelManaged with a keysize of 256 and place this in a httponly cookie with a set expiration of say.. 120 days, the expiration is refreshed each successful request to the server.
Optionally we generate the initialization vector based upon the user agent and part of the ipv4 address (the last two octets).
Obviously theres no real expiration system built into this, the user could technically use this encrypted key forever (given we don't change the server side key)..
I considered the fact that to allow this feature I need to allow the user to be able to bypass the login and give me their unique id (which is a guid), I figured the guid alone was really hard to guess a real users guid, but would leave the site open to attack by botnots generating guids (I've no idea how realistic it is for them to find a legit guid).. so this is why theres encryption where the server knows the encryption key, and optionally the iv is specific to the browser and ip part.
Should I be considering a different approach where the server issues tickets associated to a user, and these tickets would have a known expiration date so the server stays in control of expiration? should I really care about expiration? remember me is remember me after all?
Looking forward to being humbled ;),
Cheers.
Very similar question.
The solution to your question is in this blog post
"Persistent Login Cookie Best
Practice," describes a relatively
secure approach to implementing the
familiar "Remember Me" option for web
sites. In this article, I propose an
improvement that retains all the
benefits of that approach but also
makes it possible to detect when a
persistent login cookie has been
stolen and used by an attacker.
As Jacco says in the comments: for in depth info about secure authentication read The Definitive Guide To Website Authentication.
Did you consider something like Open Id? As SO uses.
How important is the information that is being remembered? If it's not going to be anything very personal or important, just put a GUID in the cookie.
Including the IP address in the calculation is probably a bad idea, as it would make users using public networks be instantly forgotten.
Using brute force to find GUIDs is ridiculous, as there are 2128 possibilities.

Best practice against password-list-attacks with webapplications

i'd like to prevent bots from hacking weak password-protected accounts. (e.g. this happend to ebay and other big sites)
So i'll set a (mem-) cached value with the ip, amount of tries and timestamp of last try (memcache-fall-out).
But what about bots trying to open any account with just one password. For example, the bot tries all 500.000 Useraccounts with the password "password123". Maybe 10 will open.
So my attempt was to just cache the ip with tries and set max-tries to ~50. The i would delete it after a successful login. So the good-bot would just login with a valid account every 49 tries to reset the lock.
Is there any way to do it right?
What do big platforms do about this?
What can i do to prevent idiots from blocking all users on a proxy with retrying 50 times?
If there is no best practice - does this mean any platform is brute-forceable? At least with a hint on when counters are resetted?
I think you can mix your solution with captchas:
Count the number of tries per IP
In case there are too many tries from a given IP address within a given time, add a captcha to your login form.
Some sites give you maybe two or three tries before they start making you enter a captcha along with your username/password. The captcha goes away once you successfully log in.
There was a relatively good article on Coding Horror a few days ago.
While the code is focused on Django there is some really good discussion on the best practice methods on Simon Willison’s blog. He uses memcached to track IPs and login failures.
You could use a password strength checker when a user sets their password to make sure they're not using an easily brute-forced password.
EDIT: Just to be clear, this shouldn't be seen as a complete solution to the problem you're trying to solve, but it should be considered in conjunction with some of the other answers.
You're never going to be able to prevent a group of bots from trying this from lots of different IP addresses.
From the same IP address: I would say if you see an example of "suspicious" behavior (invalid username, or several valid accounts with incorrect login attempts), just block the login for a few seconds. If it's a legitimate user, they won't mind waiting a few seconds. If it's a bot this will slow them down to the point of being impractical. If you continue to see the behavior from the IP address, just block them -- but leave an out-of-band door for legitimate users (call phone #x, or email this address).
PLEASE NOTE: IP addresses can be shared among THOUSANDS or even MILLIONS of users!!! For example, most/all AOL users appear as a very small set of IP addresses due to AOL's network architecture. Most ISPs map their large user bases to a small set of public IP addresses.
You cannot assume that an IP address belongs to only a single user.
You cannot assume that a single user will be using only a single IP address.
Check the following question discussing best practices against distibuted brute force and dictionary attacks:
What is the best Distributed Brute Force countermeasure?

Resources