$ENV{'CONTENT_LENGTH'} / STDIN

B

Bart Van der Donck

Hello,

I posted this article in perl.beginners.cgi but no answer there - low
activity. So I try here.

This is an HTML file:

<html>
<body>
<form method=post action=script.pl>
<input type=checkbox value=yes name=1><br>
<input type=radio value=yes name=2><br>
<input type=text value=myvalue name=3><br>
<select size=1 name=4>
<option></option>
<option value=x>x</option>
</select><br>
<textarea name=5>mytextarea</textarea><br>
<input type=submit>
</form>
</body>
</html>

This is a Perl file:

#!/usr/bin/perl
print "Content-Type: text/html;\n\n";
print "<html><body>\npassed names:<br>";
read(STDIN,$s,$ENV{'CONTENT_LENGTH'});
@p=split(/&/,$s);
for (@p) {
my @r=split/=/,$_; print $r[0]."<br>"; }
print "\n</body></html>";

When checkbox and radio are both checked, script.pl says:

passed names:
1
2
3
4
5

When checkbox and radio are not checked, script.pl says:

passed names:
3
4
5

I'm looking for a way to read out all passed names in Perl, regardless
of their values or whether or not they were checked. Is this possible ?

Thanks,
 
A

A. Sinan Unur

I posted this article in perl.beginners.cgi but no answer there - low
activity. So I try here.

You should read the posting guidelines for this group for valuable
information on how you can help yourself, and help others help you.
This is an HTML file:
<html>
<body>
<form method=post action=script.pl>
<input type=checkbox value=yes name=1><br>
<input type=radio value=yes name=2><br>

What do you think 'value=yes' means?

See http://www.w3.org/TR/html4/interact/forms.html#edef-INPUT
This is a Perl file:

#!/usr/bin/perl
print "Content-Type: text/html;\n\n";
print "<html><body>\npassed names:<br>";
read(STDIN,$s,$ENV{'CONTENT_LENGTH'});

use CGI;

Sinan
 
G

Gunnar Hjalmarsson

Bart said:
I'm looking for a way to read out all passed names in Perl, regardless
of their values or whether or not they were checked. Is this possible ?

Non-checked checkboxes and non-checked radiobuttons send nothing, so
there is nothing to read.
 
B

Bart Van der Donck

A. Sinan Unur said:

Thanks for the link. I think I understand that. Quote:

[value=] is optional except when the type attribute has the
value "radio" or "checkbox".

So it seems that W3 recommends browsers not to broadcast names of radio
buttons/checkboxes when left unchecked. In that case, Perl can not help
me here.

Yes - I already tried that, but with the same result. That's why I
decided to play around with STDIN / $ENV{'CONTENT_LENGTH'} to see if
they could help.
 
P

Paul Lalli

Bart said:
I posted this article in perl.beginners.cgi but no answer there - low
activity. So I try here.

That's really not a sufficient justification for posting an off topic
question here. The fact that your CGI happens to be written in Perl is
irrelevant.
This is an HTML file:

<html>
<body>
<form method=post action=script.pl>
<input type=checkbox value=yes name=1><br>
<input type=radio value=yes name=2><br>
<input type=text value=myvalue name=3><br>
<select size=1 name=4>
<option></option>
<option value=x>x</option>
</select><br>
<textarea name=5>mytextarea</textarea><br>
<input type=submit>
</form>
</body>
</html>

This is a Perl file:

#!/usr/bin/perl

You have forgotten
use strict;
use warnings;

Many people in this group will not bother to read your post with those
lines omitted. Please read the Posting Guidelines for other tips on
how to help you help yourself.
print "Content-Type: text/html;\n\n";
print "<html><body>\npassed names:<br>";
read(STDIN,$s,$ENV{'CONTENT_LENGTH'});
@p=split(/&/,$s);

Don't do this. Use the CGI module to obtain the parameter list.

perldoc CGI
for (@p) {
my @r=split/=/,$_; print $r[0]."<br>"; }
print "\n</body></html>";

When checkbox and radio are both checked, script.pl says:

passed names:
1
2
3
4
5

When checkbox and radio are not checked, script.pl says:

passed names:
3
4
5

I'm looking for a way to read out all passed names in Perl, regardless
of their values or whether or not they were checked. Is this possible ?

I think you have a misunderstanding about the way CGI works. When the
radio and check buttons weren't checked, those names were NOT passed at
all. The script you wrote correctly printed the names of all the HTML
inputs that *were* passed.

You would probably get better advice (for all I know, there could be a
way to work around this) by posting to a group that actually deals with
CGI questions, rather than perl questions.
comp.infosystems.www.authoring.cgi would be a good start.

Paul Lalli
 
X

xhoster

Bart Van der Donck said:
So it seems that W3 recommends browsers not to broadcast names of radio
buttons/checkboxes when left unchecked. In that case, Perl can not help
me here.


Yes - I already tried that, but with the same result.

Did you try it to generate the form, or just to parse the submission from
it?
That's why I
decided to play around with STDIN / $ENV{'CONTENT_LENGTH'} to see if
they could help.

Use "hidden" to specify the names of all the check-boxes and radio groups
on the form. Things in hidden but without name-values pairs of their own
must be unchecked.

Xho
 
B

Bart Van der Donck

Xho said:
Use "hidden" to specify the names of all the
check-boxes and radio groups on the form.
Things in hidden but without name-values pairs
of their own must be unchecked.

I was thinking in the same direction, yes. For those interested, I
ended up with the following.

HTML file:

<html><body>
<form method=post action=script.pl>
<input type=checkbox name=one value=1><br>
<input type=checkbox name=two value=2><br>
<input type=checkbox name=three value=3><br>
<input type=radio value=yes name=four>
<input type=radio value=no name=four checked><br>
<input type=text value=myvalue name=five><br>
<select size=1 name=six>
<option value=x>x</option>
</select><br>
<textarea name=seven>mytextarea</textarea>
<input type=hidden name=placeholder_one>
<input type=hidden name=placeholder_two>
<input type=hidden name=placeholder_three>
<input type=submit>
</form>
</body></html>

script.pl:

#!/usr/bin/perl
use strict; use warnings;
print "Content-Type: text/html;\n\n";
print "<html><body>\npassed names:<br>";
use CGI;
my $query=CGI->new;
my $prev ='none';
my @params = $query->param;
s/^placeholder_// for @params;
print join '<br>',
grep($_ ne $prev && ($prev=$_),sort @params);
print "\n</body></html>";

The idea is to populate the HTML file first with as many hidden
elements as there are checkboxes, and then use the same names but with
a fixed string before (in my code: "placeholder_"). No problem for the
radios because I can set one of them as checked when generating the
HTML, so its name will always be passed regardless of the value it
gets.

Appreciate the help I've got to point me in the right direction.
 
A

Alan J. Flavell

A. Sinan Unur said:

Thanks for the link. I think I understand that. Quote:

[value=] is optional except when the type attribute has the
value "radio" or "checkbox".

So it seems that W3 recommends browsers not to broadcast names of
radio buttons/checkboxes when left unchecked.

Excuse me? I think you've got two things wrong here. 1. you're
trying to understand HTML on a newsgroup that isn't much interested in
HTML - more in Perl; and 2. you're looking at the wrong part of the
spec to understand which name=value pairs are meant to be sent from
the client to the server. For the answer to 2 you'd refer to
"successful controls":

http://www.w3.org/TR/html4/interact/forms.html#h-17.13.2

For enlightenment on HTML topics in general, you'd want
comp.infosystems.www.authoring.html; whereas for CGI-specific matters
i.e evaluating form controls on the server side, you'd be better off
in comp.infosystems.www.authoring.cgi (beware its automoderation bot).
In that case, Perl can not help me here.

Perl is just one of the languages in which one can write CGI software,
indeed. If the information that you need does not reach the
server-side process, then it doesn't matter in the least whether you
program the server-side process in Perl, in shell, in COBOL or
whatever.
Yes - I already tried that, but with the same result. That's why I
decided to play around with STDIN / $ENV{'CONTENT_LENGTH'} to see if
they could help.

I'm sorry, but the logic of this escapes me. The format of the
submitted "form data set" is clearly enough documented at
http://www.w3.org/TR/html4/interact/forms.html#h-17.13

I don't know what you're exactly trying to achieve, but it looks to me
as if you need to work from that.

good luck
 
D

Dr.Ruud

Bart Van der Donck schreef:
The idea is to populate the HTML file first with as many hidden
elements as there are checkboxes, and then use the same names but with
a fixed string before (in my code: "placeholder_"). No problem for the
radios because I can set one of them as checked when generating the
HTML, so its name will always be passed regardless of the value it
gets.

Check how the form on
http://www.multilingual.ch/search_interfaces.htm
uses the same name for several items.

Appreciate the help I've got to point me in the right direction.

Rubbing it in is also not good.
 
A

Alan J. Flavell

Use "hidden" to specify the names of all the check-boxes and radio
groups on the form. Things in hidden but without name-values pairs
of their own must be unchecked.

I'm nervous about the way that this is developing here.

A server-side script should *know* what valid input it is expecting
from a form submission. Some of the expected names may be present as
name=value pairs and some may not. The program logic will need to
cope with that anyway (since a server-side script needs to be battle
hardened against anything that could be thrown at it, not merely
against the expected inputs from the author-designed form) for
security reasons.

This apparent attempt to persuade a server-side script to parse any
damned form-control name that it might get, seems to be well on the
way to opening up, at the very least, a denial-of-service attack, if
not worse, relative to the usual procedure. I'd counsel an attentive
read of Lincoln Stein's web security FAQ, and a certain attitude
adjustment towards a more defensive style of programming.

And, by the way, to the O.P: *use* CGI. Don't just call it out and
then do most of its work by hand instead!

good luck
 
X

xhoster

Alan J. Flavell said:
I'm nervous about the way that this is developing here.

A server-side script should *know* what valid input it is expecting
from a form submission.

It should know the *general format* of the valid input it is expecting.
If it knew the actual valid input, there would be no reason for a form
in the first place. There is no reason that the general format of a valid
input cannot include a hidden element with a list of thingies. (Or a list
of hidden elements with one thingy each, depending on whether you are
looking at it after CGI.pm or before)
Some of the expected names may be present as
name=value pairs and some may not. The program logic will need to
cope with that anyway (since a server-side script needs to be battle
hardened against anything that could be thrown at it, not merely
against the expected inputs from the author-designed form) for
security reasons.

They way you cope with things for security reasons and the way you cope
with things for correctness reasons are very different. The fact that
a script deals with it from a security angle doesn't automatically mean
it is dealing with it properly from a correctness angle.

This apparent attempt to persuade a server-side script to parse any
damned form-control name that it might get,

No persuasion is needed. CGI.pm will automatically parse any damned
form-control name that it might get. What you do with them, of course,
is up to you.
seems to be well on the
way to opening up, at the very least, a denial-of-service attack, if
not worse, relative to the usual procedure.

A denial of service attack just gives me the opportunity to fire, and
possibly prosecute, any malicious employee before they have the chance to
do something truly damaging. 20 minutes of downtime is a small price to
pay for getting rid of malicious personnel.

Aside from which, I don't see how this method opens up any risk that isn't
already there. And what is "the usual procedure"? This is the usual
procedure for doing what it does.


I'd counsel an attentive
read of Lincoln Stein's web security FAQ, and a certain attitude
adjustment towards a more defensive style of programming.

Is there something in particular there that you would like to draw our
attention to?

BTW, did you know that CGI.pm itself automatically prints out hidden form
elements containing the the names of the form's other elements?

Xho
 
X

xhoster

Bart Van der Donck said:
I was thinking in the same direction, yes. For those interested, I
ended up with the following.
....

The idea is to populate the HTML file first with as many hidden
elements as there are checkboxes, and then use the same names but with
a fixed string before (in my code: "placeholder_")

While that can work, wouldn't it be cleaner to put the names of the
checkboxes into the *values* of the hidden elements? Then no munging would
be necessary.

Xho
 
A

Alan J. Flavell

It should know the *general format* of the valid input it is
expecting. If it knew the actual valid input, there would be no
reason for a form in the first place.

Sure. Can we skip the more extreme bits of pedantry please, and
concentrate on the issues?
There is no reason that the general format of a valid input cannot
include a hidden element with a list of thingies. (Or a list of
hidden elements with one thingy each, depending on whether you are
looking at it after CGI.pm or before)

Indeed; my concern was more with what the O.P seemed to be
aiming to do when the parameter names came back.
They way you cope with things for security reasons and the way you
cope with things for correctness reasons are very different.

Even if there were no malicious users, there can always be mistakes,
so I continue to counsel a *defensive* attitude to server-side
programming. A program which is absolutely correct but totally
insecure may be perfect in the lab, but useless in the real world.
No persuasion is needed. CGI.pm will automatically parse any damned
form-control name that it might get. What you do with them, of
course, is up to you.

I take your point. However, but "business end" of the script ought to
*know* what it's doing, in terms of parameters, and only be waiting
for the actual values from the submission; I'm concerned that what
appears to be discussed here it the idea that the server-side script
might have little idea what parameter names to expect until the form
submission tells it.

Now, I'm not arguing that it's impossible to cope with that, just as I
wouldn't argue that it's impossible in Perl to use variable variable
names. But both are things that I reckon can be handled more safely
by a different technique, and, if someone asks or discusses the issue,
I'm going to feel it useful to advise the use of a safer method.
A denial of service attack just gives me the opportunity to fire,
and possibly prosecute, any malicious employee before they have the
chance to do something truly damaging. 20 minutes of downtime is a
small price to pay for getting rid of malicious personnel.

By default I tend to treat intranets as just a special case of
the wider (e.g world wide web) situation.

If you want to deploy a deliberately insecure procedure in order to
entrap a malicious employee, then IMHO you're discussing a very
special case, that - paradoxically - needs *even better*
"security-think" on the server side than the normal case. But let's
not head down that particular track until we have to...?
Aside from which, I don't see how this method opens up any risk that
isn't already there. And what is "the usual procedure"?

I meant having the evaluation phase of the script *know* what names it
expects to find in name=value pairs in the submission, and process
just those. One convenient approach is to have CGI.pm write the
original form from the same script, so that the code is all kept in
the same place. It also facilitates error handling: writing a fresh
form, pre-entering the input which was valid so far, and flagging the
fields which need further attention.

If some joker interferes with the client/server dialog, and submits
thousands of parameters whose names were not expected by the script,
then, sure, subject to the size limits set, CGI.pm will prepare them
for consideration by the script, but that should be the end of the
matter.
Is there something in particular there that you would like to draw
our attention to?

Not really: I'd rate it more as an attitude, rather than any one
particular technical point.
BTW, did you know that CGI.pm itself automatically prints out hidden
form elements containing the the names of the form's other elements?

I perceive the trap that you're setting here. But all that CGI.pm
does with them are to preserve them as sticky parameters, which is a
linear process. So if some joker adds a thousand more, then sure,
there will be a thousand more sticky parameters, but they don't *do*
anything, they just get dragged along for a while. The difference is
that CGI.pm doesn't try to wade through them trying to make sense of
what they mean in terms of the user's application, which is what (as I
read it - correct me if I'm wrong) was what seemed to be proposed
here.

I think I'm done with this now, unless someone can show me I've
totally misunderstood something.

thanks
 
A

A. Sinan Unur

....

Even if there were no malicious users, there can always be mistakes,
so I continue to counsel a *defensive* attitude to server-side
programming. A program which is absolutely correct but totally
insecure may be perfect in the lab, but useless in the real world.


I take your point. However, but "business end" of the script ought to
*know* what it's doing, in terms of parameters, and only be waiting
for the actual values from the submission; I'm concerned that what
appears to be discussed here it the idea that the server-side script
might have little idea what parameter names to expect until the form
submission tells it.

The danger is very very real. On a recent project, I discovered that our
IT people were using such a generic script. The script saved the results
of the submission in a data file whose entire path was specified via
hidden parameters in the form, and also to send the results of form
submission to an email address specified in its entirety in the form
submission.

Even after I demonstrated how to use the script to delete files in the
programmer's home directory (did I tell you that Apache ran with
elevated permissions on this machine), and send spam to him, my concerns
were dismissed because I was not a UNIX sysadmin with 10 years of CGI
programming experience.

Two weeks after the script went live, the server had to be taken down
for a couple of days, due to an unexplained failure.

I have no proof, as probing further at that point would not have been
diplomatically prudent, but guess what I believed caused this failure.
I think I'm done with this now, unless someone can show me I've
totally misunderstood something.

I don't think you are. I think you are correct in your understanding of
the OP's intentions. And, I hope the OP has learned something from your
recommendations. The world does not need another generic form parsing
script.

Apologies for the rant, but these security concerns are real. It does
affect other people. The "programmer" generally keeps his/her job around
here, just like the BOFH does, but I had to delay the deployment of a
classroom technology by 3 full weeks because of this failure.

Sinan
 
A

A. Sinan Unur

Serious mistake, IMO! Never, ever, allow user-defined data access to a
system command.

You might question why they did this.
....

My recommendation: Deal with it the best you can and move on.

Yeah, I filed my bug reports, sent a memo, and then the semester hit at
full force :)

Thanks for the support.

Sinan
 
B

Bart Van der Donck

Xho said:
While that can work, wouldn't it be cleaner to put the names of the
checkboxes into the *values* of the hidden elements? Then no munging would
be necessary.

Indeed. Or IMO even more clean:

<input type="hidden" name="selectboxes_on_page"
value="nameofselectbox1§nameofselectbox2§nameofselectbox3">

Life can be simple ;-)
 
A

Alan J. Flavell

Indeed. Or IMO even more clean:

<input type="hidden" name="selectboxes_on_page"
value="nameofselectbox1§nameofselectbox2§nameofselectbox3">

Life can be simple ;-)

You're still putting the script at extra risk from some joker who
submits a faked submission. Handling tainted data is quite feasible
*for someone who knows what they're doing*, but it's adding extra
complexity if the script has to handle not only the tainted parameter
/values/ (which is the usual case), but also tainted parameter
/names/.

An HTML form cannot itself create variable parameter names, so there's
no inherent need to devise server-side code to deal with them: ergo
IMHO there's no point in devising this additional complexity (and
accompanying potential security risk).

I've already conceded the point that CGI.pm, in a sense, does this
anyway, to prepare the submitted parameters for use by the "business
end" of the script - but that's just a linear operation, limited by
the max size which may have been configured, and carefully coded and
widely tested so as not to be floored by the tainted data. I'm much
more concerned about the one-off code thats written in the "business
end" of the script - to actually do something real-world meaningful
with this tainted data, and that's where I smell extra security risks.

Keep It Simple. That's still my advice.

all the best
 
X

xhoster

Alan J. Flavell said:
Sure. Can we skip the more extreme bits of pedantry please, and
concentrate on the issues?

I believe that this is one of the issues. If you script properly deals
with hidden elements containing bits of state, then processing hidden
elements containing bits of state will done properly, and there is no
reason not to do it.

Indeed; my concern was more with what the O.P seemed to be
aiming to do when the parameter names came back.

I don't understand your concerns. He gave no inkling of what he was
going to do with them, so there was no greater cause for concern about them
than about every other aspect of writing a script.
Even if there were no malicious users, there can always be mistakes,
so I continue to counsel a *defensive* attitude to server-side
programming.

I might agree if I had any idea what that means, or had any idea what it
had to do with my comment.

A program which is absolutely correct but totally
insecure may be perfect in the lab, but useless in the real world.

And a script which is absolutely secure but, in an attempt to forbid every
possible form for incorrectness allows nothing useful to be done, is
useless both in a lab and in the real world.
I take your point. However, but "business end" of the script ought to
*know* what it's doing, in terms of parameters,

And if the way that it knows what is doing in terms of some parameters is
by looking at the value of some other parameters, then it does, in fact,
know what it is doing in terms of parameters.

Now, I'm not arguing that it's impossible to cope with that, just as I
wouldn't argue that it's impossible in Perl to use variable variable
names. But both are things that I reckon can be handled more safely
by a different technique, and, if someone asks or discusses the issue,
I'm going to feel it useful to advise the use of a safer method.

Except that you haven't actually advised of a safer method.
By default I tend to treat intranets as just a special case of
the wider (e.g world wide web) situation.

If you want to deploy a deliberately insecure procedure

To me, something which is insecure allows people to see or change data they
have no write to see or change. A potential DOS is not insecure, merely
non-robust. Anyway, I don't go out of my way to open up scripts to DOS
attacks, I merely refrain from being paranoid about them. Imposing
arbitrary limits on the size of a problem people are allowed to submit
wastes far more of my predecessors time in coding the arbitrary
limitations, and then my time in recoding the arbitrary limitations every
time someone bumps up against them, plus the lost productivity of the
person who bumped up against them and needed to wait for me to change them,
than all accidental or intentional DOS attacks have ever caused me.
in order to
entrap a malicious employee, then IMHO you're discussing a very
special case, that - paradoxically - needs *even better*
"security-think" on the server side than the normal case. But let's
not head down that particular track until we have to...?


I meant having the evaluation phase of the script *know* what names it
expects to find in name=value pairs in the submission, and process
just those.

It needs to know how to know what names to expect. Sometimes that
knowledge can be directly hard-coded into the program, sometimes it can't.
When it can't, then one way around it that is to have it know how to look
up, in some other parameter what names it should expect, and have
hard-coded validation, rather than hard-coded names.

One convenient approach is to have CGI.pm write the
original form from the same script, so that the code is all kept in
the same place.

That is completely orthoganol. If the CGI.pm using script has to
dynamically generate some of the element names, then some separate
invocation of that same script has to know what element names the prior
invocation generated. You could pass that knowledge through some kind of
sever-side storage keyed by cookie or hidden field, or you could pass that
knowledge directly through hidden field.

Sure, if you pass the data itself, it has to be validated. But then again,
if you pass only a key to the data, that also has be validated. If I have
to pass things through the client anyway, and validate it anyway, it is
often the case that I may as well do all that with the data itself rather
than some key into the data repository.

I perceive the trap that you're setting here. But all that CGI.pm
does with them are to preserve them as sticky parameters, which is a
linear process.

What makes you think whatever something other than CGI.pm does with them
won't be a linear process, also? Sure, you could make it nonlinear if you
tried, but you can write bad code in an infinite number of ways.

Xho
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top