an original perldoc viewer

A

A. Sinan Unur

I have been reprimanded for my lack of knowledge of perldoc material
so I have decided to do more reading. I realized that I am often (%50
of the time) working on a machine that does not have Perl but is
connected to the internet.

Why don't you have Perl on the machine where you are doing your
development?
 
P

Phillip Hartfield

A. Sinan Unur said:
Why don't you have Perl on the machine where you are doing your
development?

Even on a standalone P1 w/64mb ram, I used winrar to chunk activestates
version over so I could code.

I added a Tk proglet to put perldoc output in a text widget, using msdos
window without decent pager is grating. TG4Perl!

Phil <-typing with one hand bites

PS patiently waiting on right hand to get over its pain-in-the-joints
attitude so i can add auto-indexing and linking feature to my pathetic
proglet.
 
W

wana

I have been reprimanded for my lack of knowledge of perldoc material so I
have decided to do more reading. I realized that I am often (%50 of the
time) working on a machine that does not have Perl but is connected to the
internet. My first thought was to go to perldoc.com, but it seemed to be
down tonight, so I wrote a simple home-made solution to get by for now. I
was hoping pod2html would format my perldocs but it did not work when I
tried: pod2html perltoc (maybe perldoc pod2html says how to do it). Here
it is. Improvements, especially in output formatting, would be welcome.

#!/usr/bin/perl
use strict;
use warnings;
use CGI qw:)standard escapeHTML escape);
$CGI::pOST_MAX=1024 * 100; # max 100K posts
$CGI::DISABLE_UPLOADS = 1; # no uploads

my $a = 'perldoc to be displayed here';
if (param('display'))
{
if (my $doc = param('docname'))
{
$a = `perldoc $doc`;
}
}
print header(), start_html();
print start_form(), p('Type name of perldoc'),
p(textfield(-name=>'docname')),
p(submit(-name=>'display')),
end_form();
print hr, pre($a),end_html();


Thanks!

wana
 
W

wana

A. Sinan Unur said:
Why don't you have Perl on the machine where you are doing your
development?

My laptop, which I do most development on, has Perl. It is a Toshiba
Satellite with Suse Linux which turned out to be a perfect Windows
replacement.

I am a complete amateur programmer in the sense that my job does not involve
programming at all. I am lucky in the sense that we are very well
connected at work with many Windows machines connected to the internet via
cable modem. I have enough free time during the day to browse around
online and connect via ssh to my web provider which is really the most fun
place to do Perl programming for me (I can only use vi as editor there).

I do hope to someday make a career of developing software when I get good
enough. For now, I only get a few precious hours during the week with my
Linux laptop.

At work, my PDA can connect to the internet wirelessly, so my little program
is perfect for a quick perldoc read. I have it running online at an
undisclosed location (just in case it's not totally secure).

wana
 
J

John Bokma

wana said:
I am a complete amateur programmer in the sense that my job does not
involve programming at all. I am lucky in the sense that we are very
well connected at work with many Windows machines connected to the
internet via cable modem. I have enough free time during the day to
browse around online and connect via ssh to my web provider which is
really the most fun place to do Perl programming for me (I can only
use vi as editor there).

Open a second session, and run perldoc there :)

If you are using PuTTY note that it recently had a necessary security
update.
I do hope to someday make a career of developing software when I get
good enough. For now, I only get a few precious hours during the week
with my Linux laptop.

At work, my PDA can connect to the internet wirelessly, so my little
program is perfect for a quick perldoc read. I have it running online
at an undisclosed location (just in case it's not totally secure).

Security by obscurity is very very bad. And yes, it's insecure.

if (my $doc = param('docname')) {
$a = `perldoc $doc`;

Very!
 
W

wana

<posted & mailed>
I have been reprimanded for my lack of knowledge of perldoc material so I
have decided to do more reading. I realized that I am often (%50 of the
time) working on a machine that does not have Perl but is connected to the
internet. My first thought was to go to perldoc.com, but it seemed to be
down tonight, so I wrote a simple home-made solution to get by for now. I
was hoping pod2html would format my perldocs but it did not work when I
tried: pod2html perltoc (maybe perldoc pod2html says how to do it). Here
it is. Improvements, especially in output formatting, would be welcome.

#!/usr/bin/perl
use strict;
use warnings;
use CGI qw:)standard escapeHTML escape);
$CGI::pOST_MAX=1024 * 100; # max 100K posts
$CGI::DISABLE_UPLOADS = 1; # no uploads

my $a = 'perldoc to be displayed here';
if (param('display'))
{
if (my $doc = param('docname'))
{
$a = `perldoc $doc`;
}
}
print header(), start_html();
print start_form(), p('Type name of perldoc'),
p(textfield(-name=>'docname')),
p(submit(-name=>'display')),
end_form();
print hr, pre($a),end_html();


Thanks!

wana

I found a major security hole: someone could run whatever commands they want
on my system. I was wondering if the following would fix it or if I should
abandon the idea altogether.

if (param('display'))
{
my $doc;
if ($doc = param('docname')
and $doc =~ /\b\w+\b/)
{
$a = `perldoc $doc`;
$a = 'not found' if not $a;
}
else
{
$a = 'invalid perldoc name';
}
}

This at least restricts users from entering additional commands like:

perltoc > youdummy

and stuff like that by making sure they can only enter words that
match /\b\w+\b/ which will either be a valid perldoc name or not. Would
this make it safe enough for online use?
 
W

wana

wana said:
<posted & mailed>


I found a major security hole: someone could run whatever commands they
want
on my system. I was wondering if the following would fix it or if I
should abandon the idea altogether.

if (param('display'))
{
my $doc;
if ($doc = param('docname')
and $doc =~ /\b\w+\b/)
{
$a = `perldoc $doc`;
$a = 'not found' if not $a;
}
else
{
$a = 'invalid perldoc name';
}
}

This at least restricts users from entering additional commands like:

perltoc > youdummy

and stuff like that by making sure they can only enter words that
match /\b\w+\b/ which will either be a valid perldoc name or not. Would
this make it safe enough for online use?

or maybe:
/^[a-z]+$/
seems to work better.

This should allow only wall-to-wall one or more a-z so `perldoc $doc` should
not be able to run any other commands via redirection or pipes. This is
scary to play around with. Someone could have deleted all of my stuff
easily if I had let the link get out.
 
W

wana

wana said:
wana said:
<posted & mailed>


I found a major security hole: someone could run whatever commands they
want
on my system. I was wondering if the following would fix it or if I
should abandon the idea altogether.

if (param('display'))
{
my $doc;
if ($doc = param('docname')
and $doc =~ /\b\w+\b/)
{
$a = `perldoc $doc`;
$a = 'not found' if not $a;
}
else
{
$a = 'invalid perldoc name';
}
}

This at least restricts users from entering additional commands like:

perltoc > youdummy

and stuff like that by making sure they can only enter words that
match /\b\w+\b/ which will either be a valid perldoc name or not. Would
this make it safe enough for online use?

or maybe:
/^[a-z]+$/
seems to work better.

This should allow only wall-to-wall one or more a-z so `perldoc $doc`
should
not be able to run any other commands via redirection or pipes. This is
scary to play around with. Someone could have deleted all of my stuff
easily if I had let the link get out.

No! Try:

/^[a-z1-9]+$/

or you won't be able to read your perlfaq1 - perfaq9

oh boy!
 
T

Tad McClellan

wana said:
I am often (%50 of the
time) working on a machine that does not have Perl


Then it follows that during that 50% of the time you are not
doing Perl programming, since perl is not there.

You don't need access to the Perl docs when you are not programming
in Perl, so why is it that you think you need what you think you need?
 
B

Ben Morrow

Quoth (e-mail address removed):
I have been reprimanded for my lack of knowledge of perldoc material so I
have decided to do more reading. I realized that I am often (%50 of the
time) working on a machine that does not have Perl but is connected to the
internet. My first thought was to go to perldoc.com, but it seemed to be
down tonight, so I wrote a simple home-made solution to get by for now. I
was hoping pod2html would format my perldocs but it did not work when I
tried: pod2html perltoc (maybe perldoc pod2html says how to do it). Here
it is. Improvements, especially in output formatting, would be welcome.

#!/usr/bin/perl

USE TAINT MODE.

#!/usr/bin/perl -T

This would have caught the error you noticed for yourself.

Ben
 
W

wana

Ben said:
Quoth (e-mail address removed):

USE TAINT MODE.

#!/usr/bin/perl -T

This would have caught the error you noticed for yourself.

Ben

which perldoc explains taint mode? I searched perltoc and did perldoc -q
taint and didn't find much.

wana
 
A

A. Sinan Unur

ok, I read perlsec and did a little testing...
------------------
#!/usr/bin/perl -T

my $a = 'perl';
`perldoc $a`;

Exactly what it says. Since you have invoked your script via the perl
binary, you should specify the T switch on the command line:

perl -T test.pl

This does not really matter when you are only checking syntax. So, keep
the -T option on the shebang line but also specify it on the command line
if you are going to run the script via perl.
 
S

Sherm Pendley

wana said:
$a = `perldoc $doc`; #this is the dangerous line
$a = 'not found' if not $a;

IMNSHO, you're looking at this from the wrong direction.

Instead of trying to filter out any "bad" characters that might be
subject to special interpretation by the shell, bypass the shell
entirely by using the multi-argument version of open() instead of backticks.

Instead of trying to anticipate in advance what doc names might be
valid, just check the name you're given before running perldoc on it.

Something like this:

my @podpaths;
foreach my $path (@INC) {
push @podpaths, $path;
push @podpaths, "$path/pods";
}
push @podpaths, split(/:/, $ENV{'PATH'});

my $podfile = $doc;
$podfile =~ s%::%/%g;

my $pod;
PODSEARCH: foreach my $path (@podpaths) {
foreach my $ext ('', '.pm', '.pl', '.pod') {
if (-f "$path/$podfile$ext") {
$pod = "$path/$podfile$ext";
last PODSEARCH;
}
}
}

if ($pod) {
# You've already translated the doc name to a file path,
# so just pass the path to perldoc using its -F switch
open(PODFILE, '<', '/usr/bin/perldoc|', '-F', $pod)
or die("Could not open $pod: $!");
$a = join('', <PODFILE>);
close PODFILE;
} else {
$a = 'not found';
}

The above is typed into Mozilla, and is meant to be illustrative, not
complete. It's untested, and it's missing some important "boilerplate"
bits and output code.

sherm--
 
W

wana

Ben said:
Quoth (e-mail address removed):

USE TAINT MODE.

#!/usr/bin/perl -T

This would have caught the error you noticed for yourself.

Ben

ok, I read perlsec and did a little testing...
------------------
#!/usr/bin/perl -T

my $a = 'perl';
`perldoc $a`;
------------------
me> perl -c test.pl
Perl> Too late for "-T" option at test.pl line 1.
(what does that mean?)
me> ./test.pl
Perl> Insecure $ENV{PATH} while running with -T switch at ./test.pl line 4.
(ok, this is useful and expected)

now test the CGI program with -T...with the protective regex
screening removed...
------------------------------------------
#!/usr/bin/perl -T

use CGI qw:)standard);
if (param('display'))
{
if (my $doc = param('docname'))
{
$a = `perldoc $doc`; #this is the dangerous line
$a = 'not found' if not $a;
}
else
{
$a = 'invalid perldoc name';
}
}
print header(), start_html();
print start_form(), p('Type name of perldoc'),
p(textfield(-name=>'docname')),
p(submit(-name=>'display')),
end_form();
print pre($a), end_html();
-------------------------------------------
me> ./testcgi.pl
Perl> Content-Type: text/html; charset=ISO-8859-1

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"
xml:lang="en-US"><head><title>Untitled Document</title>
</head><body><form method="post" action="/./pd.bak"
enctype="application/x-www-form-urlencoded">
<p>Type name of perldoc</p><p><input type="text"
name="docname" /></p><p><input type="submit" name="display"
value="display" /></p><div></div></form><pre /></body></html>


ok, no error from the -T this time although it is equally insecure.
Actually, more so since the entire world now has access to it via
the web (not that Perl should be aware of that fact). Is that correct
that Perl will not pick up a taint problem in this case? I know that it
is not secure because I was able to enter commands and make them run before
adding a screening regex statement.

Thanks for any help.

wana
 
B

Ben Morrow

Quoth (e-mail address removed):
ok, I read perlsec and did a little testing...
------------------
#!/usr/bin/perl -T

my $a = 'perl';
`perldoc $a`;

This has been answered already...
me> ./test.pl
Perl> Insecure $ENV{PATH} while running with -T switch at ./test.pl line 4.
(ok, this is useful and expected)

now test the CGI program with -T...with the protective regex
screening removed...
------------------------------------------
#!/usr/bin/perl -T

use CGI qw:)standard);
if (param('display'))
{
if (my $doc = param('docname'))
{
$a = `perldoc $doc`; #this is the dangerous line
$a = 'not found' if not $a;
}
else
{
$a = 'invalid perldoc name';
}
}
print header(), start_html();
print start_form(), p('Type name of perldoc'),
p(textfield(-name=>'docname')),
p(submit(-name=>'display')),
end_form();
print pre($a), end_html();

Right... you are not passing any value for docname, so the undef that
CGI.pm gives you is not tainted. With

#!/usr/bin/perl -T

use strict;
use warnings;

use CGI qw/:standard/;

$ENV{PATH} = "/usr/bin:/bin";

my $doc = param 'docname';
my $pod = `perldoc $doc`;
print $pod;

__END__

I get

~% ./cgitaint docname=open
Insecure dependency in `` while running with -T switch at ./cgitaint
line 11.

as expected. If I add

$doc =~ /^([\w:]+)$/ ? $doc = $1 : die "Invalid perldoc name";

in the obvious place I get instead the docs for open.pm.
Is that correct that Perl will not pick up a taint problem in this
case?

No, it is not correct... do you have an example where this happens?

Ben
 
A

A. Sinan Unur

wana said:
Thanks for examples and advice. I found when I was at work today when I
tried to access my script via the web it would not run. It turns out it
was because of the -T. When I got home and removed it, it worked fine
again.

If you don't mind me asking, why did you remove -T instead of fixing the
insecure dependency?
 
W

wana

Ben said:
Quoth (e-mail address removed):
ok, I read perlsec and did a little testing...
------------------
#!/usr/bin/perl -T

my $a = 'perl';
`perldoc $a`;

This has been answered already...
me> ./test.pl
Perl> Insecure $ENV{PATH} while running with -T switch at ./test.pl
line 4. (ok, this is useful and expected)

now test the CGI program with -T...with the protective regex
screening removed...
------------------------------------------
#!/usr/bin/perl -T

use CGI qw:)standard);
if (param('display'))
{
if (my $doc = param('docname'))
{
$a = `perldoc $doc`; #this is the dangerous line
$a = 'not found' if not $a;
}
else
{
$a = 'invalid perldoc name';
}
}
print header(), start_html();
print start_form(), p('Type name of perldoc'),
p(textfield(-name=>'docname')),
p(submit(-name=>'display')),
end_form();
print pre($a), end_html();

Right... you are not passing any value for docname, so the undef that
CGI.pm gives you is not tainted. With

#!/usr/bin/perl -T

use strict;
use warnings;

use CGI qw/:standard/;

$ENV{PATH} = "/usr/bin:/bin";

my $doc = param 'docname';
my $pod = `perldoc $doc`;
print $pod;

__END__

I get

~% ./cgitaint docname=open
Insecure dependency in `` while running with -T switch at ./cgitaint
line 11.

as expected. If I add

$doc =~ /^([\w:]+)$/ ? $doc = $1 : die "Invalid perldoc name";

in the obvious place I get instead the docs for open.pm.
Is that correct that Perl will not pick up a taint problem in this
case?

No, it is not correct... do you have an example where this happens?

Ben

Thanks for examples and advice. I found when I was at work today when I
tried to access my script via the web it would not run. It turns out it
was because of the -T. When I got home and removed it, it worked fine
again.

wana
 
W

wana

A. Sinan Unur said:
If you don't mind me asking, why did you remove -T instead of fixing the
insecure dependency?

I should have done that but in this particular case, I decided I wanted the
insecure dependency because I wanted to run some more commands via the web.
I have wrapped the script in a secure login/session-based solution so I can
run an insecure script in a secure environment.

By the way, if anyone out there needs to get in shape and has joined a gym,
perldocs are great companions on the stair machines and bicycles. I just
print them on out and bring them with me (not on my own printer though :)).
Perlop is over 40 pages! One good perldoc can make a 30-60 minute aerobic
workout fly by in no time.

wana
 

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,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top