It probably makes sense for most pack formats to untaint. But I agree that it would be better if the "a", "A", and "Z" formats would not untaint. My guess is that it was an intentional features due to the other formats. But making an exception for those few makes perfect sense (or, more accurately, make it so feeding a tainted value as input to an a/A/Z format should cause the output of pack to also be tainted).
| [reply] |
Wierdly, it seems that in perl 5.8.8, either of packing and unpacking with "B*" untaints, unpacking with "N*" untaints; but packing with "N*" or packing and unpacking with "C*" or "a*" doesn't untaint a scalar. I've no idea what the correct behaiviour should be.
Not really related, but note that this command doesn't raise an insecure dependency error:
perl -wTe '() = unpack $ARGV[0], 1e9;' p
it segfaults.
However, the result of such an unpack is tainted, as can be seen from the error from this command.
perl -wTe '$z = pack "p", "hi\n"; $r = unpack $ARGV[0], $z; eval $r;'
+p
Update: I forgot to say that I found this bug when re-examining Re: What's your favourite method of untainting?.
Update: see perlbug ticket #52552.
| [reply] [d/l] [select] |
Those criteria for when untainting is done and when not look random to me.
Could it be as simple as whether the regex engine is used internally, during the parsing of the unpack template?
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] |
Perlsec starts of with enthusiastic claims as to it's protections but the text contains many caveats. Winnowing down to the grist, the following data sources are stated to be marked tainted. All command line arguments, environment variables, locale information (see perllocale), results of certain system calls ("readdir()", "readlink()", the variable of "shmread()", the messages returned by "msgrcv()", the password, gcos and shell fields returned by the "getpwxxx()" calls), and all file input are marked as "tainted". Italics are mine.
This would seem to say that all other system calls are not tainted.
The following statement would seem to confuse some: If an expression contains tainted data, any subexpression may be considered tainted, even if the value of the subexpression is not itself affected by the tainted data. I could not find where in perldoc the term expression is defined. I found the definition for a statement, but a statement in generally not considered to be an expression. An expression is generally considered to be a sequences of identifiers and operators, although in some languages an expression may include functions. This would seem to leave the exact requirement for pack() or unpack() in an unclear state. I note that it does not say that a statement will, in itself, taint data. This would seem to be reserved for the expressed system calls above.
In a more specific vien, ambrus writes:
Not really related, but note that this command doesn't raise an insecure dependency error:
perl -wTe '() = unpack $ARGV[0], 1e9;' p
Not sure what you are thinking here but it should seg-fault, regardless of where the 'p' pattern is received from you are asking to unpack a arbitrary memory offset. I far as I know perl does not ( yet ) promise to protect oneself from out of band memory accesses.
From perldoc -f unpack:
The "p" and "P" formats should be used with care. Since Perl has no way of checking whether the value passed to "unpack()" corresponds to a valid memory location, passing a pointer value that's not known to be valid is likely to have disastrous consequences.
In regards to the use of ARGV as a parameter to unpack, I would think that feeding a argument into unpack without validation could easily lead to bad consequences outside of whether the program is tainted or not, as clearly demonstrated my your example. The taint checks are included as a bookkeeping aid and not to prevent the programmer from hanging himself.
s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s
|-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,,
$|=1,select$,,$,,$,,1e-1;print;redo}
| [reply] |
echo print 'Some piece of nasty code'|perl -Tne"m[(.+)];$_=$1;eval;"
Some piece of nasty code
I don't see any additional risk by allowing my $untainted = unpack 'A*', $tainted;.
Nor any lesser risk by not allowing it.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
| [reply] |
For what it's worth, your well written test program allowed me to determine the code that changed the tainting behaviour: it was patch 24010:
Change 24010 by rgs@bloom on 2005/03/08 17:53:50
Subject: Encoding neutral unpack
From: perl5-porters@ton.iguana.be (Ton Hospel)
Date: Sun, 6 Mar 2005 18:29:38 +0000 (UTC)
Message-Id: <d0fi6i$k06$1@post.home.lunix>
It's quite a large patch: Show patch
| [reply] |