Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^4: Using relative paths with taint mode

by Bod (Parson)
on Jun 19, 2021 at 23:24 UTC ( [id://11134045]=note: print w/replies, xml ) Need Help??


in reply to Re^3: Using relative paths with taint mode
in thread Using relative paths with taint mode

You don't just want to blindly untaint. You want to validate the input.

That makes sense...thanks

So, would a sensible approach be to check that $Bin resembles one of the places I expect it to be run from?
Something like this (untested):

#!/usr/bin/perl -T use CGI::Carp qw(fatalsToBrowser); use FindBin qw($Bin); if ($Bin =~ /^(\/home\/someuser\/somewebsite\/\w{2,4}\/cgi-bin)/) { $Bin = $1; } use lib "$Bin"; use Site::HTML; use strict; use warnings;
The \w{2,4} allows for the different subdomains used for development, testing, etc.

I don't recall seeing anything like that in any other Perl code I've seen that uses FindBin and lib so I'm guessing there is a better way to do it...

Replies are listed 'Best First'.
Re^5: Using relative paths with taint mode
by afoken (Chancellor) on Jun 20, 2021 at 09:37 UTC
    #!/usr/bin/perl -T use CGI::Carp qw(fatalsToBrowser); use FindBin qw($Bin); if ($Bin =~ /^(\/home\/someuser\/somewebsite\/\w{2,4}\/cgi-bin)/) { $Bin = $1; } use lib "$Bin"; use Site::HTML; use strict; use warnings;

    The \w{2,4} allows for the different subdomains used for development, testing, etc.

    A few notes:

    • \w can be problematic if you use locale, see perlsec. Better limit that more, e.g. lower-case ASCII letters.
    • You could avoid the leaning toothpick syndrome by using different quotes for the match operator:
      if ($Bin =~ m!^(/home/someuser/somewebsite/[a-z]{2,4}/cgi-bin/)!)
      It's not a security thing per se, it just makes the code more readable.
    • Your code lacks any handling for a failed validation. If $Bin does not match, you simply continue and hope that taint mode will kill your script. Make that explicit:
      if ($Bin =~ m!^(/home/someuser/somewebsite/[a-z]{2,4}/cgi-bin/)! ) { $Bin = $1; } else { die "Go away, stupid script kiddie!\n"; } # or maybe: $Bin =~ m!^(/home/someuser/somewebsite/[a-z]{2,4}/cgi-bin/)! or die "W +here am I?\n"; $Bin = $1;
    • You don't need to quote $Bin in use lib "$Bin".
    • You are mixing compile time and runtime. FindBin sets up $FindBin::Bin (and all other exported variables) at compile time. use lib uses $FindBin::Bin at compile time. Way after that, at runtime, you are validating and untainting $FindBin::Bin. That won't work. The easiest way to work around that is to use an expression after use lib, as in Re^2: Calculations before using lib; or Re^6: @INC from $0, that evaluates to the untainted version of $FindBin::Bin.
    • As explained in Re^5: Using relative paths with taint mode by ikegami, you should use $FindBin::RealBin instead of $FindBin::Bin.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re^5: Using relative paths with taint mode
by ikegami (Patriarch) on Jun 20, 2021 at 06:35 UTC

    That fails for a $0 of /tmp/script.cgi. Keep in mind that a caller can provide anything they want for $0; it doesn't need to have any relation to the script whatsoever. (While true for a binary executable, it's a bit different here...)

    I think it's ok if you use $RealBin instead of $Bin (which you should be doing anyway[1]), but I wouldn't rule out me overlooking something.


    1. $Bin fails when the program is launched using a symlink.

    Seeking work! You can reach me at ikegami@adaelis.com

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11134045]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (2)
As of 2024-04-25 20:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found