Learn secure Perl practices to prevent common code and web vulnerabilities.
Copy the install command and let the AI configure it · recommended for beginners
Please install the "perl-security" skill from askskill: 1. Download https://raw.githubusercontent.com/affaan-m/ECC/main/skills/perl-security/SKILL.md 2. Save it as ~/.claude/skills/perl-security/SKILL.md 3. Reload skills and tell me it's ready
Please review this Perl code for security risks, focusing on taint mode, input validation, command execution, SQL injection, and XSS, then provide fixes and example code.
A categorized security review with vulnerability explanations, severity levels, and corrected Perl examples.
I use DBI in Perl to access a database. Rewrite the following concatenated SQL into parameterized queries and explain how this reduces SQL injection risk.
Parameterized DBI query examples plus guidance on input handling and database security practices.
Based on Perl security best practices, create a team-ready secure coding checklist covering taint mode, file and process operations, web security, dependency review, and perlcritic security policies.
A structured Perl secure coding checklist suitable for code reviews and development standards.
Comprehensive security guidelines for Perl applications covering input validation, injection prevention, and secure coding practices.
Start with taint-aware input boundaries, then move outward: validate and untaint inputs, keep filesystem and process execution constrained, and use parameterized DBI queries everywhere. The examples below show the safe defaults this skill expects you to apply before shipping Perl code that touches user input, the shell, or the network.
Perl's taint mode (-T) tracks data from external sources and prevents it from being used in unsafe operations without explicit validation.
#!/usr/bin/perl -T
use v5.36;
# Tainted: anything from outside the program
my $input = $ARGV[0]; # Tainted
my $env_path = $ENV{PATH}; # Tainted
my $form = <STDIN>; # Tainted
my $query = $ENV{QUERY_STRING}; # Tainted
# Sanitize PATH early (required in taint mode)
$ENV{PATH} = '/usr/local/bin:/usr/bin:/bin';
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
use v5.36;
# Good: Validate and untaint with a specific regex
sub untaint_username($input) {
if ($input =~ /^([a-zA-Z0-9_]{3,30})$/) {
return $1; # $1 is untainted
}
die "Invalid username: must be 3-30 alphanumeric characters\n";
}
# Good: Validate and untaint a file path
sub untaint_filename($input) {
if ($input =~ m{^([a-zA-Z0-9._-]+)$}) {
return $1;
}
die "Invalid filename: contains unsafe characters\n";
}
# Bad: Overly permissive untainting (defeats the purpose)
sub bad_untaint($input) {
$input =~ /^(.*)$/s;
return $1; # Accepts ANYTHING — pointless
}
use v5.36;
# Good: Allowlist — define exactly what's permitted
sub validate_sort_field($field) {
my %allowed = map { $_ => 1 } qw(name email created_at updated_at);
die "Invalid sort field: $field\n" unless $allowed{$field};
return $field;
}
# Good: Validate with specific patterns
sub validate_email($email) {
if ($email =~ /^([a-zA-Z0-9._%+-]+\@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/) {
return $1;
}
die "Invalid email address\n";
}
sub validate_integer($input) {
if ($input =~ /^(-?\d{1,10})$/) {
return $1 + 0; # Coerce to number
}
die "Invalid integer\n";
}
# Bad: Blocklist — always incomplete
sub bad_validate($input) {
die "Invalid" if $input =~ /[<>"';&|]/; # Misses encoded attacks
return $input;
}
use v5.36;
sub validate_comment($text) {
die "Comment is required\n" unless length($text) > 0;
die "Comment exceeds 10000 chars\n" if length($text) > 10_000;
return $text;
}
Catastrophic backtracking occurs with nested quantifiers on overlapping patterns.
use v5.36;
# Bad: Vulnerable to ReDoS (exponential backtracking)
my $bad_re = qr/^(a+)+$/; # Nested quantifiers
my $bad_re2 = qr/^([a-zA-Z]+)*$/; # Nested quantifiers on class
my $bad_re3 = qr/^(.*?,){10,}$/; # Repeated greedy/lazy combo
# Good: Rewrite without nesting
my $good_re = qr/^a+$/; # Single quantifier
my $good_re2 = qr/^[a-zA-Z]+$/; # Single quantifier on class
# Good: Use possessive quantifiers or atomic groups to prevent backtracking
my $safe_re = qr/^[a-zA-Z]++$/; # Possessive (5.10+)
my $safe_re2 = qr/^(?>a+)$/; # Atomic group
# Good: Enforce timeout on untrusted patterns
use POSIX qw(alarm);
sub safe_match($string, $pattern, $timeout = 2) {
…
Audit Claude skills and commands with quick scans or full stocktakes.
Create iOS liquid glass interfaces with dynamic visuals and interactive morphing.
Record polished web app UI demo videos for walkthroughs, tutorials, and showcases.
Plan demand forecasts, safety stock, and replenishment for multi-location retail inventory.
Unify multi-channel notifications for routing, deduplication, escalation, and inbox consolidation.
Audit, plan, and implement SEO improvements for better search visibility.
Review security risks for auth, inputs, secrets, APIs, and sensitive features.
Apply modern Perl 5.36+ idioms and best practices for maintainable applications.
Apply Laravel security best practices for auth, vulnerabilities, APIs, and deployment.
Audit MCP servers for spec compliance, security risks, and remediation guidance.
Apply Django security best practices for safer auth, app defenses, and deployment.
Review Python, JS/TS, and Go code for security best practices.