Preventing Duplicate Form Submissions using 2FA - php

My problem is this:
I have a survey that is taken by people that they're paid for. I want to avoid the same person submitting the form multiple times. It is a web application.
What I have tried:
I have tried recognizing the IP address from which they try to submit the survey but it hasn't worked.(They could just change devices and so, IP changes) I could try 2FA (where I authenticate using SMS/Voice to phone numbers) but free phone services like Google Voice/Twilio will render that useless. Using a SHA/MD5 hash on a combined key such as phone number and email address still faces the same multiple emails/phone numbers problem. Uber has recently covered up its tracks and devised a way (or a partnership) to recognize Google Voice Numbers. I have gone through the Google Voice API and haven't found a way to find the actual phone number linked to the Voice number.
Is there any full-proof way of doing this?
PS: I am NOT talking about multiple form submissions on a form (say a ecommerce website) which causes multiple charges to a credit card. Please do NOT suggest CAPTCHA.

Related

Security of logging in with phone number only, plus SMS code

I am building a cross-platform app and using PHP and MySQLi. Users sign up with either their Facebook account or phone number. If they choose phone number, they enter their number and an SMS is sent containing the verification code. The user enters the code and an API token is sent back to be used across the API requests. Tinder (for example) is this way.
I am considering Twilio for the verification.
My issue comes down to the security of this login process. Can a malicious user just rapid-fire the login request that creates a verification code over and over again... sending plenty of SMS and costing me a fortune on my Twilio account? Should I only allow so many attempts? Can a bot just eventually guess the code?
What is the security behind Tinder's API?
things to consider:
1- limit request per phone number
2- limit request per user (by ip)
3- use captcha (only after second attempts to keep your app user friendly)
4- use honeypots
"can a bot guess the code?"
verification codes should have a time constraint. after like 2 mins they should be invalid. time constraint and request limiting should make it very very unlikely for a bot to guess the code.
if you are using laravel it already have rate limiting middleware (limit by ip).
Twilio developer evangelist here.
I agree with all the things that Shalior says in their answer, so I'm not going to reiterate that.
What I wanted to share was this article on falsehoods programmers believe about phone numbers. It is a good reminder that phone numbers don't necessarily uniquely define a user, and worth keeping in mind if this is your intention for a passwordless login.

Mobile registration system. How to handle E164 and national mobile number login?

I'm implementing a mobile registration system in PHP where by the user can register with their mobile number. They can also log in with that number and receive SMS notices/verification etc.
Let me explain the system before moving onto the problem as its easier to explain that way.
My current system works like this:
User signs up with 07733333333
Phone number is converted to E164 format and stored as +44773333333
SMS validation is sent
This works great and ensures the user can't sign up twice with the same number. It's also the format our SMS service provider requires.
The way I convert to E164 is using Google's LibPhoneNumber library. It requires a country code to convert the number so I take that from the IP address. The user is able to change the country code if our guess is wrong. On the page after registration they will see a page that says "We've sent an SMS to this number: +44773333333". The user can change this number/country code at this point.
The problem arises when logging in.
If a user logs in with +44773333333 it's easy to grab this from the database. It's already stored in this format.
But, if they log in with 0773333333 I need to make a guess at what region that mobile number is to convert it to E164 format to run the query. There is no way I can query this number in the database because it doesn't exist in that form. I can guess that it's +44 from the IP address but this is unreliable. What if the user is on holiday? Or using a VPN? That guess can't be made.
What is the best way to handle this?
My only thought is to have two fields in the database. One is national_mobile_number and the other is e164_mobile_number. That way I can query either fields to see if the numbers match. I don't know what impact this would have on performance with many users (500,000+).

Fake account creation prevention on a Laravel website

I'm working on a Laravel project I'm building on my own that will require a fake account creation prevention system. I've already read some articles online and for now all the solutions which came to my mind are the following ones. I would like to make a mix of following technics, but not sure about how it's handle on other existing websites.
My website will require a bank account / paypal account, but also social networks to enjoy the experience. My service won't need people to pay to access to it.
I wanted to have a return of experience of people creating solutions like this online and what is the best combo or solution to avoid to maximum fake profiles creation ?
Email validation
(+) Easy to implement
(+) Easy to do for users
(-) Easy for people to bypass with fake emails or trash mails
Captcha
(+) Good to block spam bots
(+) Easy to implement
(-) Not working for every time of bots, and not working when people creating manually fake profiles
Social network link
(+) Could be a good basis to check user presence on Internet
(-) Not everyone has a social network account
(-) The social network account could be a scam also
SMS validation
(+) Pretty secure
(-) Not everyone has a mobile or are whiling to give their mobile
(-) Some platform already exists to send / receive online SMS to easy to avoid this system
Bank account / Paypal account
(+) Hard to fake
(+) Only people who are whiling to fill that information will do it
(-) How to check the user is real based on that informations ?
(-) What if the Paypal account is also a fake ?
Moderators
(+) Perfect to control all informations
(-) Consume time
(-) Consume money
I also know there is an existing online solution for that, but at the beginning of a project it represents a huge cost : Detect fake accounts
What are the solutions you are using right now and what would be adapted to minimize the number of fake profiles on a website ?
I implemented for prevent spam email registration in /register url.
When I try Google Captcha V2, V3, Mews Captcha, neither of one works for me.
Finally honeypot did the job.
option 1) we are using the invitation CODE scenario that will be generated from the admin side and only that users who have the CODE will be able to sign up the website.
option 2) when generally bots or something are using they were filled all form field so we can just take the Empty Form Field and it will be validating while register new user if value will be filled then its bot or something wrong that way we can prevent it.

Preventing abuse to an invite system

recently I helped some friends ship an invite system in their website that works like this: A user creates an account, we send a verification email and when he verifies the e-mail he gets one free credit to spend on the website. In addition to that, he has personalized links he can share on social networks or via e-mail and when people register using this link (e-mail verified accounts again) he gets one credit per invite. Much like the invite system on thefancy.com or any other reward driven invite system on the web.
Lately we see elevated rates of fake user account which probably are automated. The registration page features a CAPTCHA but we're aware this can be bypassed. We also see elevated rates of users creating disposable email addresses to create accounts following specific invite links thus crediting one legit users that onwards uses the free credits he earns.
I am looking for an automated way to prevent such kind of abuse. I currently investigating putting rate limits on invites/registrations that come from the same ip address but this system itself has it own flaws.
Any other production tested ideas?
Thank you
Edit:
I've also proposed 2 factor registration via SMS but was turned down due to budget shortage.
It seems you need to require more than just a verified email address before a user can send invites, ideally something that shows the user has participated in your site in some way. Without knowing what your site is it's hard to give specifics, but the StackOverflow equivalent would be requiring users to have at least X reputation before they can invite others. If you're running a forum you could require that they've made at least X posts.
I'd also suggest a small time limit before new accounts can invite - e.g. they have to have been a member for at least X days. This complicates automated invites somewhat.
An extremely simple method that I have used before is to have an additional input in the registration form that is hidden using CSS (i.e. has display:none). Most form bots will fill this field in whereas humans will not (because it is not visible). In your server-side code you can then just reject any POST with the input populated.
Simple, but I've found it to be very effective!
A few ideas:
Ban use of emails like 'mailinator'.
Place a delay on the referral reward, allowing you to extend fraud detection time period, giving you more time to detect bogus accounts and respond accordingly.
Require the referred user to create a revenue generating transaction before you give out any referral rewards (I know that might not be a shift you can make) - possibly in turn increasing the reward to account for the inconvenience to the referrer (you should be saving money through decreased fraud so not a hard sell).
Machine learning. Ongoing observations and tuning with your fraud detection. The more data you have the better you will be able to identify these cases. (IP addresses as you mention.) Shipping / billing info even more telling if it applies - beware adjacent PO boxes.
Add a CAPTCHA test to the confirmation page. I would be wondering if your CAPTCHA is sturdy enough if it is getting bypassed somehow. You might consider using the (hateful) reCaptcha which seems popular. A CAPTCHA on the confirmation page would reduce the risk that a 'bot is submitting the confirmation page. In other words, it would implement the idea of client interaction with the site after registration. A similar method would be to ask for the registrant's password.

How can I get a phone number customers can sms to that posts the information to my website?

i need an sms service that can gives me a phone number and then my customers can send me sms to that number. then posts the sms information to my website like http://xx.com/newsms.php?body=hey
Thanks
Twilio recently released a SMS API. With Twilio you can:
Get a unique phone number (not a keyword at a shared short code).
Easily connect it via a HTTP POST
It's ridiculously simple. Check out the API.
Try www.textmarks.com - they got a PHP API as well.
If the content can be public or semi-public you might consider using Twitter, which allows various ways of posting via SMS. Their API lets you do pretty much whatever you want with the resulting feed.
An upside of this could mean extra exposure for your site, depending on how you implement it. This is especially true if any of your customers happen to be heavy Twitter users. Also, people would be not be limited to SMS, but could post via web or twitter apps.

Categories