|
NAMECGI::EncryptForm - Implement trusted stateful CGI Form Data using cryptography.SYNOPSISuse CGI::EncryptForm; my $cfo = new CGI::EncryptForm(secret_key => 'my secret'); my $hashref = { username => 'joe', password => 'test' }; my $encrypted_string = $cfo->encrypt($hashref); if (!defined($encrypted_string)) { print $cfo->error(); return; } my $newhashref = $cfo->decrypt($encrypted_string); if (!defined($newhashref)) { print $cfo->error(); return; } print $newhashref->{'username'}; PREREQUISITESThis modules requires the following perl modules:Digest::SHA1, Crypt::HCE_SHA and Storable ABSTRACTMany CGI programmers take for granted the validity of stateful CGI form data.Im talking about the common scenario where you present a form to the browser, the user fills in the form, you verify the form values, store them in the next form as hidden fields, the user fills in another form, the script appends these results to the next form in hidden fields and so on. Using hidden form fields is one mechanism where by CGI scripts can maintain state in the process of collecting information from the user. Unfortunately, it is also one of the weakest to implement because the CGI script must trust the hidden form fields and there values, provided by the users browser. At some point in time the CGI program does something with this stateful information. To be completely sure the hidden fields haven't been altered along the way and thus rendered initial verification checks useless, the programmer must continually verify all new form fields and previous state (encapsulated in hidden form fields) to be sure the desired constraints are met. This process of verification becomes tedious to program especially if there are many forms required to produce a final result. To tackle this problem I created CGI::EncryptForm, where by instead of including state in hidden form fields verbatim, we use SHA1 encryption algorithm to provide a satisfactory level of trust between the users browser and the CGI script. DESCRIPTIONAn object is created with a secret key defined by the CGI script. The objects encrypt() method is called with a perl data structure, which in the context of CGI scripts would normally contain key/value pairs. The encrypt() method returns an encrypted string. The encrypted string is stored in a hidden form field. The user fills in the form. The CGI script processes the form, extracts the encrypted string from the hidden form field, decrypts the string and returns the original data structure. Further results from the form are added to the data structure, then it is encrypted again and stored in the next form as a hidden field. This process continues until the CGI script has all the desired information and is ready to process it. To process the results, the CGI script decrypts the encrypted string from the last hidden form field, which contains the collective state of all previous form input.Along the way, the users input was verified only once. The fact that state was encrypted and therefore trusted, renders the process of continually verifying all state for each form processed, unnecessary. METHODS
EXAMPLEThis example illustrates the use of CGI::EncryptForm in combination with CGI.pm to maintain stateful information in a multi-form CGI script.#!/usr/local/bin/perl use CGI::EncryptForm; use CGI; use vars qw($cgi $cfo); $cgi = new CGI(); $cfo = new CGI::EncryptForm(secret_key => 'blah'); print $cgi->header(), $cgi->start_html(), $cgi->start_form(); if (defined $cgi->param('enc')) { form3(); } elsif (defined $cgi->param('something')) { form2(); } else { form1(); } print $cgi->end_html(), $cgi->end_form(); sub form1 { print "<h1>form1</h1>", "Type something and we will remember it: ", $cgi->textfield('something'), $cgi->submit(); } sub form2 { print "<h1>form2</h1>", $cgi->hidden(-name=>'enc', value=>$cfo->encrypt({ $cgi->Vars })), "Now click here and I will tell you what you typed based on ", "the encrypted hidden form field, which you would normally ", "only see if you view the HTML source. For the sake of this ", "demonstration the encrypted field is included below.<p>", $cfo->encrypt(), "<p>", "Before proceeding with this form I suggest you take note of ", "what the encrypted field looks like, then click the back ", "button and resubmit the previous form with the same value ", "again. What you will notice is the encrypted field will ", "change. This is because the SHA encryption algorithm is ", "based on a secret key and a random key. In the module we ", "take care of generating a unique random key for each ", "invocation of the encryption routine, which is why a ", "distinct encrypted string is produced each time.", "<p>", $cgi->submit(); } sub form3 { my $hashref = $cfo->decrypt($cgi->param('enc')); if (!defined($hashref)) { print $cfo->error(); return; } print "<h1>form3</h1>", "Previously in the first form you typed:<p>", $hashref->{something}, "<p>We reproduced this data by decrypting the hidden form ", "field called 'enc', which was passed to us from the previous ", "form. You may like to try and tamper with the hidden form ", "field in form2, to see if you can alter the result of the ", "data as it originally flows from form 1 to form 3. Good luck"; } NOTESCGI::EncryptForm is not limited to form fields. The encrypted result can be stored in cookies and URL's as well. Personally though, I discourage this because your more likely to exceed size limitations with various web browsers and servers.BUGSNone that I know of.TODONone.AUTHORCopyright 1999, Peter Marelas. All rights reserved.This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Bug reports and comments to maral@phase-one.com.au. Thanks to the authors of these fine perl modules Storable, Digest::SHA1 and Crypt::HCE_SHA. SEE ALSOStorable, Digest::SHA1, Digest::HCE_SHA1
Visit the GSP FreeBSD Man Page Interface. |