Subject: | Perl taint mode causes "Cannot determine local time zone" |
Date: | Mon, 07 Apr 2014 17:47:33 -0400 |
To: | bug-DateTime-TimeZone [...] rt.cpan.org |
From: | Stephen Ostermiller <1012web [...] ostermiller.com> |
The following command only fails when taint mode is enabled:
$ perl -T -MDateTime::TimeZone::Local -le 'print
DateTime::TimeZone::Local->TimeZone()->name'
Cannot determine local time zone
Tested against:
DateTime::TimeZone::Local::VERSION = '1.60'
perl 5, version 14, subversion 2 (v5.14.2) built for
i686-linux-gnu-thread-multi-64int
Linux 3.11.0-19-generic #33-Ubuntu SMP Tue Mar 11 18:48:32 UTC 2014 i686
athlon i686 GNU/Linux
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=13.10
DISTRIB_CODENAME=saucy
DISTRIB_DESCRIPTION="Ubuntu 13.10"
This appears to be because DateTime/TimeZone/Local/Unix.pm reads from
files and environment variables which causes that data to be "tainted".
It validates this data, but does not untaint this data before using it.
Lines such as:
return eval { DateTime::TimeZone->new( name => $name ) };
return NULL when taint mode is enable and $name is tainted.
My system should get the timezone from the /etc/timezone file which is
checked in the FromEtcTimezone method. The time zone name is validated
against _IsValidName which ensures that it is safe to use, but does not
untaint it. Untainting $name before it is used in the return statement
fixes the problem on my system.
($name) = ($name =~ /^(.*)$/g); # untaint
local $@;
local $SIG{__DIE__};
return eval { DateTime::TimeZone->new( name => $name ) };
Each of the methods in Unix.pm are likely to need untainting, but I have
only tested this fix with FromEtcTimezone on my system.