I have a login and signup forms i handle validation with JS like showing user messages if email isnt in the right form also minimum characters number etc , the question is as everyone says we must add a server side validation to stay safe from the case user changed or disabled JS in browser , but does that means i dont need and its impossible to show this errors to client side in case he disabled JS cause its disabled ? in general do you write some logic code for that kind of simple form validation errors to user , or this validation errors are only important for developer? if user disabled JS i think react app wont work either so that doesnt make sense and thats what i see
The Server validations are just there to make sure that you are safe that basically means you should not rely on the front-end validations at all. However, you can validate the request with Clientside/JS as well so you won't need an extra call to API to validate the inputs.
In-case of disabled Javascript, you may ask the user to enable or otherwise, you will not be notified of any error.
<noscript>
<span style="color:red">JavaScript is not enabled!</span>
</noscript>
Server-side validation is must-have. It must be implemented always as it's only guaranteed it cannot be skipped.
Client-side validation is just for user's comfort, he doesn't need to send a request as basic mistakes can be catch during inputting data. Remember that it can be skipped easily within a common browser, so you cannot rely on its safety.
Always best solution is combining both: client-side for comfort and server-side for security.
I am trying to understand the steps I have to follow in order for data to be input and output securely on a website. This is what I understood so far:
**
Procedure
**
1)User inputs data
2)This data is validated using JavaScript. If data doesn’t match the structure you
requested, send an error message.
3)The data is also validated using PHP in case the JavaScript is disabled or not supported by the browser. The PHP validation will almost be identical to the JavaScript one. If data doesn’t match the requested structure, send an error message.
4)Open a connection with the database (PDO method)
5)Check input data against your database using prepared statements (PDO method) and return an error message if required [for example if the data is an email address then we cannot have 2 users with the same email address/ Error message: This email address is already registered. If you are already registered please login or use another email address to register].
6)After all checking is done [client-side (JavaScript) and server-side (PHP)], use prepared statements to insert un-escaped data into the database.
7)When data is requested and must be displayed on the web browser, only then escape (output) data, to prevent XSS.
**
Security
**
A)The PHP script will use session_regenerate_id when there is a change in the level of privilege (from logged in to logged out and via versa) – mitigate session fixation
B)SSL will be used to minimize the exposure of data between the client and the server
C)The form will have a hidden field nesting an anti-CSRF token, that will be checked against the one stored in the session – mitigate CSRF
D)Passwords will be stored after hashing them with Bcrypt hashing algorithm (with a proper salt)
E)(2)+ (3) validation will use Regular Expressions. I understand that, a wrong Regular Expression can cause many errors. Are there any general accepted Regular Expressions for validating email address, passwords, etc?
**
Questions:
**
1)Do I understand the input/output procedure correctly? Am I doing something wrong?
2)I know that security-wise you can never be 100% protected. What else should I do? Is something I write above wrong?
Thanks in advance.
Yes, you understand it all right in general.
That's, as you noted yourself, is an endlessly open topic. There are thousands vectors. Some of them are include injection (never include or read a file taken blindly from user input), eval (avoid this operator as a hot iron), upload injection is alone a wide topic with multiple issues (in short, always verify input data format)
As of regexps - oh, yes. Just try google.
I've been doing a lot of research about spam-prevention methods, I do not want to resort to using CAPTCHA.
The form typically sends an email to the user and the webmaster with the contents of the form.
The first thing I've done is to remove the contents of the form in the email sent to the user and simply have a confirmation message.
I have added a row for the persons 'title' and hidden the row using CSS, if the field is filled in. The submission completes without sending any emails.
I'd like to add a couple of other techniques,
Check the time to complete submission - do not send emails if under 5 seconds.
Pass through an unique ID - do not send emails if no match
The problem is that website pages are cached, so directly setting a session variable is useless. I'm considering use ajax to hit a CFC and set the variable, but it would require JavaScript.
Should I restrict submissions to only those with JavaScript enabled? Or are there any alternative suggestions?
Thanks
Daniel,
I have a similar spam-detection approach that has been in place since last year. I can share what I have seen.
Session based tests:
Checking the time it takes someone to fill out the form and checking that the user comes from the right page have been very reliable checks, though somewhat fraught with difficulty. In your case, forcing users to have modern, javascript enabled browsers might be your best option. And it seems like it's becoming a more accepted practice, I guess, right? I don't really know..
Content based tests:
Another two fairly helpful practices are to check that form fields contain different values and that no more than a specified number of URLs have been entered. Spammers almost always seem to stick the same trash URL into every field. However, these checks aren't nearly as good as session-based checks.
Our spam-detection heuristic has a few other checks, in addition to the ones above:
Basic regex injection tests - bare-bones, but I can share if you are interested
Spam Content - pretty useless - a simple library constructed mostly by hand
Banned IP Address - also pretty useless..
Some numbers from our heuristic over the last year or so.
Total failed tests= 83,356
Failed Injection Test = 54 (0 failed this test and no other tests)
Failed Too Many URLs In Input Test = 18,935 (2396)
Failed Spam Content Test = 3673 (46)
Failed Hidden Field Tampering Test = 60,295 (1479)
Failed Dubious Time Elapse Test = 64,430 (17,126)
Failed Invalid Session Test = 28,706 (140)
Failed Fields Contain Same Values Test = 167 (49)
Failed Banned IP Address (not implemented) = 0 (0)
I don't want to post too many details about exactly what our criteria are, but if you are interested I'd be happy to share code.
-Ben
I suggest you take a look at http://cfformprotect.riaforge.org/ as it works well for me.
I was recently messing with a django local server project and I had a input like
<form....{% csrf_token %}
....
<input type="text" value="foo" readonly />
....
</form>
Now the value of the input should stay the way I want it to ("foo"), but I used google chrome inspect and was able to change the value of the readonly input and pass the new value to the server, which saved the bad value.
So I have a few questions:
What are the general rules or mental checklists to prevent security risks like this?
Could I use the JavaScript console and corrupt data like this as well? Update: YEP.
So do I have to basically do all my checks on the server side?
If no to 3, what are the client side validations that are protected from html/js inspectors?
Edit:
I'm guessing from the answers so far, it's yes to 3. So should I still bother with client side security/checks? Will they actually make me more secure or is it just a false sense of security (which is bad)? Should I do client side checks to possibly save some checks on the server side, so my performance might be better? Basically: How much client side checking should I do?
You cannot reply on Javascript or anything on the client side for security. Just ensure that your server is secure.
For example you can just telnet to the port and send the appropriate data to the server. This will thwart and checks via Javascript (or any other technology( on the client side.
Just use Javascript to make the users experience on the client more enjoyable and more responsive. Do not use it for security.
Ask yourself why you needed that readonly value in the first place. Presumably, it was your code that generated it, when the user first requested the form. So, what was available to your code when the user requested the form that is not available when the user submits it back? There shouldn't be anything, which should lead you to the conclusion that that field can just as easily be generated on submit, without it needing to appear in the form at all.
Your server code must be the final authority, it simply cannot rely on the quality of validation that the client has done. View all clients, be they HTML or otherwise as prone to the effects of both devious users and fallible coders.
Never believe the data sent by a user (cookies, session,parameters in HTTP request,...). All data send by users can be modified.
Yes of course
It is still to be done.
I'm trying to figure out a good way to prevent bots from submitting my form, while keeping the process simple. I've read several great ideas, but I thought about adding a confirm option when the form is submitted. The user clicks submit and a Javascript confirm prompt pops up which requires user interaction.
Would this prevent bots or could a bot figure this out too easy? Below is the code and JSFIddle to demonstrate my idea:
JSFIDDLE
$('button').click(function () {
if(Confirm()) {
alert('Form submitted');
/* perform a $.post() to php */
}
else {
alert('Form not submitted');
}
});
function Confirm() {
var _question = confirm('Are you sure about this?');
var _response = (_question) ? true : false;
return _response;
}
This is one problem that a lot of people have encountered. As user166390 points out in the comments, the bot can just submit information directly to the server, bypassing the javascript (see simple utilities like cURL and Postman). Many bots are capable of consuming and interacting with the javascript now. Hari krishnan points out the use of captcha, the most prevalent and successful of which (to my knowledge) is reCaptcha. But captchas have their problems and are discouraged by the World-Wide Web compendium, mostly for reasons of ineffectiveness and inaccessibility.
And lest we forget, an attacker can always deploy human intelligence to defeat a captcha. There are stories of attackers paying for people to crack captchas for spamming purposes without the workers realizing they're participating in illegal activities. Amazon offers a service called Mechanical Turk that tackles things like this. Amazon would strenuously object if you were to use their service for malicious purposes, and it has the downside of costing money and creating a paper trail. However, there are more erhm providers out there who would harbor no such objections.
So what can you do?
My favorite mechanism is a hidden checkbox. Make it have a label like 'Do you agree to the terms and conditions of using our services?' perhaps even with a link to some serious looking terms. But you default it to unchecked and hide it through css: position it off page, put it in a container with a zero height or zero width, position a div over top of it with a higher z-index. Roll your own mechanism here and be creative.
The secret is that no human will see the checkbox, but most bots fill forms by inspecting the page and manipulating it directly, not through actual vision. Therefore, any form that comes in with that checkbox value set allows you to know it wasn't filled by a human. This technique is called a bot trap. The rule of thumb for the type of auto-form filling bots is that if a human has to intercede to overcome an individual site, then they've lost all the money (in the form of their time) they would have made by spreading their spam advertisements.
(The previous rule of thumb assumes you're protecting a forum or comment form. If actual money or personal information is on the line, then you need more security than just one heuristic. This is still security through obscurity, it just turns out that obscurity is enough to protect you from casual, scripted attacks. Don't deceive yourself into thinking this secures your website against all attacks.)
The other half of the secret is keeping it. Do not alter the response in any way if the box is checked. Show the same confirmation, thank you, or whatever message or page afterwards. That will prevent the bot from knowing it has been rejected.
I am also a fan of the timing method. You have to implement it entirely on the server side. Track the time the page was served in a persistent way (essentially the session) and compare it against the time the form submission comes in. This prevents forgery or even letting the bot know it's being timed - if you make the served time a part of the form or javascript, then you've let them know you're on to them, inviting a more sophisticated approach.
Again though, just silently discard the request while serving the same thank you page (or introduce a delay in responding to the spam form, if you want to be vindictive - this may not keep them from overwhelming your server and it may even let them overwhelm you faster, by keeping more connections open longer. At that point, you need a hardware solution, a firewall on a load balancer setup).
There are a lot of resources out there about delaying server responses to slow down attackers, frequently in the form of brute-force password attempts. This IT Security question looks like a good starting point.
Update regarding Captcha's
I had been thinking about updating this question for a while regarding the topic of computer vision and form submission. An article surfaced recently that pointed me to this blog post by Steve Hickson, a computer vision enthusiast. Snapchat (apparently some social media platform? I've never used it, feeling older every day...) launched a new captcha-like system where you have to identify pictures (cartoons, really) which contain a ghost. Steve proved that this doesn't verify squat about the submitter, because in typical fashion, computers are better and faster at identifying this simple type of image.
It's not hard to imagine extending a similar approach to other Captcha types. I did a search and found these links interesting as well:
Is reCaptcha broken?
Practical, non-image based Captchas
If we know CAPTCHA can be beat, why are we still using them?
Is there a true alternative to using CAPTCHA images?
How a trio of Hackers brought Google's reCaptcha to its knees - extra interesting because it is about the audio Captchas.
Oh, and we'd hardly be complete without an obligatory XKCD comic.
Today I successfully stopped a continuous spamming of my form. This method might not always work of course, but it was simple and worked well for this particular case.
I did the following:
I set the action property of the form to mustusejavascript.asp which just shows a message that the submission did not work and that the visitor must have javascript enabled.
I set the form's onsubmit property to a javascript function that sets the action property of the form to the real receiving page, like receivemessage.asp
The bot in question apparently does not handle javascript so I no longer see any spam from it. And for a human (who has javascript turned on) it works without any inconvenience or extra interaction at all. If the visitor has javascript turned off, he will get a clear message about that if he makes a submission.
Your code would not prevent bot submission but its not because of how your code is. The typical bot out there will more likely do an external/automated POST request to the URL (action attribute). The typical bots aren't rendering HTML, CSS, or JavaScript. They are reading the HTML and acting upon them, so any client logic will not be executed. For example, CURLing a URL will get the markup without loading or evaluating any JavaScript. One could create a simple script that looks for <form> and then does a CURL POST to that URL with the matching keys.
With that in mind, a server-side solution to prevent bot submission is necessary. Captcha + CSRF should be suffice. (http://en.wikipedia.org/wiki/Cross-site_request_forgery)
No Realy are you still thinking that Captcha or ReCap are Safe ?
Bots nowDays are smart and can easly recognise Letters on images Using OCR Tools (Search for it to understand)
I say the best way to protect your self from auto Form submitting is adding a hidden hash generated (and stored on the Session on your server of the current Client) every time you display the form for submitting !
That's all when the Bot or any Zombie submit the form you check if it the given hash equals the session stored Hash ;)
for more info Read about CSRF !
You could simply add captcha to your form. Since captchas will be different and also in images, bots cannot decode that. This is one of the most widely used security for all wesites...
you can not achieve your goal with javascript. because a client can parse your javascript and bypass your methods. You have to do validation on server side via captchas. the main idea is that you store a secret on the server side and validate the form submitted from the client with the secret on the server side.
You could measure the registration time offered no need to fill eternity to text boxes!
I ran across a form input validation that prevented programmatic input from registering.
My initial tactic was to grab the element and set it to the Option I wanted. I triggered focus on the input fields and simulated clicks to each element to get the drop downs to show up and then set the value firing the events for changing values. but when I tried to click save the inputs where not registered as having changed.
;failed automation attempt because window doesnt register changes.
;$iUse = _IEGetObjById($nIE,"InternalUseOnly_id")
;_IEAction($iUse,"focus")
;_IEAction($iUse,"click")
;_IEFormElementOptionSelect($iUse,1,1,"byIndex")
;$iEdit = _IEGetObjById($nIE,"canEdit_id")
;_IEAction($iEdit,"focus")
;_IEAction($iEdit,"click")
;_IEFormElementOptionSelect($iEdit,1,1,"byIndex")
;$iTalent = _IEGetObjById($nIE,"TalentReleaseFile_id")
;_IEAction($iTalent,"focus")
;_IEAction($iTalent,"click")
;_IEFormElementOptionSelect($iTalent,2,1,"byIndex")
;Sleep(1000)
;_IEAction(_IETagNameGetCollection($nIE,"button",1),"click")
This caused me to to rethink how input could be entered by directly manipulating the mouse's actions to simulate more selection with mouse type behavior. Needless to say I wont have to manualy upload images 1 by 1 to update product images for companies. used windows number before letters to have my script at end of the directory and when the image upload window pops up I have to use active accessibility to get the syslistview from the window and select the 2nd element which is a picture the 1st element is a folder. or the first element in a findfirstfile return only files call. I use the name to search for the item in a database of items and then access those items and update a few attributes after upload of images,then I move the file from that folder to a another folder so it doesn't get processed again and move onto the next first file in the list and loop until script name is found at the end of the update.
Just sharing how a lowly data entry person saves time, and fights all these evil form validation checks.
Regards.
This is a very short version that hasn't failed since it was implemented on my sites 4 years ago with added variances as needed over time. This can be built up with all the variables and if else statements that you require
function spamChk() {
var ent1 = document.MyForm.Email.value
var str1 = ent1.toLowerCase();
if (str1.includes("noreply")) {
document.MyForm.reset();
}
<input type="text" name="Email" oninput="spamChk()">
I had actually come here today to find out how to redirect particular spam bot IP addresses to H E L L .. just for fun
Great ideas.
I removed re-captcha a while back converted my contactform.html to contactform.asp and added this to the top (Obviously with some code in between to full-fill a few functions like sendmail, verify form filled out completely etc.).
<%
if Request.Form("Text") = 8 then
dothis
else
send them to google.com
end if
%>
On the form i stuck a basic text field with the name text so its just looks like anything not specifying what its for at all, I then stuck some text 2 lines above in red that states enter what 2 + 6 = in the box below to submit your request.