Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Form Validation and Untainting

by Limbic~Region (Chancellor)
on Feb 11, 2005 at 16:37 UTC ( [id://430166]=perlquestion: print w/replies, xml ) Need Help??

Limbic~Region has asked for the wisdom of the Perl Monks concerning the following question:

All,
I am currently researching prior art to validate and untaint data coming from CGI posts. Since it may be relavent, I am using CGI::Application with CGI::Simple and HTML::Template.

In the past, I have just written custom routines in light of the myriads of choices on CPAN. For this project though, I would prefer to have something that is:

  • clean
  • flexible
  • easily maintained
  • relatively fast

CGI::Application::Plugin::ValidateRM uses Data::FormValidator which is the way I think I should go, but with all of the possibilities, I am soliciting your personal opinions. The more information and details you can provide keeping my objectives in mind the better. My research (see below for a partial list) hasn't turned up any clear winners.

Cheers - L~R

Replies are listed 'Best First'.
Re: Form Validation and Untainting
by cbrandtbuffalo (Deacon) on Feb 11, 2005 at 17:38 UTC
    We've suffered through various forms of custom validation and ad hoc is not the way you want to live. I've also recently started using Data::FormValidator and I think it's great. Here's why:
    • It's fairly mature. It's been around long enough that many features are there and they've encountered and solved enough problems;
    • I found the interface very clear and clean-cut, yet flexible in the right parts. You can play with the profile as much as you want before you check your data. You can also play with the data hash you pass. We seldom just pass the param hash. We usually tweak it first, and DFV doesn't care.
    • It clearly differentiates between filters and constraints. Filters let you reasonably massage data (i.e., remove a dash from a phone number) to be nice to your users. If the simple filters don't clean it up enough, the constraint fires errors.
    • You can easily define your own filters and constraints on your system in custom constraint modules.
    • You get plenty of info back on failed constraints so you can form an appropriate response for the user.
    • It standardizes your validation. You are using a standard module rather than ad hoc code. Plus it prevents you from stuffing other things into your validation steps.

    It's simple to start using it, and so far we haven't expanded beyond its capabilities. It can even handle complex inter-form dependencies in the constraint model. So far, it gets two thumbs up from me.

      This is maybe a bit outthere/overkill for small systems but it could save you some code logic and is portable.

      1. Define XML docs and XML schema for your all forms and use XSLT to generate your form pages.
      2. use XML::Xerces to validate user input against the schema

      Of course you are slightly restricted in what you can validate by the XML schema language

Re: Form Validation and Untainting
by meredith (Friar) on Feb 11, 2005 at 17:03 UTC

    For the very simple tasks, I usually loop over a hash of 'field name' => 'quoted regex' pairs. All of the regexes are positive assertions. A variation on that would be a making a dispatch hash in the same form.

    I've used Data::FormValidator once, but I didn't like the feel of it, so I'll be watching to see the replies you get. =)

    mhoward - at - hattmoward.org
Re: Form Validation and Untainting
by johnnywang (Priest) on Feb 11, 2005 at 22:44 UTC
    I use CGI::Applicaiton::ValidateRM, the nice thing about it is that it also calls HTML::FillInForm to fill back the submitted parameters. Of course, the code in CGI::Applicaiton::ValideRM is only about 20 lines using Data::FormValidator and HTML::FillInForm, so you can do everything with those two modules yourself.

    By the way, before I learnt these, I was using java Struts, the fill-parameter-back and error handling is one of the things I liked. It's amazing to see that there are still lots of sites out there that don't do this: you lose all your parameters if one is missing.

Re: Form Validation and Untainting
by sri (Vicar) on Feb 11, 2005 at 20:07 UTC
Re: Form Validation and Untainting
by Zaxo (Archbishop) on Feb 11, 2005 at 22:26 UTC

    Here's the Tie::Constrained way:

    use Tie::Constrained 'detaint'; tie my $trusty, 'Tie::Constrained' , sub { &condition && &detaint; };

    You can build a dispatch table - a hash of coderefs - to provide the proper \&condition for each field.

    our %check; @check{@fields} = ( sub { $_[0] =~ m/^$RE{'URI'}$/; }, # . . . ); for (@fields) { my $check = $check{$_}; tie $hash{$_}, 'Tie::Constrained', sub { &$check && &detaint }; }

    The detainting is done on an anonymous copy of the formerly untrusted data, so the tied variable is never tainted, and original data stays that way.

    The code that does the rest of the work can be written as if it never heard of taint mode.

    After Compline,
    Zaxo

Should you need javascript too.
by emazep (Priest) on Feb 13, 2005 at 03:57 UTC
    Data::FormValidator is great, but it unfortunately doesn't also generate javascript validation code.

    Though client-side javascript validation does not offer any reliability when used as the only validation stage, since it can be easily bypassed, when coupled with server-side (Perl) validation proves to be extremely precious in almost any web application.

    It's precious because the client data does not have to reach the server to be validated, so you can save both bandwidth and server CPU cycles by intercepting wrong data right on the client machine, thus alleviating both your network connection and your server from receiving the wrong data, checking them and sending back the form again (possibly several times before a successful form submission.)
    Furthermore, client-side validation gives your users a much stronger interactiveness feeling (and this is perhaps the most important thing.)
    Then should a bad guy bypass your client-side validation, you always have your Perl validation code replicated on the server that will inexorably stop it.

    So you could now think that it's a nightmare to keep in sync both Perl and javascript validation code (and you would be right, if you should do it by hand,) but what about if you could define your validation code just once (even in a declarative manner,) and get your Perl (server-side) validation code, and then get also javascript (client-side) validation code for free?!

    Well, such a sweet thing is provided by (at least) two modules I'm aware of: CGI::Ex::Validate by Paul T. Seamons and CGI::FormBuilder by Nathan Wiger.
    I don't know very much about the former, but I use the latter all the time (together with CGI::Application, as you required) and I find it nothing less than spectacular.
    It has not all the data analysis capabilities offered by Data::FormValidator, but it has the most common validation schemes built-in (and it's easily extensible too, offering some useful javascript hooks.)
    Furthermore it offers many other things related to web forms management, should you need it.
    CGI::Ex::Validate should offer even more about data validation though, to be honest, I don't know how well it integrates with CGI::Application (CGI::Ex has got its own application builder, called CGI::Ex::App.)

    Ciao,
    Emanuele.

      While this is a really old post, I stumbled on it and thought it'd be worth mentioning for prosperity that Data::FormValidator does have a companion module Data.FormValidator.js to do javascript validation using the same validation profile. Some things aren't supported on the javascript side, such as the custom perl subroutines, but it does get you a fair bit of the validation onto your frontend to make for a better user experience and reduce trips to the server.
Re: Form Validation and Untainting
by astroboy (Chaplain) on Feb 12, 2005 at 21:26 UTC
    Have a look Mark's Demo and the accompanying code. So much in so few lines. It's what hooked me onto Data::FormValidator by way of CGI::Application::Plugin::ValidateRM, and it's now how I do all of my web work

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://430166]
Approved by atcroft
Front-paged by Tanktalus
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (5)
As of 2024-03-29 12:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found