September 30, 2012

how to prevent script tags in zend form

Question by Awais Qarni

Hi there I am just testing my own developed application and got a problem. I entered

<script>window.location = "http://www.google.com";</script>

in Zend_Form_Element_Text element. I pressed submit and the value is saved. After saving value I redirect the user to listing and when it redirects to listing, script tag executes and it goes to google.com.

My form element looks like

 $first_name = new Zend_Form_Element_Text('first_name');
 $first_name->setRequired(true)
            ->addFilter('StringTrim')
            ->addValidator('StringLength', false, array(2, $metaData['first_name']['LENGTH']))
            ->setDecorators(array('ViewHelper', 'errors'));

I want to know how can I prevent the user to enter such kind of values? Is there any built in validation or any other way?

Answer by vascowhite

Well done for testing your app, many people don’t bother. Don’t worry about storing that string in your database it won’t do any harm and changing it may give you problems with other, valid, entries. As vstm says, escape it when you use it.

However, as you are specifically talking about a ‘First Name’ field there is probably some more validation that you can do, such as rejecting any names with a / in them. I’m not aware of any language that has that as part of a name. If there is, I’d love to know how it’s pronounced. You could probably add . = and some others to that list too, but don’t get too carried away.

You should carefully consider every field in your form with regards to what input you would reasonably expect to receive and validate the input accordingly. Anything that doesn’t pass validation is rejected. A string like '<script>window.location = "http://www.google.com";</script>' should certainly never pass validation for a field expecting a person’s name.

Personally, I never filter input. It either passes validation and is accepted, or it doesn’t and is rejected. I can’t make good input out of bad input by filtering it, so it gets rejected and the user is asked to re-enter their data. For example, using a StripTags filter on

<script>window.location = "http://www.google.com";</script>

will leave you with

window.location = “http://www.google.com”;

which is still not a valid name and should be rejected.

Your validation will never work 100% of the time and that is why you should always escape values received from user input before echoing them out to the browser.

Zend Framework has a raft of validators that you could use and don’t forget the validators and filters that PHP has already available for you. Use them properly and you will greatly reduce the risk of malicious input hurting either your application or, more importantly, your users.

Those validators and filters are there for you to use, but neither PHP nor Zend Framework know what kind of data you are expecting, so it is very important that you read the documentation and learn exactly how they work, how to use them and when to use them.

There is an excellent resource at The Web Application Security Project that every web dev should be forced to read on pain of death.

tl;dr
Validate input and escape output.

Answer by Starx

You can use filters to restrict input from the user. Read about the filters

There is a filter in Zend Framework called Zend_Filter_StripTags which will give you the option to strip all or selected tags. Here is an example from the site itself.

$filter = new Zend_Filter_StripTags();     
print $filter->filter('<B>My content</B>'); 

As result you will get the stripped content ‘My content’.

On your case the following

$first_name->setRequired(true)
            ->addFilter('StringTrim')
            ->addFilter('StripTags') //Here a add a filter to strip tags
            ->addValidator('StringLength', false, array(2, $metaData['first_name']['LENGTH']))
            ->setDecorators(array('ViewHelper', 'errors'));
April 11, 2012

Jquery form validation – pop up to specific checkbox

Question by holian

I use Jquery form validation. Before visitor submit i need to check the ‘Terms&Cond’ checkbox. If not checked i would like to see the message an alert box. (other messages shown near in the textboxes)

How to set this? I try this:

 $("#myform").validate({
      errorPlacement: function(error, element) {
            if ( element.is(":checkbox") ) {
                alert(error.html());
            }
            },
        rules: {
            name: {
                required: true,
                minlength: 3,
                maxlength: 40,
                lettersonly: false
            },
            ad: {
.....

But this did not work.

Thank you for help.

Answer by Starx

error does not have a html() function. You were probably trying to alert the markup of the element.

alert(element.html());
March 23, 2012

Problems with my javascript, I dont want to validate <select> tags that are disabled

Question by ps__

This javascript will find all my selects and validate them but I want to add that it doesnt validate my disabled selects. How can I code that in my javascript?

$("#next-step").click(function () {

                var $step = $(".wizard-step:visible"); // get current step

                var validator = $("form").validate(); // obtain validator
                var anyError = false;
                $step.find("select").each(function () {
                    if (!validator.element(this)) { // validate every input element inside this step
                        anyError = true;
                    }


                });

                if (anyError)
                    return false; // exit if any error found

Thanks in advance!

Answer by ehynds

if (!this.disabled && !validator.element(this)) {
    anyError = true;
}​

or (slower)

$step.find("select:enabled").each(function() {
    if (!validator.element(this)) {
        anyError = true;
    }
});​

Answer by Starx

The easiest way, i know of is to give the select tags, a class like skipvalidation and then

$("form").validate(
   ignore: ".skipvalidation"
);

You can find all the disabled elements and add the class as

$("input:disabled").addClass("skipValidation");
$("form").validate(
   ignore: ".skipvalidation"
);
February 27, 2012

How can we specify rules for jquery validation plugin by class?

Question by Zesty

The jQuery Validation plugin works great and is very easy to use:

$(".selector").validate({
})

Just by setting css classes like “required email”, the default message will be displayed.

However, I need to customize the messages. The documentation says you can specify rules using a key-value pair for elements and their corresponding messages:

$(".selector").validate({
   rules: {
     name: "required",
     email: {
       required: true,
       email: true
     }
   },
   messages: {
     name: "Please specify your name",
     email: {
       required: "We need your email address to contact you",
       email: "Your email address must be in the format of name@domain.com"
     }
   }
})

But, it is not practical to specify a rule for every form element, especially server-generated controls in ASP.NET. Is it possible to specify rules that would apply to ALL elements? Or can I use a class selector somehow?

I tried the following, but it didn’t work:

$("#frmMyForm").validate
({
    rules:
    {
        $(".required email"):
        {
            required: true,
            email: true
        }
    },
    messages:
    {
        $(".required email"):
        {
            required: "Please enter your email address",
            email: "Your email address must be in the format of name@domain.com"
        }
    }
});

That seemed to have a syntax error – the plugin didn’t do anything. Then I tried:

$("#frmMyForm").validate
({
    rules:
    {
        ".required email":
        {
            required: true,
            email: true
        }
    },
    messages:
    {
        ".required email":
        {
            required: "Please enter your email address",
            email: "Your email address must be in the format of name@domain.com"
        }
    }
});

This didn’t have any syntax error – the plugin worked, but it ignored the rules/custom messages. Has anyone here used jQuery Validation plugin? If so, how did you apply rules/custom messages to multiple elements?

Thanks!

Answer by Sparky672

For the purposes of my example, this is the base starting code:

HTML:

<input type="text" name="field_1" />
<input type="text" name="field_2" />
<input type="text" name="field_2" />

JS:

$('#myForm').validate({
    rules: {
        field_1: {
            required: true,
            number: true
        },
        field_2: {
            required: true,
            number: true
        },
        field_3: {
            required: true,
            number: true
        }
    }
});

Option 1) You can assign classes to your fields based on desired common rules and then assign those rules to the classes. You can also assign custom messages.

HTML:

<input type="text" name="field_1" class="num" />
<input type="text" name="field_2" class="num" />
<input type="text" name="field_3" class="num" />

The .rules() method must be called after invoking .validate()

JS:

$('#myForm').validate({
    // your other plugin options
});

$('.num').each(function() {
    $(this).rules('add', {
        required: true,
        number: true,
        messages: {
            required:  "your custom message",
            number:  "your custom message"
        }
    });
});

Option 2a) You can pull out the groups of rules and combine them into common variables.

var ruleSet1 = {
        required: true,
        number: true
    };

$('#myForm').validate({
    rules: {
        field_1: ruleSet1,
        field_2: ruleSet1,
        field_3: ruleSet1
    }
});

Option 2b) Related to 2a above but depending on your level of complexity, can separate out the rules that are common to certain groups and use .extend() to recombine them in an infinite numbers of ways.

var ruleSet_default = {
        required: true
        number: true
    };

var ruleSet1 = {
        max: 99
    };
$.extend(ruleSet1, ruleSet_default); // combines defaults into set 1

var ruleSet2 = {
        min: 3
    };
$.extend(ruleSet2, ruleSet_default); // combines defaults into set 2

var ruleSet3;
$.extend(ruleSet3, ruleSet_1, ruleSet_2); // combines sets 2 & 1 into set 3.  Defaults are included since they were already combined into sets 1 & 2 previously.

$('#myForm').validate({
    rules: {
        field_1: ruleSet2,
        field_2: ruleSet_default,
        field_3: ruleSet1,
        field_4: ruleSet3
    }
});

End Result:

  • field_1 will be a required number no less than 3.

  • field_2 will just be a required number.

  • field_3 will be a required number no greater than 99.

  • field_4 will be a required number between 3 and 99.

Answer by Starx

jQuery.validator.addClassRules(); will attach the validation to class, but there is no option for messages, it will use the general error messages.

If you want that to work then, you should refactor the rules like this

$.validator.addMethod(
     "newEmail", //name of a virtual validator
     $.validator.methods.email, //use the actual email validator
     "Random message of email"
);

//Now you can use the addClassRules and give a custom error message as well.
$.validator.addClassRules(
   "email", //your class name
   { newEmail: true }
 );
...

Please fill the form - I will response as fast as I can!