Earlier this week I had an interesting problem. I had a web form that needed to pass data on to a third party CGI program (it's a credit card payment system). The inputs to the CGI program were defined by the company who own it and the web form inputs were defined by what the user would expect to see.
The two set of requirements did not match up.
For example, for repeating payments, the CC system wanted two separate values for amount and period. On the web form you only need one input for this as the amount paid is a function of how frequently you pay (you either pay £x a month or £12x a year).
So I needed to put an intermediate step in between the form and the CGI program. One that would calculate the amount given the period.
My first idea was quite simply brilliant (even if I do say so myself). I'd write my own CGI program which took the inputs, munged them around a bit and then made a POST to the external CGI program. My program would take the content returned by the external program, add a <base> tag and display it to the user. (Can you tell I've just read Perl & LWP?)
It all worked fine. Except for one thing. The external CGI program needs to set a cookie. And as it was my program that was actually doing the work, the external cookie didn't get a chance to set a cookie (or if it did, it set the cookie on the wrong domain).
I was just about to start writing code to get round this problem when someone pointed out a slightly "cheating", but far simpler solution - a confirmation page.
Now, my program munges the input parameters as appropriate, but instead of calling the external program, it simply displays a page that says "please confirm you want to make this payment". It displays all of their data back to them, but in the background all the real data is in hidden inputs. Submitting this form passes control over to the external CGI program.
It's probably an obviously solution to many of you reading this, but I just thought it was a useful reminder of the wisdom of keeping things simple :)
This works all very well until something needs a POST not a GET. So I have this script that takes any request and resubmits it to the defined url as a post:
Now the important thing to note is that this script doesn't even have a submit button - as soon as the page is loaded javascript submits the page.#!/usr/bin/perl
# force as a hardcoded value for security reasons
use constant URL => "http://theurlhere.com/cgi-bin/script.jsp";
use CGI;
my $q = CGI->new();
# start the page
print $q->header;
print $q->start_html(-onLoad => "document.myform.submit()");
print "Please wait...";
# start the form
print $q->start_form(-name => "myform",
-action => URL);
# print out all values
foreach ($q->param())
{
print $q->hidden(-name => $_,
-value => $q->param($_)) . "\n";
}
print $q->end_form;
print $q->end_html;
Of course this will only work if you know they have javascript enabled (which in this case I do - it's my browser)
-Dom
Re:Security Hole!
davorg on 2002-09-05T15:38:38
Hmmm.... good point. This obviously isn't going to be quite as simple as I expected.
Re:Security Hole!
darobin on 2002-09-05T18:55:18
You only need security there if they can do anything bad with what they submit, ie generally if they can somehow change the price. Normally, they shouldn't be able to, you'd only send the ID of a product and how many of it they're taking and let the remote end do the math using prices in its store. Of course, it wouldn't be the first time I see an online sales system with that kind of hole...
I haven't done much in the way of cookies, but conceptually they are sort of like a key=valkey=valkey=val hash, right? So, you get a cookie from the CC site on behalf of the user, and quote/escape/whatever to it, and set it as the value of one of those keys in a cookie you send to the user. Then, decode it when you get it back.
Maybe.