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).