Security and Taint Mode

50.1 Taint Mode

With -T, data from outside (args, env, files, sockets) can't be used in operations that affect the system (shell, file writes, eval) until it's validated through a regex capture.

#!/usr/bin/perl -T
use v5.36;
$ENV{PATH} = '/usr/bin:/bin';                  # taint mode requires a clean PATH
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};

my $file = $ARGV[0];                           # tainted (external input)
# open my $fh, '>', $file;                     # dies: "Insecure dependency in open while running with -T"
my ($safe) = $file =~ /^([\w.-]+)$/            # untaint by extracting via a regex capture
    or die "Invalid filename\n";
open my $fh, '>', "/var/data/$safe" or die $!;
say ${^TAINT} ? 'taint mode on' : 'off';
use Scalar::Util qw(tainted); say tainted($file) ? 'tainted' : 'clean';

50.2 Common Vulnerabilities and Mitigations

List-form system/exec/open '-|'; never interpolate user input into shell strings; IPC::Run3/Capture::Tiny with arrays

DBI placeholders (?), $dbh->quote_identifier for identifiers, ORMs Two-argument open

Always use the three-argument form (open my $fh, '<', $file); 2-arg open interprets |, >, and leading/trailing spaces

Validate filenames, reject .., use File::Spec->no_upwards, resolve with Cwd::abs_path and check the prefix

String eval / /ee / (?{}) with user input Avoid; use dispatch tables XSS in web apps

Auto-escaping templates (Mojo <%= %> escapes by default; TT | html), HTML::Entities

Avoid nested quantifiers on user input, limit input length Crypt::URandom, Crypt::PRNG, Bytes::Random::Secure (not rand) for tokens

Crypt::Argon2, Crypt::Bcrypt, Authen::Passphrase Never Storable::thaw or eval untrusted data; use JSON Symlink races / temp files

File::Temp (secure creation), O_EXCL, operate on filehandles

Environment variables or secret managers; don't commit credentials

IO::Socket::SSL with verification (SSL_verify_mode => SSL_VERIFY_PEER), Mozilla::CA

Pin with Carton, check CPAN::Audit (cpan-audit deps .), keep Perl updated

perldoc perlsec is the primary reference. Perl::Critic has security-related policies (e.g., ProhibitTwoArgOpen, ProhibitStringyEval).