How to validate a contact form using JavaScript? - javascript

I've made a contact form:
<form action="mailto:myemail#me.com" method="post" enctype="plain/text">
<label for="name">Name:</label> <input type="text" name="name" />
<label for="email">Email:</label> <input type="text" name="email" />
<br clear="all" />
<input type="submit" value="Compose" />
</form>
I want to create a javascript form validator without having to use a server-side language like PHP. Any ideas?

This is a bad idea. JavaScript and JavaScript validation can be bypassed in a number of ways.
The user could tell the browser to not execute any of the JavaScript on the page. If the form itself does not rely on JavaScript, the form will still show up, and the action page will still be there, but all your validation is gone.
The DOM can be edited by the user. Web page developer tools like those in Chrome, Firefox, and IE make it a cinch to change attributes of a form. This includes removing attributes like onsubmit from a form. Or, the user could simply remove JavaScript function from the resources used by the webpage entirely. This allows the user to avoid going through validation.
A user can send POST or GET data directly to the action URL without going through your page. This is great for attackers, since they can inject a malformed form into your server without even going through a browser--they can use a terminal instead, which is much more convenient.
In summary, do not do this. Allowing the user to control validation is a bad thing. Users can turn off client-side JavaScript, but they can't turn off PHP server-side validation. Use PHP validation if you don't want to suffer from embarrassing cross-site scripting attacks and other vulnerabilities.
If you are looking for a PHP form validation library, you can find a number of them around the Internet. For instance, I personally have contributed to one such library that does a good job of evaluating fields in either a POST or GET type form. I apologize for the self promotion, I must insist that you do server-side validation for the sake of security.
That isn't to say that client-side validation is awful and should never be used. But it should always be backed up by server-side validation. You should view client-side validation as a way to inform the user that there is a problem with their form input without reloading, but always use server-side validation to actually look at the input for problems.

Take a look on this live example.
$('#form1').submit(function() {
// Store messages
var msgs = [];
// Validate name, need at least 4 characters...
var name = $('[name=name]', this);
if(name.val().length < 4) {
msgs.push('- Name need at least 04 characters;');
}
// Validate email [...]
// {CODE}
// Validate otherthings [...]
// {CODE}
if(msgs.length !== 0) {
alert("We have some problems:\n\n" + msgs.join("\n"));
return false;
}
});​

be careful not to mix things up. you want to do client-side validation, which is nice-to-have, but not as required as server-side validation, which you can only do on the server.
any script-kiddie will still manage to post some crazy data to your server, so you will have to check your requests and sanitize the data on the server-side.
BUT, if you want to do validate your form data before submitting (which is definitely a good standard), you should use one of the many available jQuery plugins to get the biggest bang for the buck.
here is one: http://docs.jquery.com/Plugins/Validation#Example
if you don't like to use jQuery, you can always specify onBlur=myFunction() to execute whatever logic you need when an input field loses its focus.

Related

How to prevent fake form validation

So I have page with simple form. To submit this form I need person submitting to check checkbox (some privacy policy etc).
I have the form like this:
<form role="form" class="form" id="zamowienie" action="send_order.php" method="post">
<button type="button" id="wyslijZamowienie">SEND</button>
<input type="checkbox" id="regCheckbox" value="">
</form>
(Of course, every distracting inputs are deleted.)
Then I have script that shall submit form only after checking the checkbox.
button.on("click",function(){
if ($("#regCheckbox").is(":checked")) $("#zamowienie").submit();
Unfortunately, I found out that user can change localy the button type from "button" to "submit" and he will be able to submit the form ignoring my submit protect script.
And additional question. I am not an expert but I started wandering what else can do user with FireBug or dev tools. Can he perform any attacks this way?
Many thanks for any answers or guidance.
The user is able to change your form in many other ways, not just changing the type attribute of the button, the best is to check it on the server side too, for example, you should do something like this:
Validate via Jquery:
$("#zamowienie").submit(function(e) {
if(!$('input[type=checkbox]#regCheckbox:checked').length) {
//stop the form from submitting
return false;
}
//Continue and submit the form
return true;
});
Validate in the backend:
If you are using PHP in the backend for example, you have to check if the checkbox is checked, with something like this:
Note: Your checkbox need a name attribute, let's say mycheckbox
if (isset($_POST['mycheckbox'])) {
//Process your form
}
else{
//Checkbox was not checked, print an error message or something
}
Always validate your code in the backend, the Javascript validation is just a plus for usability and User Experience.
That's one of the reasons why you always validate on the server.
There's no problem validating on the FrontEnd, but you need a double check from the server so you guarantee that all the data is as you expected.
As for the Firebug/Chrome Dev Tools question, anyone can pretty much edit everything from your FrontEnd. From CSS to JS. Even if you minify it!
Consider that the user can do everything he wants. He can modify everything in your form or even create another one targeting the same url and create a script to submit it 1000 times.
That's why you often read :
Never Trust User Input
This means you have to check the whole request on server side : check the method used, check that the fields you are expected are set with data types that you expect.
To summarize : Front end is just here to help the "usual" user to communicate with your server, but on server side (back end), you have to expect every input possible.

Defeating spam registrations

I am trying to learn as much as possible about running a high-profile website. I designing some user registration screens and was thinking about the typical CAPTCHA, or annoying alternatives. In my opinion, having them either causes accessibility issues, or simply bothers potential customers and inhibits their registration process.
My question is whether spambots recognize and trigger JavaScript events, such as the keydown or keypress event on an input field. From what I can gather, most bots simply do form posts via the action attribute and don't programmatically "fill out" web forms.
In theory, I could add JavaScript that something like the following:
<input name="email" />
<input name="human" type="hidden" />
<script>
var emailField = document.getElementById( 'email' );
emailField.onkeydown = function( ) {
document.getElementById( 'human' ).value = "human";
};
</script>
Then, on the server side, I could verify that the post data includes a value of "human" for the hidden form field.
Is this a viable solution, at least as effective as typing in a bunch of random, difficult-to-read characters? Would using a random generated value from the server be more helpful in repetitive attempts than a static value of "human"?
Most spam bots will simply look for a <form> on your page and then post data directly to the URL specified in the action attribute. This is very simple, lightweight, and easy to do.
Some spam bots will actually use a headless browser (such as PhantomJS) which executes JavaScript on the page. These spam bots are much harder to fool, but few bots use this method since it is much more expensive (in CPU and RAM).
I've found that it's generally fine to go for blocking the most common spam bots through a honeypot (field on the page that is removed programmatically, and other similar methods). Some bots will get through, and anyone who does manual analysis to find a way to exploit your page will still get in. For most sites, this is good enough, and provides a good balance in preventing spam while keeping your site usable.

Can a form with a disabled <input type="submit"> be hacked to submit anyway?

I'm just curious about the security of the <input type="submit" /> tag.
If I have a form (with method="post") with just one "Submit" button, which is disabled, and I haven't written any JS/AJAX/jQuery that affects the form, the button, or its other contents, could someone still find a way to submit the form?
Here's the code for a form along the lines I'm talking about:
<form method="post" action="processor.php" enctype="multipart/form-data">
<input type="text" name="foo" value="bar" />
<input type="submit" value="Submit" disabled="disabled" />
</form>
Thanks much!
Yes, I don't even need your form to submit it. I can use cURL or a similar library to just send a POST request as if it came from a form.
Always validate everything server-side, you don't always get what you expect.
Anyone skilled enough with the 'Element Inspector' of most modern browsers can add/edit/remove any attribute and their values.
Using this method I can remove the disabled attribute and then just click the submit button
That and you can run javascript through the console or the address bar/bookmark like this
javascript:document.getElementsByTagName("form")[0].submit();void(0);
Forms can also be submitted using server-side libraries like cURL
Anything on the client can be hacked. Don't trust the client. Always validate on the server.
For example, Tampermonkey.
Sure. Typing this in the console (or in a bookmarklet) will do it, with all modern browsers including IE8 and above:
document.querySelector("form[action=processor.php]").submit();
On older browsers, if it's the first form:
document.getElementsByTagName("form")[0].submit();
If it's harder to find (not the first form), then on older browsers it might take a couple more lines of code, but that's all.
Yes, they absolutely could.
As a general rule, don't rely on anything client-side for security. A malicious user can and will manipulate any client-side code.
You need to make sure everything is secure on the back-end, regardless of what requests your front-end code makes.
Other answers state that you can submit the form directly without using your form, which is also true. I just wanted to point out that, in addition, the user could un-disable your button and then click it, as well (using Firebug or equivalent). Any html or other text you send to the client, they can modify however they like.
Disabling buttons client-side is great for increasing usability (disabling during ajax updates, or if there are required fields missing values, for instance), but it shouldn't be part of your toolkit for anything security-related.
Yes, they can simply alter the HTML and enable the form by changing $disabled="disabled"$ to $disabled="false"$. Set your server not to accept invalid input.

how do i identify from what website a user submitted a form?

I want to identify from what website a user has submitted a contact form.
The contact form is an include file (.shtml) and this file is being used on two different websites. Since it's only one file (include), will a javascript if...else statement or switch statement do this? If so, how would it be written?
I'm new to JavaScript and haven't had to write much so would appreciate help with the syntax.
I thought about adding two hidden fields on the one include contact form, with IDs of the two different sites:
html
<input type="hidden" data-id="new_student_signup" name="student_signup" value="" />
<input type="hidden" data-id="existing_student_signup" name="existing_student_signup" value="" />
js
if(data-id="new_student_signup"){
// this user came from the new student website
code if this condition is true
}
else if(data-id="existing_student_signup"){
// this user came from the existing student website
code if this condition is true
}
Or should I just create a new include file for the other website and add the hidden field to that file instead of using javascript on one include?
I'll admit, that seems easiest for a JavaScript novice like me, but I do like the idea of learning more JavaScript.
You can do it using server side scripting by checking HTTP_REFERRER.
PHP example
<?php
if(!empty($_SERVER['HTTP_REFERRER']) && $_SERVER['HTTP_REFERRER'] == 'http://google.com/')
{
// proceed accordingly
}
You might want to distinguish referrer based on the domain name or more specific data in the URL rather than the whole HTTP referrer string. In that case, take a look at http://php.net/parse_url.
You can do it using JavaScript as well by accessing document.referrer property.
You could do this in javascript by checking the document.url property and putting that into a hidden input field. However, I think you'd be better off just checking this in server side programming code. You can just check the current server you're on and use that to determine which form it is. You can do this by getting the SERVER_NAME server variable, this will tell you the domain you're currently on.

Spam Prevention/Reduction - Contact Form?

I want to add a simple Contact form to my web site so that customers can contact me easily.
<form>
NAME
<input type='text' name='name' />
EMAIL
<input type='text' name='email' />
MESSAGE
<textarea name='message' />
<input type='submit' />
</form>
This form would simply email me the customers message.
But, I also want to reduce (not, I'm not saying eliminate but at least reduce), SPAM.
I've looked into using CAPTCHAs but, ultimately, I don't want to hinder the customer with having to fill out extra information.
Any ideas of a good simple spam prevention/reduction method I could use for my Contact form.
A very simple trick I've been using with a surprisingly good success rate is this: Provide a text field that is hidden from human users with style="display: none", but with an enticing name like email. Most bots will fill in something in this field, but humans can't see it so they wont. At the server, just make sure the field is empty, else treat the submission as spam.
If you want to do a completely front-end solution I have had success recently by leaving the form action attribute blank, and populating it via a $(document).ready function. Most spambots use a browser that has javascript disabled, or are looking for hidden fields to avoid detection.
Example:
Your html would be:
<form method="POST" action="" id="contact-form">
and anywhere in that page you can use this to populate it.
<script>
$(document).ready(function(){
$("#contact-form").attr("action", "/yourMailScript.cgi");
});
</script>
A bot browser with no javascript will not get a form action, and they will get a 404 upon submission. Anyone with a normal browser (unless they have JS disabled for paranoid reasons) will get the normal behavior.
The only (client-side) way other than a CAPTCHA type user confirmation would be to write the whole thing dynamically. A lot (but not all) of robots would probably ignore the dynamic content. Eg
document.write("<"+"form>"
+" NAME "
+" <"+"input type='text' name='name' /> "
+"EMAIL "
+"<"+"input type='text' name='email' /> "
+"MESSAGE "
+"<"+"textarea name='message' /> "
+"<"+"input type='submit' /> "
+"<\/form> ");
Use Google or Yahoo mail account. They have good anti-SPAM filters.
Hidden fields, silly questions (what is 3+4?), etc, are not very effective at blocking spam on forms, IMHO.
I researched this several years ago, and came up with a solution I call "FormSpammerTrap". It uses JavaScript code to 'watch' for focus/onclick on required fields. Automated processes, unless highly customized for a specific site (which takes more time than spambot owners want to take), can't 'focus/onclick' a required field. (And there are some other techniques I use.)
I have a free solution at my www.FormSpammerTrap.com site. And there's a form there that spambots can try to spam...and they haven't, for more than 3 years. You are welcome to try it out...it's all open source, so you can see how it works. (And, if you use the form, I don't harvest your email. I reply once, then delete your email.)
My technique is much more effective in blocking spambots, IMHO. They haven't been able to spambot the contact form on that site.
**Added 12 Jul 2018 **
The trick is to add an on-click/on-focus event that changes the action parameter to the actual processing page. Otherwise, the default value I use is a honeytrap-type site. I think it's hard for a spammer to simulate those events, although possible perhaps. The technique blocks a lot of bot-spammers.
And still, after a couple of years using the technique on that site, the form hasn't been spammed by bots. (I define a bot spammer that sends multiple submits via the attack, not just one submit.)
Works for me.
You can add simple question, each serious person who wants to contact you, can easily answer. For example a field where he should enter the first letter of the domain. Most bots don't understand the question and will enter nothing or something random.
You could also try to track the time how long the user needs to input data. If he tries to send the form earlier than 5 seconds before typing the first word just don't allow to send it. Bots usually just parse the site, fill out everything and then post it and go to the next website.
#sec {
visibility: hidden;
padding: 0;
margin: 0;
height: 1;
}
<form method="POST" action="www.google.com">
NAME
<input type='text' name='name' />
<br /> EMAIL
<input type='text' name='email' />
<br /> MESSAGE
<textarea name='message' /></textarea>
<br />
<input type='text' name='security' id='sec' placeholder="Do not enter anything here" />
<input type='submit' formaction="" />
</form>
**Here, only a user who clicks on the submit button actually could submit the form. using auto submit simply redirects the bot to google.com.
**
*Also the input 'security' is an input field that is hidden to users, and visible to certain bots, known commonly as HoneyPot Captcha. On the server side, you can simply skip all the requests that has the 'security' field filled. Not every bot can be tricked this way, and this is where the attribute formaction comes into play *
grep for URI methods, urlencoded characters, or the two HTML markup characters, seems to work.
Use an anti-spam API like Akismet or Cleantalk. You can use the traditional checks for less sophisticated bots before hitting the API. An anti-spam API is the only way to catch spam submitted by a human.
I think that nowadays, most of the solutions posted are either inefficient or outdated.
reCAPTCHA is not a hassle for users any more
google documentation
reCAPTCHA v3 returns a score for each request without user friction.
The score is based on interactions with your site and enables you to
take an appropriate action for your site.
OP states that he needs an alternative to CAPTCHA, in order to avoid hassle for his users (up to v.2, reCAPTCHA requires user interaction). However, as of v.3, reCAPTCHA can detect bots "silently", without requiring user interaction.
Front-end-only solutions are inefficient
The honeypot (hidden input that only a bot could fill) and simple questions methods, as well as other front-end implementations, are still vulnerable to spam attacks. First of all, the spammer can bypass all front-end and post directly to the server. Therefore, a server-side check is required.
In addition, if someone wants to spam your site, specifically, he can easily read your source-code and build a script that is "clever" enough to not be caught by the front-end protection.
On the other side, reCAPTCHA v.3 tracks data and works behind the scenes, in Google's back-end, to determine if the user is actually human. Its logic is hidden, therefore, the attacker can not easily develop a "smarter" bot. In addition, the attacker can not just bypass the front-end; a token is created, is passed server-side and then to Google's back-end to be validated.
TL;DR
Nowadays, reCAPTCHA seems to be the best solution in all aspects. No user friction and the most secure.
Use JS technology. Like if a user comes on your contact page then javascript will generate a string or anything like that you prefer and put the information on a hidden text field. But it is not the actual solution, smart bot can easily crack it.
Another way is, You can also use email verification after contact form submission. And store the data on your database. If customer verifies the url through email then the contact information will mailed to you from database.
And also use delay to prevent continuous robot attack. Like sleep() in PHP code. This will add few delay in your code. By this way you can reduce random attacks but this is not the prevention method.
I found a nice idea on this page:
http://www.evengrounds.com/developers/alternatives-to-captcha
You can make your SUBMIT button display a confirmation page, on which you explain to user that he has to hit CONFIRM button to actually send a message. Spambots would usually only submit first form and skip the second step.
If you dont want to use recaptcha then you can use a service like Real Email and validate the emails server side before processing. Keep in mind that your probably want a way to report to the user if there is something wrong with the input.

Categories

Resources