Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.89k stars 533 forks source link

tainted values in ternary conditional #9529

Open p5pRT opened 15 years ago

p5pRT commented 15 years ago

Migrated from rt.perl.org#59916 (status was 'open')

Searchable as RT59916$

p5pRT commented 15 years ago

From dean@cs.serenevy.net

This is a bug report for perl from dean@​cs.serenevy.net\, generated with the help of perlbug 1.35 running under perl v5.8.8.


perlsec states that​:

  $result = $tainted_value ? "Untainted" : "Also untainted";

is effectively

  if ( $tainted_value ) {   $result = "Untainted";   } else {   $result = "Also untainted";   }

Thus $result will not be tainted. This is not the case when the value contains an interpolated value.

  $foo = "untainted";   $result = $tainted_value ? "is $foo" : "Also $foo";

$result will be tainted following the above expression.

It would be nice if this could be made to work\, however if it can not be done due to "the principle of 'one tainted value taints the whole expression'" then the exception outlined in persec should be qualified.

Test script attached.

#!/usr/bin/perl -T use warnings; use strict; use Scalar​::Util qw/tainted/; use Test​::More tests => 16;

my $tainted = "true" . substr($^X\,0\,0); my $const = "blah"; my $value;

# Assumptions #------------ ok( tainted( $tainted )\, "tainted value is tainted" ); ok( $tainted\, "tainted value is boolean true" );

ok( !tainted( $const )\, "constant value is not tainted" ); ok( !tainted( "the $const" )\, "interpolated value is not tainted" );

# ternary #-------- $value = $tainted ? "the $const" : 1; is( $value\, "the $const"\, "ternary interpolation​: check value" ); ok( !tainted( $value )\, "ternary interpolation​: not tainted" );

$value = $tainted ? "the const" : 1; is( $value\, "the const"\, "ternary constant​: check value" ); ok( !tainted( $value )\, "ternary constant​: not tainted" );

# if-else #-------- if ($tainted) { $value = "the $const"; } else { $value = 1; } is( $value\, "the $const"\, "if-else interpolation​: check value" ); ok( !tainted( $value )\, "if-else interpolation​: not tainted" );

if ($tainted) { $value = "the const"; } else { $value = 1; } is( $value\, "the const"\, "if-else constant​: check value" ); ok( !tainted( $value )\, "if-else constant​: not tainted" );

# modifier #--------- $value = 1; $value = "the $const" if $tainted; is( $value\, "the $const"\, "modifier interpolation​: check value" ); ok( !tainted( $value )\, "modifier interpolation​: not tainted" );

$value = 1; $value = "the const" if $tainted; is( $value\, "the const"\, "modifier constant​: check value" ); ok( !tainted( $value )\, "modifier constant​: not tainted" );



Flags​:   category=core   severity=low


Site configuration information for perl v5.8.8​:

Configured by Debian Project at Fri Apr 25 20​:33​:47 UTC 2008.

Summary of my perl5 (revision 5 version 8 subversion 8) configuration​:   Platform​:   osname=linux\, osvers=2.6.24.4\, archname=i486-linux-gnu-thread-multi   uname='linux ninsei 2.6.24.4 #1 smp preempt fri apr 18 15​:36​:09 pdt 2008 i686 gnulinux '   config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.8 -Dsitearch=/usr/local/lib/perl/5.8.8 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dlibperl=libperl.so.5.8.8 -Dd_dosuid -des'   hint=recommended\, useposix=true\, d_sigaction=define   usethreads=define use5005threads=undef useithreads=define usemultiplicity=define   useperlio=define d_sfio=undef uselargefiles=define usesocks=undef   use64bitint=undef use64bitall=undef uselongdouble=undef   usemymalloc=n\, bincompat5005=undef   Compiler​:   cc='cc'\, ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\,   optimize='-O2'\,   cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include'   ccversion=''\, gccversion='4.1.2 20061115 (prerelease) (Debian 4.1.1-21)'\, gccosandvers=''   intsize=4\, longsize=4\, ptrsize=4\, doublesize=8\, byteorder=1234   d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=12   ivtype='long'\, ivsize=4\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8   alignbytes=4\, prototype=define   Linker and Libraries​:   ld='cc'\, ldflags =' -L/usr/local/lib'   libpth=/usr/local/lib /lib /usr/lib   libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt   perllibs=-ldl -lm -lpthread -lc -lcrypt   libc=/lib/libc-2.3.6.so\, so=so\, useshrplib=true\, libperl=libperl.so.5.8.8   gnulibc_version='2.3.6'   Dynamic Linking​:   dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-Wl\,-E'   cccdlflags='-fPIC'\, lddlflags='-shared -L/usr/local/lib'

Locally applied patches​:  


@​INC for perl v5.8.8​:   /home/duelafn/Perl/lib   /etc/perl   /usr/local/lib/perl/5.8.8   /usr/local/share/perl/5.8.8   /usr/lib/perl5   /usr/share/perl5   /usr/lib/perl/5.8   /usr/share/perl/5.8   /usr/local/lib/site_perl   .


Environment for perl v5.8.8​:   HOME=/home/duelafn   LANG=en_US.UTF-8   LANGUAGE (unset)   LD_LIBRARY_PATH (unset)   LOGDIR (unset)   PATH=/Local/bin​:/Local/bin/rcs​:/usr/local/bin​:/usr/bin​:/bin​:/usr/games   PERL5LIB=​:/home/duelafn/Perl/lib   PERL_BADLANG (unset)   SHELL=/bin/bash

p5pRT commented 12 years ago

From @jkeenan

The language in 'perlsec' is as the original poster reported. I ran his test and confirmed his observations​:

### not ok 6 - ternary interpolation​: not tainted # Failed test 'ternary interpolation​: not tainted' # at 59916.t line 24. ... not ok 14 - modifier interpolation​: not tainted # Failed test 'modifier interpolation​: not tainted' # at 59916.t line 47. ###

If the behavior matched the documentation these tests would have passed.

So\, what action should be taken?

Thank you very much. Jim Keenan

p5pRT commented 12 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 12 years ago

From @cpansprout

On Sat Nov 26 13​:54​:08 2011\, jkeenan wrote​:

The language in 'perlsec' is as the original poster reported. I ran his test and confirmed his observations​:

### not ok 6 - ternary interpolation​: not tainted # Failed test 'ternary interpolation​: not tainted' # at 59916.t line 24. ... not ok 14 - modifier interpolation​: not tainted # Failed test 'modifier interpolation​: not tainted' # at 59916.t line 47. ###

If the behavior matched the documentation these tests would have passed.

So\, what action should be taken?

I suppose the documentation should be clarified\, but it would be nice to make tainting less paranoid and only taint values that we *know* hail from tainted sources. The latter might be too hard to implement.

The current implementation taints any newly-created or assigned-to scalars in the current expression if any tainted value has been ‘looked at’\, where ‘looked at’ happens any time a tied variable would have a FETCH.

Does that make sense\, or is my explanation too opaque?

Thank you very much. Jim Keenan

--

Father Chrysostomos