I'm creating a contact form for my company and I want to make it as spam-proof as possible. I've created a honey pot + session checking, but I also want to make it so that it's only possible to submit the form once every x minutes. In other words, banning the IP from using the form for x amount of time.
What is the best solution to do this?
I can think of a few but none of them seem ideal.
Store the users IP in a database every time the form is submitted, along with the timestamp. When a user submits the form, first check the database to see if they submitted within the timeframe.
Some problems could arise from large networks where users could the same IP though. It depends on the target audience, really.
Database. Store the IPs in there and timestamp them.
A nice approach I've seen being used on some blogs is to use JavaScript to protect against bots. Like in the onsubmit() event change the method of a form from GET to POST. You can do other magic too. Bots are very inept at executing JavaScript so you can use that to your advantage.
On the other hand - this might hurt the 0.0000001% of users that don't have JavaScript enabled. Well, your choice really. :)
If you don't mind restricting the form to cookie-enabled browsers (eliminating some "browsers" aka bots I assume), you could do something like this:
Form page loads, it checks for a session variable with a timestamp. If none is found, it creates one and redirects to the same page, but with a GET parameter specifying "action=start" or something. So on the second load, if you see $_GET['action'] == 'start', you can check for that session variable. If you don't find one, you can redirect elsewhere saying cookies are required.
Now you can check the timestamp and do something else if it's been too soon.
This method will at least allow the same IP, since if you're dealing with a large group of people behind a firewall you don't have to block the whole group.
The database thing is probably your best bet, because it doesn't require them to allow anything, it just logs their data. The only issue with that is that they could be masking their IP or hitting it from multiple places. I'd try cross-referencing the IP on their session/cookie with the database. If the same person is hitting your site really fast from the same IP address it'll be obvious, but if you create a user ID as well, you can see if they're rapidly switching IP addresses.
It also wouldn't hurt to have some kind of cron script (or at least a tool written and on standby) ready to cleanup a mess that does manage to get through. For my site I'm writing one to flag exactly identical submissions from multiple ips within a very small timespan (Within 10 seconds).
At the very least you could write some queries to show questionable submissions to the comment form.
Related
For a project at my school, I would like to allow members to 'sign-in' at the end of meetings to show their attendance. Obviously, there will be people who arn't at the meetings and will try to cheat the system.
The way I was going to go about this was
Restrict a form from being submitted (through php) if their IP is not within the range of the school's network
Prevent one device from submitting twice (add a week-long cookie)
I am not sure if my IP method is the best way to go about this, or if I'm entirely going about it wrong. So before I get too far into research; is this the best way to deal with this problem?
To restrict submissions to a certain IP range, you may want to look at this answer. However, this only works if the device used is in your school's network, and you would have to add some time constraint (so claiming participation the day after does not work).
As for cookies, those can be deleted by the user. For you, it may actually suffice to remember the logins used, and if they have been submitted for the week in question.
All in all, you may be easier off printing a list that participants have to sign...
I guess this is more of just a personal preference questions, but I'm really concerned with performance. I'm working on a little project and one thing that people can do is RSVP to events. Now I know the option that people choose (attend or not attend) must be stored in a database, but to make the site look a little better, I also want the button that allows someone to attend switch to not attend when they click it.
At this point I'm thinking of three options, either query the database, figure out if the person is attending, and display the appropriate button. -OR- I could save the information in a cookie and just pray that the user doesn't delete the information. -OR- I could save the information in a cookie, if the cookie is present then display whatever the cookies says, if not then query the database. Option 3 seems the best to me.
I always kind of inspect major sites and look at some of the techniques they use. They tend to keep the cookie count under 20. Is there anything bad about option 3, or is it the way I should go. Thanks!
If you use cookie, you can expect that there is some other person who uses the same machine, the same user account, the same browser, the same settings. There can be also a person who uses different browsers. There can be also two persons who share two computers.
If the users log in you can use sessions, it is cookie, of course, but you can identify the user, so he knows "it's not me".
And about performance: if you set your cookie, it takes also time to get it and then send it, via http headers and responses. But the best idea would be to benchmark this. Because of the small time to access db and for the reasons I stated before, I would use the db.
Store it in the db. If the user logs in on a 2nd machine and changes the status, the wrong status will show when they go back to the 1st machine.
Without the details on how people access the site, whether they are logged in or not, it is hard to say but I would agree with you on the 3rd option - query the cookie first if there i nothing, query the database - which works as long as no two people use the same computer session.
Another option that may work (or not depending on your web app) is to have individualized links. This can work nicely if people come to your site from email links with a url similar to this http://example.com/[eventid]/[uniquecode]
HiI am at prototype stage. For the scenario below, I want to share my plan with you and I am asking your opinions if my plan makes sense or is there any better way to achieve my requirement that you may recommend. thanks, regardsSCENARIOA spam bot can haunt my forms. (mail, comment, article sharing) At the verification stage, I can detect if it’s a spammer by known methods. (captcha, time limit, secret question, hidden form element etc.) but what if the spam boy tries and tries continuously? It won’t able to validate and excute the form aim but it’ll consume the bandwidth continuously. MY REQUIREMENTNot only prevent to execute the form aim but also prevent bandwidth consumption on a continuous base. MY PLANUsing session abilities, count the number of attempts of the specific ip in a limited time. If the number of attempts is greater than n in x minutes, then redirect the visitor to a totally different url or ban the visitor ip at run-time with php codes. MY QUESTIONS
Is it logical to redirect the spammer to a totally different url? If
yes do you know any web page that welcomes the spammer IPs in order
to add them to their blacklists? In other way I am aware that this
activity will not be ethical so I must not apply this kind of
redirection.
Is it possible to ban an ip at php runtime in my related
verification pages?
1) It seems illogical to me. For example imagine brute-force bot that would try to get through your captcha. Most propably it will not even run in a web browser. If you send redirect headers, it might just ignore them and not load the target page. If you really need to save bandwidth, you could simply print blank page (for example you could use exit())
2)It is possible to ban ip anytime, you allways have $_SERVER['REMOTE_ADDR'] variable and if you decide to ban the ip, you can just add it to database (or file). And whenever somebody needs to be verified, you can query the database for their ip.
I want to have an Online user counter but something which performs real time. I mean when someone comes in, the counter updates, or when someone leaves the site, the counter decrease.
I can't find anything like this on net. Is there any script for this ?
You could probably keep a list of all sessions in a database and update the "online time" every time someone hits a page. Then check how many sessions were updated in the last x minutes. However, this won't be very real time: depending on the amount of minutes you defined it will be a little bit off.
Even Google Analytics (the new real time version) gets it wrong sometimes. Don't worry too much if you can't get it right either. ;-)
You should have a look to WebSocket. There is a lot of demos out there, mostly real-time chat application, you could hack something on it :)
In my opinion, WebSocket seems a bit overhead in you case (you just want a number, no real two-sides communications) but it's the good way to do "real-time" apps.
Here are some links:
Socket.IO (node.js backend)
WebSocket and Socket.IO
Introduction to Server-Sent Events (another technique)
phpwebsocket
as far as i know there is no way to track when a user leaves your site, short of a log out button (which one can easily avoid by simply closing the window)
To expand on Tom's answer, you could create a table that tracks sessions in a database. At minimum the fields should be session_id, ip_address, activity_time. Name them whatever you'd like. You would need a function that executes on every page load that matches a record on session_id and ip_address. If a matching record does not exist, you create one; if a match is made, then update the time.
A few caveats:
1) getting the right ip address can be tricky, especially with AOL users and/or proxy users. You need to look for X_Forwarded_For headers. If they exist, for a user, use that address, otherwise use $_SERVER['REMOTE_ADDR']. I would suggest looking up X_Forwarded_For for your setup because Im not sure its available for all setups
1a) if you dont get the right ip address, some users will create a new entry on every page view
2) You need a way to remove stale sessions. I suggest as part of the function that updates the activity time, it also checks for any activity_time that is older than 5 minutes (I use 15 minutes) and if so, removes the corresponding record.
Then all you need to do is a simple count on the table and that will give you a reasonably accurate representation of the number of users currently online. With very little coding you could put this to a lot of uses. On a dating site I created I added an extra column to the table and was able to display an online icon next to users that were logged in, the same in search results to show users doing searches what users were currently online. with a bit of imagination it could be used for a few more scenarios.
Also, with a membership feature, when a user logs in you can update the session table to show that they are a member rather than a guest and if the user logs out you can remove the session from the table. Its best when a user logs out but stays on the site that you generate them a new session for security purposes. This is a bit more than what you were asking for.
You have the browser leave an HTTP connection open to your server for some unused resource (like /usercounter) that your server never responds to. Then you count the number of open connections. You can have the request send a cookie associated with the user's session so you can know if the connections are all unique users. This solution is very difficult and you will likely not find any ready-to-go solutions for implementing this.
The solution above will get a count of users who have javascript enabled. For other users, you would have to have some sort of guesstimate of how long a user would be around and update that timer on each page load.
I'm coding a sweepstakes entry form in php where the User submits some information in a form and it is stored in a database.
I would like to find a way to restrict this form to one submission per person. Either dropping a cookie or by IP address. What would be the best way to approach this?
I'm building it on code igniter, if that makes any difference.
Simple answer, log the IP in the same row with the information store. If you do a cookie a bot or user can easily remove the cookie destroying your protection scheme. So simply log the IP address and then query each entry for uniqueness before accepting the submission.
They both have their own downsides tbh. Cookies are easy to forge and easy to remove which will allow multiple votes. Restricting by IP is better but IP addresses can be shared within networks and can also be proxied to avoid detection. Best bet is rely on something like email address and force the user to click an emailed link to confirm a vote, admittedly though this isn't great.
There are several methods you can use to mitigate against casual cheating. In my view you should not expect to be able to stop a determined cheater without a more formal validation process (cc authorization..etc).
The easiest approach is to ask for a residential address to send goods when they win :)
First and foremost deny the cheater any feedback channel to be able to tell if their submission was accepted or rejected. If there is a slight delay for accepted entries make sure you add a fake delay with some jitter so they can't tell if their scheme for thwarting your anti-cheating method worked or even if you have any anti-cheating methods at all. Detecting bulk submissions by a cheater are much easier when they don't feel they need to be creative.
IP Address as you mentioned. Perhaps use geoip, whois..etc to get distributions over time WRT area.
User agent and system fingerprinting - there is a huge amount of information you can get from the browser that may or may not be unique. Browser type, version, operating system, screen resolution, color depth, installed fonts, plugins (flash, pdf, java...etc) and associated version numbers, language, browsers local time (log client clock skew)
Use of cookies, perhaps hide references to an innocent sounding domain in an included javascript you also control. This may be used to correlate the manual deletion of obvious cookies with the hidden cookies. Its less known that cookies can also be stored in separate databases of other plugins the user may have such as flash player. These are NOT removed when the browser cookies are deleted.
Use of images with cache headers. The first time a user visits the site display an image after their entry is submitted. If they've already filled out the form and they submit again the image would be cached and you can use the absence of the image request to assume submitted entries are a result of cheating.
Why not drop both. Throw a cookie on the user's machine. Then, in a database keep a field with an ip address. That way, if they have different ip addresses (due to certain internet company configs), the cookie can catch it. The database field will serve to be more secure and a backup if people don't allow cookies. These solutions will not be 100% foolproof, however, because if a person had changing ip addresses and doesn't allow cookies, you could run into problems. I would check for cookies being enabled to get around this. Try to set a cookie and read it. If you can, you're good to go. Otherwise, prompt them to allow cookies.
Best of luck
To add to the others, you could require a login/signup to vote.
As stated by others cookies are easy to fake / delete. The client IP seen for a single user can change even mid session, and there may be thousands of users sharing the same client address.
Email addresses are harder to forge - and you can add a verification stage to the process - its information you need to capture anyway - but do keep track of the user agent and client address each submission originates from and is verified from - then you can make a smart determination about the winner instead of trying to check every submission.
C.