Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hash keys forget taintedness #22137

Open
leonerd opened this issue Apr 11, 2024 · 4 comments
Open

Hash keys forget taintedness #22137

leonerd opened this issue Apr 11, 2024 · 4 comments
Labels
taint Relates to taint-mode (`perl -T`)

Comments

@leonerd
Copy link
Contributor

leonerd commented Apr 11, 2024

The documentation on taint mode says that the only way to remove taint from a value is to perform a regexp capture on it, and look at the capture buffers. Not so - it turns out that the keys of hashes forget their taintedness too.

#!perl -T
use v5.36;
use Taint::Util;
my $val = "value";
say "1: ", tainted($val)?"TAINT":"not taint";
taint $val;
say "2: ", tainted($val)?"TAINT":"not taint";
my %h = ( $val => 123 );  
my ( $k ) = keys %h;
say "3: ", tainted($k)?"TAINT":"not taint";
1: not taint
2: TAINT
3: not taint

If hash keys remembered taintedness I would have expected the last line to read

3: TAINT
@leonerd
Copy link
Contributor Author

leonerd commented Apr 11, 2024

The documentation on taint mode says that the only way to remove taint from a value is to perform a regexp capture on it, and look at the capture buffers

Actually, now I mention that, perlsec does talk about this.

Still, as a quirk, I wonder whether it could be fixed. Either the HEK structure or the HE structure could store an additional bit to say if the key data should be considered tainted.

@demerphq
Copy link
Collaborator

demerphq commented Apr 11, 2024 via email

@mauke
Copy link
Contributor

mauke commented Apr 11, 2024

Still, as a quirk, I wonder whether it could be fixed. Either the HEK structure or the HE structure could store an additional bit to say if the key data should be considered tainted.

That would change behavior that's been in perl since 5.0 (I think) and documented (in perlsec) since 2003 (commit 595bde1). I bet there is code out there that depends on this. You can't even reasonably change it locally (behind use v5.42 or something): What if new-semantics code adds a tainted key to a hash and then passes the hash to old-semantics code that expects keys to never be tainted?

Anyway, what is the documentation that says the only way to remove taint from a value is to perform a regexp capture on it? I thought the only page that talks about taint mode in detail was perlsec, which does mention the hash keys thing (three times).

@Jake-perl
Copy link

This behavior is documented and consistent with Perl's taint mode design.

This should work;

use v5.36;
use Taint::Util;

my $val = "value";
say "1: ", tainted($val) ? "TAINT" : "not taint";
taint $val;
say "2: ", tainted($val) ? "TAINT" : "not taint";

my %h;
my $tainted_key = taint_keys($val);
$h{$tainted_key} = 123;
my ($k) = keys %h;
say "3: ", tainted($k) ? "TAINT" : "not taint";

sub taint_keys {
my ($value) = @_;
my $tainted_key = "$value";
taint $tainted_key;
return $tainted_key;
}

@leonerd leonerd added the taint Relates to taint-mode (`perl -T`) label May 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
taint Relates to taint-mode (`perl -T`)
Projects
None yet
Development

No branches or pull requests

4 participants