I have a PHP contact form mailer on my website. The contents don't store in a database, but are emailed directly to me. I have received a couple strange contacts in the last few days.
The user has to fill in name, email, confirm email subject and message.
I have a javascript security in place that verifies an email is typed in the same twice, and checks for the # and the dot. Also, required fields are checked with javascript.
Here is the most recent message-you can see it is a bunch of bogus links, etc. Is this anything I should be concerned of from a security standpoint?
Name: fvjnqazcy
Email: cervau#fbcalj.com
Email confirm: cervau#fbcalj.com
Phone: 47668113220
Subject: uSMvoegKPt
Message: KU17Gd lsyixbpcjddi,
[url=http://sojlxycrnxlb.com/]sojlxycrnxlb[/url], [link=http://wesixtcvuzbj.com/]wesixtcvuzbj[/link], http://dcgfyjhpfpbx.com/
It looks more like a spammer to me. If you have more of these messages than you can handle, you need to add a CAPTCHA to your contact form. I don't think it's intended to exploit a potential security issue in your application though.
Yeah, I agree with Mehrdad, it just looks like a random spam bot. Don't ask why they are doing that; I don't think there is a real reasoning for them to add spam..
I have a javascript security in place that verifies an email is typed in the same twice, and checks for the # and the dot. Also, required fields are checked with javascript.
You really shouldn't do any important checks with JavaScript. Or at least not without testing them on the server side as well.
JavaScript is easily disabled and then all your checks will fail. Especially bots never interpret JavaScript, so all your checks won't be made and all input is just accepted as it is.
To prevent spam in general you should gradually add more security checks on the server side. One rather hard option is adding a CAPTCHA, but moving those checks to your server first will probably help as well (given that the bot enters two different email addresses).
Related
I have a form that takes user input of basics such as name, email, location, and then sends an email with these values formatted into a table, for internal use. I was wondering what the security issues involved here are, and how to account for them as close to 100% as possible? I'm using PHP and its mail() function.
So far, all I have is strip_tags applied to all the inputted data. Other than that, there is nearly no validation other than char length count, but even those are fairly large (ex. 80 for name and 255 for email; name having no other validation so as to not cause trouble for foreign names, and email using FILTER_VALIDATE_EMAIL).
Note -- there is no db query (and if there was, I would use a prepared statement as the safeguard for queries), BUT it will be connected to one, if this affects anything.
Thank you very much for your time and help!
try using a Captcha to be able to avoid people using it to spam.
Take a look to recaptcha. its a free CAPTCHA service that helps digitize books, newspapers and old time radio shows. They have useful information in their Webpage.
The only thing i can think of right now is to add captcha or something to be secured from spammers.
I would make sure that the combination of PHP functions that you are using, and the SMTP server combination is not vulnerable to SMTP Injection.
Otherwise it may be possible to hijack your mail server to send emails or spam to any address. A CAPTCHA would mitigate this somewhat, but even so you do not want the mail server being vulnerable even if the CAPTCHA response is correct.
I've searched this site for similar answers and I still can't make up my mind. Also I'm new to this site.
I'm in the process of developing a PHP script to allow users to register. After they register they are sent a email with a token to validate that they have access to that email saying it is valid and it will mark them as 'valid users' otherwise it will delete that entry after a set time. What I'm wondering is if a custom REGEX that I made (which works fairly good for the most part just needs tuning every now and then) or if filter_var with FILTER_VALIDATE_EMAIL is better than my custom REGEX. I know that if you send too many emails that bounce back you might be marked as a spammer site and my client wouldn't like that too much.
Anything else that might help would be great help to me.
I would use Filter_validte_email if you don't have a lot of experience validating email or writing regex. It is also important to remember that any regex or filter will not prevent emails that bounce back, they will only check to make sure the entered address looks like it should. Thus you will get a valid check on noaddress#nodomain.tld even though this clearly will not be delivered unless nodomain.tld happens to exist and there happens to be a user noaddress with a mail account there.
See How to check if an email address exists without sending an email?
What are the consequences of not validating a simple email form on the server.
Keep in mind that:
javascript validation is being carried out
there is no database in question, this is a simple email form
The PHP code I would like to use is this:
<?php
$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS );
$full_name = $post_data["full_name"];
$email_address = $post_data["email_address"];
$gender = $post_data["gender"];
$message = $post_data["message"];
$formcontent = "Full Name: $full_name \nEmail Address: $email_address \nGender: $gender \nMessage: $message \n";
$formcontent = wordwrap($formcontent, 70, "\n", true);
$recipient = "myemail#address.com"; $subject = "Contact Form"; $mailheader = "From: $email_address \r\n";
mail($recipient, $subject, $formcontent, $mailheader);
echo 'Thank You! - Return Home';
?>
Would a simple captcha solve the issue of security?
UPDATE:
A few questions I would really like answered:
If I am not worried about invalid data being sent, what is the absolute minimum I can do to improve security. Basically avoid disasters.
I should probably mention that this code is being generated in a form generator and I would like to avoid my users getting attacked. Spamming might be sorted by adding Captcha.
UPDATE:
What is the worst case scenario?
UPDATE:
Really appreciate all the answers!
A couple of things I plan to do:
add this as Alex mentioned:
filter_var("$post_data['email_address']", FILTER_VALIDATE_EMAIL);
add simple captcha
If I did add simple server side validation, what should I validate for? Cant the user still send invalid data even if I am validating it?
Also, will the above stop spam?
No validation occurs when there is no javascript present, might as well not have it...
Do you think spam bots have javascript enabled?
Extra note on would be attackers
If I were attacking your form, I would first see your javascript validation.. Next I would turn javascript off and try again...
The Consequences of only using client side validation are the same as not using validation at all...
Would a simple captcha solve the issue of security?
Not unless it's server side...
In general if you are just playing around and don't care, you don't need validation at all.
Having client-side validation is pointless and you will just be wasting your time. The client-side only approach will get you in trouble. You can't trust your users that much.
If you plan to actually release this or really use it on a live environment, you must have a server side validation. It is well worth the time since this is a simple form now, but it may grow to be much more than that. In addition, if you take care of your validation now, you can reuse it later with other components of your application/site. If you try thinking if terms of reusability you will save your self countless of hours of development.
There are also obvious issues such as injections and javaScript issues, as mentioned by other users.
In addition, a simple CAPTCHA does not cut it anymore. There are some nice resource regarding CAPTCHA.
Take a look at those.
Coding Horror
Decapther
So the simple answer of your questions is that you are certainly vulnerable in your current situation. I know that more development takes more time, but if you follow good development practices such as reusability and orthogonal/modular design you can save yourself a lot of time and still produce robust applications.
Good luck!
UPDATE:
You can add FILTER_VALIDATE_EMAIL to take care of the email validation and you can read more about the email injection and how to take care of it here: damonkohler.
As for the CAPTCHA, it could solve the problem, but it really depends on how valuable of a target your form/site is. I would recommend using non-linear transforms or something that is widely used and proven. If you are writing your own you may get yourself in trouble.
Summary:
Validate Email
Still make sure you are save from injections
Make sure the CAPTCHA is strong enough
Really Consider server-side validation
UPDATE:
#kht Did you get your questions answered? Let us know if something was unclear.
Good Luck!
UPDATE:
OK, I think we have made you a bit confused here with this whole client-side/server-side fiasco. I will try to break it down now so it makes more sense. The first part explains some basic concepts, and the second answers your questions.
First, PHP is a server-side language. It runs on the server and when a page request is sent, the server will "run" the PHP script, make any changes to the requested page, and then send it to the user who is requesting the page. The user has no access/control over that PHP script. On the contrary, as discussed earlier, the client-side scripts, such as JavaScript can be manipulated. However, just because you have some PHP script running and checking something on a form, that does not mean that the form is secure. It only means that you are doing some server-side processing of the form. Having it there, and making it secure are two different things as I am sure you have already figured out.
Now when we say that you need server-side validation we mean that you need a good one. Also, in this hectic Q&A format nobody really mentioned that there is a difference between validating data and sanitizing data.
sanitizing - making the data meet some criteria
validating - checking if the data meets a criteria
Take a look at phpnightly for a better explanation and examples.
There are also some nice simple tutorials describing how to create basic validation of a form.
nettuts
Very basic, but you should get the idea.
So how do you approach your current problem?
To begin with, you should keep what you have in terms or client-side validation and add the CAPTCHA as you mentioned(check my post or you can research some good ones).
What should you validate?
a. you should validate the data: all fields such as email, name, subject...
check if the data matches what you expected: is the filed empty?; is it an email?; does it contain numbers?; etc. You can validate the data on the server side for the same things you are validating it on the user side. The only difference is that the client cannot manipulate that validation.
b. you could sanitize the data as well
make it lower case and compare it, trim it, or even cast it into a type if you need to. If you have time to check it out, the article from phpnighty has a decent explanation of the two and when not to use both.
Can the users still send invalid data?
sure they can, but now they have no access to the validation algorithm, they can't just disable it or go around it.(strictly speaking)
when the data is invalid or malicious, just inform the user that there has been an error and make them do it again. That is the point of the server-side validation, you can prevent the user from circumventing the rules, and you can alert them that their input is not valid
be very careful with the error messages too; don't reveal too much of the rules you are using for validation to your user, just inform them what you are expecting
Also, will the above stop spam?
If you make sure the form is not vulnerable to email injections, you have client-side validation, CAPTCHA, and server-side validation of some form(it does not have to be super complex) it will stop spam.(keep in my that today's great solution is not so great tomorrow)
Why the hell do I need that server-side bull* when my client-side validation works just fine?*
Think of it as having a safety net. If a spammer goes around the client-side security, the server-side security will still be there.
This validation thing sounds like a lot of work, but it is actually pretty simple. Take a look at the tutorial I included and I am sure the code will make things click. If you make sure no unwanted information is being sent through the form, and the clients cannot manipulate the form to send to more than one email, then you are pretty much safe.
I just wrote this one out the top of my head, so if it is confusing just put some more questions or shoot me a message.
Good Luck!
Without validation they could use injection to add in values such as CC: and BCC: to send emails to multiple other people via your form. So I would recommend the least you do is add in:
filter_var("$post_data['email_address']", FILTER_VALIDATE_EMAIL);
If you check the email is valid, the worst they could do is send you invalid data.
JS validation is excellent, as long as the browser supports JS. Unfortunately there are still browsers that lack on JS support.
But, when you do not perform serverside validation, you expose your mail() to injectors. I can create my own nastyFile.html within which I place a formular wich action="http://yousite.com/yourEmailHandler.php" and by doing that I might am able to omit your JS validation
Anyone can spoof their HTTP GET/POST requests:
netcat is enough to build a simple GET request
simple python/perl scripts are enough to craft modified POST submissions
Firefox (and likely many others) have plugins that do just that from the browser (e.g. TamperData)
javascript can be readily enabled/disabled/altered aat will using convenient plugins like
IE developer toolbar
Chrome dev toolbar
FireBug
Opera DragonFly
It's just making things too easy. There could be all kinds of motives. You risk getting tampered (inconsistent/unclean) data in your database. You risk getting DoS-ed (e.g. by receiving crafted responses that bring down the server, or just hold a request handler (thread) for a long time resulting connection timeouts)
This is scratching the surface only, because once your site isn't secure, there is no telling what that can be leveraged for.
By using filter_input_array(), you are doing some server-side validation (or sanitization, which amounts to the same thing in this case). Also, by hardcoding the recipient e-mail address, you've plugged the worst and most common hole in typical e-mail forms. Whether by luck or by design, it looks like those might actually be enough in this case.
In general, vulnerabilities in e-mail forms can be divided into two broad categories:
tricking the script into doing something other than sending e-mail, or
tricking it into sending e-mail to the wrong address (spam).
In your case, all you're doing with the user-provided data (as far as the code you've showed us goes, anyway) is passing it to mail(), which is hopefully free of major security holes. (But then again, this is PHP, so...) As for tricking your script into spamming the wrong recipient, there are (again) basically two ways to do that:
if the client can supply the recipient address, a spammer can just pass in whatever they want;
otherwise, they can use e-mail header injection to insert bogus recipients (and other content), generally by injecting line breaks into the data.
Fortunately, you've hardcoded your e-mail address into the script, and the sanitization method you've chosen (FILTER_SANITIZE_SPECIAL_CHARS) replaces line breaks with HTML character entities. So it looks like you might be safe from both of these attacks. Of course, someone could still use the form to send (more or less) arbitrary e-mails to you, but presumably that's a risk you're willing to take.
All that said, though....
I'm hardly infallible, and there might be potential security issues that I've missed in my analysis above. In general, the stricter you are in checking your input, the less likely you are to be vulnerable to unexpected attacks. For example, I'd very much second the suggestion given by others here to apply an extra validation step to the user-supplied e-mail address (and, more generally, to any data that might end up in the e-mail headers).
One consequence may be if the browsers javascript is off or some expert user using firebug or some other tools change the behavior of the javascript validation than you may get a useless information
Javascript might be disabled
A person could put anything in the mail header in your code.
That is a security risk
EDIT:
$post_data contains the items from the form - $email_address being one that makes up the $mail_header. You can use that to inject stuff into the mail header.
I'm adding a feature to my site to allow people to invite their friends. I was going to accept a commma-separated list and allow them to import their Gmail contacts.
My question is, how do i prevent someone from just posting a string of emails to my script and essentially A) overwhelming my mailserver or B) spamming a bunch of people. Obviously, captcha would help with this, but just curious if there's other ways to limit our risk...
Since the contacts/etc are all on the front end, there's no way to hash it using our sites encryption key...so my initial thought of hashing the emails before sending them to our "sender" script probably wont work...
Any advice, help or direction on this is much appreciated!
First and foremost: Don't use a generic sender script! Any script that takes recipients and a message body from an external request is a security issue. Security is hard and you will make mistakes, opening you up to spammer. Better create several scripts that are only capable of sending a specific e-mail. E.g. a contact-us script that is hardcoded or preconfigured to send e-mail only to you. A tell-a-friend script that has a hardcoded or preconfigured message template in it.
Next, you need to be very careful about putting anything supplied by your users into an e-mail header (this includes message subjects, from/reply-to addresses, etcetera). Of course, it's nice to set the reply-to automatically to the user's e-mail address, but what if I type this as my e-mail address:
me#example.org\nBCC:spam-target#example.org
Now I'm spamming other people through your contact form, even though that form is only supposed to send mail to you.
You should treat anything that a user can put in a mail header (or message) as suspicious as you'd treat anything that goes in an SQL query.
In my registration process, the user registers, they get emailed a verification link, and if they click it, only then would their account be verified. But isn't this verification method too easy for the bots?
I think an email could be created by a bot, but for sure if the verification is just clicking a link, it could also be automated by a bot. I'm not sure since I haven't done this and don't care to test it just to know, but my question is isn't this verification method flawed?
I'm thinking about sending the verification code to the user as a text which they would have to copy/paste manually into a form AND the form is captcha protected. Is this a better idea? any flaws with it?
Most of the suggestions are about verifying emails and using CAPTCHAs which of course you should do, but keep in mind that none of these methods is completely bulletproof.
Email verification
A bot can easily "click" on links in any email. Copying and pasting something would be slightly more annoying for the bot author but not much. Generally email verification is just that - email verification.
You verify if the email is likely to be controlled by whoever tries to register, but of course since email is usually sent in cleartext over untrusted TCP and relies on insecure DNS, then until we're all using DNSSEC and encrypt all traffic it will be easy to sniff emails and spoof servers and clients. The important thing to realize is that using email verification you get only a certain degree of confidence that whoever or whatever you are talking to is really a user of that email address.
Turing test
Answering a question that only human should know the answer to would be still more annoying but considering that you probably wouldn't have an infinite number of questions, the bot author might redirect unknown question to a real human and use cached answers if any question repeats more than once. Answering a question like "what is 12+8" like I've seen in some websites lately as a Turing test is completely counterproductive since this question is actually easier for bots than for humans. Probably the most popular Turing test for that are CAPTCHAs but here you also have to realize that they can be fooled.
First of all people are showing methods of circumventing CAPTCHAs, for example see the Decoding reCAPTCHA talk from DEFCON 18. Many CAPTCHAs are much easier for robots to decipher since they are generated by algorithms that are trivial to reverse. The reCAPTCHA distortions are also pretty simple but the words that they use are real scanned words that was hard for OCRs so in principle it should be much harder for bots, but it is not always the case.
And there is also a possibility to display captchas that you want to guess on other websites and have people answer it for you. Also there is a black market of people actually solving captchas so if your bot author doesn't mind paying something like two cents for a dozen then no matter how hard it is for humans, actual humans will solve it anyway.
Bottom line
The bottom line is that using any of the bot-stopping techniques will always be a compromise of how much would a bot owner (a spammer or anyone else who wants to register a lot of users in your system) be willing to spend time, effort and money to do it, and how much inconvenience for your users are you going to tolerate, because ultimately you will never be able to do any automated test to tell humans and bots apart without actually annoying humans and alienating people with disabilities (has anyone ever tried to guess the audio version of reCAPTCHA?), and still your bots may actually be human-powered, so not really bots but cyborgs, so to speak.
It's an arms race for which your honest users are paying a price. Please keep all of that in mind.
The questions is what are you trying to verify? When you send a link to an email address, what you can know is that whoever registered that account has access to the email address. It doesn't tell you anything about them other than that.
So yeah, bots can create an account, and use it for registration. If you want to stop bots, then yeah, a captcha is what you need to add. Note that there's little point in adding the code to copy/paste - that's both easy for a bot to do, and also doesn't gain you anything over the captcha.
As always, security and convenience are generally competing with each other.
A link in an email simply validates that it is an active email address. Yes, it's easy for the bots to handle this. But is your service so valuable that bots will be attacking it?
A CAPTCHA is always the way to go to ensure your users are human. The additional coding and frustrations involved with it are a trade-off.
In the end, keep things as simple as possible, but not simpler.
As pointed out already, you simply have some CAPTCHA validation.
My suggestion is though do human validation before your app creates the user account and sends the verification email. Added value of your site can't easily be forced to just spam verification emails and create bogus waiting to be verified accounts.
Nothing wrong with a link if you do that.
Yes, bots can enter emails and check the responses. I've also heard of endeavors toward bots getting better at image recognition and answering captchas, although I can't say for sure how good they are. If you are really really concerned, I would go with:
Email verification
Captcha
Simple random questions (How many ears/fingers do most humans have?)
Cell phone number that sends a code via SMS
The last one might prove to be the best in eliminating bots, but it will also limit who signs up for your website. Also, the more validations you have, the more you'll annoy users and the more you'll increase the barriers to getting them to sign up, which could also be a pretty big drawback. Personally, I think captchas are a good balance of bot protection vs. user inconvenience.
Are you verifying an email only or doing a full registration?
I always verify the email account first. then once verified complete the registration process.
so add a captcha at the verify email step.
In other words, ask the user to enter their email address, enter the captcha and submit the form.
That way only real people get the verification email sent.
It doesn't prevent human bots of course.
DC
It also means you don't need to store failed/bad registration data.
One problem is a user validating with one email address and then changing it during the registration process, I handle that this way..
When a user submits their email address the data is not stored at all. Instead I use $validation_code = md5(trim($email)+$secret) to generate the verification code. That way they can't change the email address on the actual registration form. The email and verification code is carried as a hidden field to the end to validate the email address. if the email address is altered from the verified one, registration will fail as the md5 no longer matches.
DC
I ran into similar problems with verification emails and testing. If you want to end-to-end test email verification try EmailE2E.com — it's free.
You can send and receive emails from randomly generated inboxes via an API.
It's perfect for testing Firebase, Amazon Cognito, or other OAuth providers that use email verification codes during sign up. Plus it has clients in Java and JS.