
Perl Security
Install when you write or review Perl (CGI, Mojolicious, Dancer2, Catalyst) and need taint mode, injection defenses, and safe DBI/process patterns.
Overview
perl-security is an agent skill most often used in Ship (also Build) that applies Perl taint mode, validation, safe execution, and web injection defenses before production Perl ships.
Install
npx skills add https://github.com/affaan-m/everything-claude-code --skill perl-securityWhat is this skill?
- Taint mode (`-T`) workflow: identify tainted sources, validate, then untaint before unsafe ops
- Parameterized DBI queries and disciplined input validation at trust boundaries
- Safe process and filesystem patterns when paths or commands come from users
- Web-facing guidance for XSS, SQL injection, and CSRF in Perl stacks
- Aligns reviews with perlcritic security policies for consistent static checks
Adoption & trust: 4k installs on skills.sh; 210k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your Perl app accepts query strings, uploads, or env data but you are unsure whether taint mode, DBI, or subprocess calls are actually safe.
Who is it for?
Solo maintainers of Perl web or CLI services who must harden user-facing input, DB access, and command execution without a full security team.
Skip if: Greenfield projects that have fully migrated off Perl, or pure data-science Perl with no external input surfaces.
When should I use this skill?
Handling user input in Perl, building Perl web apps (CGI, Mojolicious, Dancer2, Catalyst), reviewing Perl for vulnerabilities, file ops with user paths, executing system commands, or writing DBI queries.
What do I get? / Deliverables
After the skill runs, code and reviews reflect validated untaint paths, parameterized queries, and constrained file/process usage aligned with perlcritic security expectations.
- Hardened code snippets with validation and untaint
- Security review notes on injection and execution risk
- DBI query patterns using placeholders
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Security hardening is canonical on the Ship shelf before production, even when coding happens in Build. Content is appsec-focused—input boundaries, SQLi/XSS/CSRF, and shell/DB safety—not general Perl syntax.
Where it fits
Scaffold a Mojolicious route that reads query params only after taint validation and untaint.
Audit DBI calls in a legacy Catalyst app for string-interpolated SQL before deploy.
Patch a production CGI script after a path traversal report in user-supplied filenames.
How it compares
Use as a Perl-specific secure-coding playbook, not a generic OWASP checklist that ignores `-T` and DBI idioms.
Common Questions / FAQ
Who is perl-security for?
Indie developers and ops-minded builders shipping Perl web apps or scripts that handle untrusted input, files, shells, or SQL.
When should I use perl-security?
In Build while adding endpoints or file ops, and in Ship during security review—especially for CGI, Mojolicious, Dancer2, and Catalyst code paths.
Is perl-security safe to install?
It is documentation-only guidance; confirm fit with your deployment model and review the Security Audits panel on this Prism page before trusting third-party skill sources.
SKILL.md
READMESKILL.md - Perl Security
# Perl Security Patterns Comprehensive security guidelines for Perl applications covering input validation, injection prevention, and secure coding practices. ## When to Activate - Handling user input in Perl applications - Building Perl web applications (CGI, Mojolicious, Dancer2, Catalyst) - Reviewing Perl code for security vulnerabilities - Performing file operations with user-supplied paths - Executing system commands from Perl - Writing DBI database queries ## How It Works 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. ## Taint Mode Perl's taint mode (`-T`) tracks data from external sources and prevents it from being used in unsafe operations without explicit validation. ### Enabling Taint Mode ```perl #!/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)}; ``` ### Untainting Pattern ```perl 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 } ``` ## Input Validation ### Allowlist Over Blocklist ```perl 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; } ``` ### Length Constraints ```perl 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; } ``` ## Safe Regular Expressions ### ReDoS Prevention Catastrophic backtracking occurs with nested quantifiers on overlapping patterns. ```perl 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/^