Bod has asked for the wisdom of the Perl Monks concerning the following question:
I am putting a unique string of text onto a PDF document using PDF::API2. Here is the minimal code to demonstrate:
This works as expected when taint mode is off. But, once taint mode is turned on I get:#!/usr/bin/perl -T use CGI::Carp qw(fatalsToBrowser); use FindBin qw($RealBin); my $safepath; BEGIN { if ($RealBin =~ m!^(/home/...path.to.site.../(test|uk)/www)!) { $safepath = "$1/../lib"; } else { die "Insecure access!"; } } use lib "$safepath"; use cPanelUserConfig; use PDF::API2; use strict; use warnings; my $pdf = PDF::API2->open("$ENV{'DOCUMENT_ROOT'}/../data/xmas/GiftSub +scription.pdf"); my $font = $pdf->font("$ENV{'DOCUMENT_ROOT'}/../data/xmas/Merriweather +.ttf"); my $page = $pdf->open_page(1); my $text = $page->text; $text->font($font, 36); $text->position(656, 403); $text->text('ABC-123'); $pdf->save("$ENV{'DOCUMENT_ROOT'}/test.pdf"); print "Content-type: text/plain\n\n"; print "$ENV{'HTTP_HOST'}/test.pdf\n";
Insecure dependency in open while running with -T switch at /usr/lib64 +/perl5/IO/File.pm line 187
I have replaced $ENV{'DOCUMENT_ROOT'} with hardcoded paths to ensure that it is not this that is causing the problem.
Is it possible to use PDF::API2 in taint mode or do I have to choose between finding another module or turning off taint mode?
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Insecure Dependency in Taint Mode
by kcott (Archbishop) on Nov 05, 2022 at 01:15 UTC | |
G'day Bod, "Is it possible to use PDF::API2 in taint mode ..." I'd say the short answer is "yes". Obviously, I can't reproduce your environment — apart from anything else, there's insufficient information, such as your Apache? configuration — however, the following test works fine.
Changing the last two (new() & save()) lines to:
also works without any problems. I checked:
I'm running Perl v5.36.0 and PDF::API2 v2.043. You've included completely unknown code with "use cPanelUserConfig;". Clearly, we're unable to test that. Try removing all of the code related to PDF::API2 and see if cPanelUserConfig is the cause of your taint issue. Your report suggests that you think PDF::API2 is the source of the problem, but you don't say why; you could be working from a false premise. I'd move strict and warnings to the start of your code. Was there a reason for putting these in the middle of the script? It's been 10-20 years since I last wrote any CGI code; my knowledge is certainly not current. I seem to recall that its documentation included troubleshooting tips involving running a CGI script from the command line. Perhaps look into that and see if it's any help. Have a look at "FindBin: KNOWN ISSUES" and what it says about issues with mod_perl. I'm very much guessing with this — I don't even know if you're using mod_perl — but it may be worth a look. Take a look through "perlsec - Perl security" for anything that might help. Perhaps the suggested:
If none of those suggestions help, you'll have to step through your code to find out where problems are occurring. — Ken | [reply] [d/l] [select] |
by Bod (Parson) on Nov 05, 2022 at 11:45 UTC | |
I'd say the short answer is "yes" That's encouraging - thanks kcott You've included completely unknown code with "use cPanelUserConfig;" cPanelUserConfig is a cPanel module. It performs some magic with @INC so that user installed modules can be found by Perl. PDF::API2 is a module I have installed so without cPanelUserConfig we won't get very far. Pretty much every script I write server side has this so I can be pretty sure this is not the cause of the issue. I'd move strict and warnings to the start of your code. Was there a reason for putting these in the middle of the script? As both strict and warnings operate for all the block regardless of where they are declared, I tend to use them to separate the head code from the actual mechanics of code. I'm sure there are proper terms that I don't know but by "head code" I mean the part of the code that sets thing up correctly such as the shebang, setting paths and bringing in modules to use. Everything below is what actually does the work of the script. Your report suggests that you think PDF::API2 is the source of the problem, but you don't say why Sorry - I should have explained that identical head code exists in all the other scripts on the site and they all run with taint mode on. It's only since I tried using PDF::API2 that I have had this problem and the error reports it as being in File which is used by PDF::API2 and not called by my script anywhere else. I'm out of the office currently but will look at the other things you suggest a little later and try removing/substituting code until I find the exact cause of the issue. | [reply] [d/l] [select] |
by kcott (Archbishop) on Nov 05, 2022 at 14:13 UTC | |
"cPanelUserConfig ..." I don't really want to harp on cPanelUserConfig. Here's a few quick notes: "As both strict and warnings operate for all the block regardless of where they are declared, ..." No, that's incorrect. Here's a handful of examples that I threw together to demonstrate:
"... the error reports it as being in File ..." Actually, the error reports ".../IO/File.pm" which is the core module IO::File. I seem to recall that you were stuck with a fairly early version of Perl by your ISP; although, I do think IO::File would have been available in whatever early version that was:
"... which is used by PDF::API2 and not called by my script anywhere else." You don't necessarily need to have a "use IO::File;" statement. Consider these two:
"... will look at the other things you suggest a little later ..." You might also like to try Carp::Always to get verbose backtraces. It can produce a lot of output, but could be a quick way to track down the source of the "Insecure dependency ..." message. Good luck with your troubleshooting. :-) — Ken | [reply] [d/l] [select] |
by pryrt (Abbot) on Nov 05, 2022 at 18:47 UTC | |
by kcott (Archbishop) on Nov 05, 2022 at 23:43 UTC | |
by Bod (Parson) on Nov 05, 2022 at 20:27 UTC | |
by AnomalousMonk (Archbishop) on Nov 05, 2022 at 13:14 UTC | |
Give a man a fish: <%-{-{-{-< | [reply] [d/l] [select] |
by tobyink (Canon) on Nov 05, 2022 at 17:29 UTC | |
This is not true, and you can verify it using:
Perl will complain about the use of symbol $y, but not $x because $x was used before strictures. Both strict and warnings use lexical scope, which means their effect starts where they're imported, and continues until the end of the block they were imported into (that is, the closing curly brace "}") or if they weren't imported into a block, until the end of the file. | [reply] [d/l] [select] |
|
Re: Insecure Dependency in Taint Mode
by pryrt (Abbot) on Nov 05, 2022 at 19:19 UTC | |
The problem you are having with taint here is exactly the same problem that you had before you learned how to untaint RealBin. Any time to want to use an external variable, like the $FindBin::RealBin or an $ENV{...} environment variable to access the filesystem, you have to untaint it. I used the command line on my cPanel-based webhost to prove the point: running DOCUMENT_ROOT=/home1/pryrtcom/public_html perl -T sscce-t.pl :
source:
Learn the lesson of taint: essentially anytime you use a variable that comes from the outside world, you have to untaint it before using it to access the filesystem. (Second lesson: taint error messages are unhelpful. The problem is not with IO::File, but with using a tainted variable to try to access the filesystem.) | [reply] [d/l] [select] |
by Bod (Parson) on Nov 05, 2022 at 20:36 UTC | |
Thank you pryrt - very helpful But in the original post I wrote: I have replaced $ENV{'DOCUMENT_ROOT'} with hardcoded paths to ensure that it is not this that is causing the problem However, given your comments and the troubleshooting help from kcott, I shall investigate further after food and watching some fireworks out of the window as it is Guy Fawkes Night here in the UK (much to the annoyance of Boomer, the office hound). | [reply] [d/l] |
by pryrt (Abbot) on Nov 05, 2022 at 22:29 UTC | |
I have replaced $ENV{'DOCUMENT_ROOT'} with hardcoded paths Sorry I hadn't noticed that statement. Though if you knew that already, it would have been nice if your SSCCE had removed that distraction. Especially because when I ran my original code, I was able to show a taint problem with $ENV{'DOCUMENT_ROOT'} and no problem when I had an untainted variable instead. I assumed that must be the culprit, since it matched your shown code. Taking out that, I can run an equivalent of every single line from your SSCCE script, with some extra debug prints, without flagging a taint problem.
Command: HTTP_HOST=127.0.0.1 perl -T sscce-t.pl Output:
Source:
(I tried with a font I uploaded, or one that was present on my host. Either one gave me the error when I ran the $pdf->font(...) line. I don't know if you're just not seeing that error because it's in a server logfile that you haven't checked, or whether you're not getting that warning, maybe because of using a different font or a different version of PDF::API2 -- that's one of the reasons I included the print of the module version in my code.) But with that code, I could not replicate your taint error. To emphasize to the advice from kcott, you need to narrow it down to which line of code is actually causing the taint problem. His example of loading a PDF and then immediately saving it (instead of loading, manipulating, and saving) will narrow it down to whether it's one of your manipulation commands that's causing the problem, or just writing the PDF to disk. Also, wrapping individual commands in eval (like I did in my first code example), with extra debug prints around, so you know exactly where it happens, would also be helpful to you. Also, if you have shell access to your host, it would be good to try running it from the command-line rather than just through the browser -- this will make it easier to see side warnings that are buried in a log file you haven't checked, and will also show if there's maybe something different going on between running through web interface and running through your host's command line. But as my two SSCCE's have shown, there is nothing inherently taint-unsafe with any of the PDF::API2 v2.043 commands that I ran, which I believe match in spirit the method calls you showed, so the problem seems to me to be something unique about the way you are using them, or arguments that you are passing to them, rather than inherent to the library. | [reply] [d/l] [select] |
by Bod (Parson) on Nov 05, 2022 at 22:47 UTC | |
|
Re: Insecure Dependency in Taint Mode
by afoken (Chancellor) on Nov 06, 2022 at 11:52 UTC | |
(Perhaps you should re-read Re: When not to use taint mode.) Insecure dependency in open while running with -T switch at /usr/lib64/perl5/IO/File.pm line 187 That's a hint, but not very helpful. So you managed to pass a tainted value to some IO::File method that calls open. In the current version of IO::FIle (v1.48), line 187 is at the end of the IO::File->open() method. Luckily, the Carp::Always module can help here. I use a simpler example to demonstrate it:
Note that you need to start perl with the -T flag if it is also in the #! line:
Now, that's more helpful error message. I messed up line 10 of my test script, passing a tainted $fn to IO::File->open(). 'w' can't be tainted, as it is a constant. Why is $fn tainted? Because it was copied from the tainted list of arguments @ARGV. (In theory, $fh could also be tainted, depending on what IO::File->new() does.) Update: How to debug CGIs from the command line: Re: Running a CGI script from a command line? Alexander
-- Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-) | [reply] [d/l] [select] |