Check Perl 5.28.3 Coverage for Regular Expression Security Fixes
You will finish with a quick, repeatable check for whether a Linux host is running a Perl release at or after the 5.28.3 security update, and a way to decide whether an application accepts regular expressions from an attacker. The examples are read-only until the optional package update.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell, the perl command and permission to inspect the package database. Updating packages needs an administrator account and a maintenance plan. Do not try to reproduce the vulnerable expressions on a production host: the advisory concerns memory corruption, and the same class of input can also consume excessive CPU.
1. Check the interpreter you are actually using
Start with the executable found through your normal PATH. This is an ordinary command and does not need elevated privileges:
$ command -v perl
/usr/bin/perl
$ perl -e 'print "$^V\n"'
v5.38.2
The version on this machine is Perl v5.38.2, supplied by Ubuntu package version 5.38.2-3.2ubuntu0.6. Your output may differ. A distribution package can contain backported fixes, so the version string alone is useful evidence but not the whole package audit.
Checkpoint: record the path and version from your host. If a service uses a virtual environment, wrapper, container or hard-coded interpreter path, repeat this check in that same runtime. Checking your login shell does not prove that a service uses the same Perl.
2. Confirm the distribution package
On a Debian or Ubuntu system, ask dpkg-query for the installed interpreter package:
$ dpkg-query -W -f='${Package} ${Version}\n' perl
perl 5.38.2-3.2ubuntu0.6
For the documentation package, use the same check if it is installed:
$ dpkg-query -W -f='${Package} ${Version}\n' perl-doc
perl-doc 5.38.2-3.2ubuntu0.6
The local perl5283delta manpage is documentation for the 5.28.3 release, not a command that changes Perl. It describes the differences from 5.28.2 and names three regular expression compiler flaws: CVE-2020-10543, CVE-2020-10878 and CVE-2020-12723. The document also says there are no intentional incompatible changes from 5.28.2.
Do not compare perl-doc alone with the runtime. The documentation package supplies manpages; the interpreter package is what runs application code. If the two packages have different versions, treat that as a documentation mismatch to investigate, not as proof that the runtime is protected.
3. Decide whether the vulnerable input path exists
The release notes narrow the risk: an application is exposed when it evaluates regular expressions supplied by an attacker. A fixed expression in your source is a different case from compiling a pattern taken from a request, uploaded file, message or job payload.
Search application code and configuration for the boundary where external text becomes a pattern. Look for Perl constructs such as qr//, m// or s/// assembled from a variable, and for modules that compile a pattern on behalf of the application. Also inspect the caller: a safe-looking helper may still receive a request field.
$ rg -n --glob '*.pl' --glob '*.pm' --glob '*.psgi' \
'qr\W|m\W|s\W|regexp|regex|pattern' /path/to/application
rg: /path/to/application: No such file or directory
Replace /path/to/application with the real source directory. The example deliberately shows a failed placeholder path rather than pretending that a generic location exists. If your source is elsewhere, run the command there and review matches manually. A text search is triage, not a proof of exploitability.
Checkpoint: write down each untrusted-to-regex path, its process and its input limit. If no attacker-controlled pattern reaches Perl, the specific 5.28.3 issue is less directly relevant, but keeping Perl patched remains the correct baseline.
4. Run a harmless regression smoke test
You can confirm that this interpreter compiles and runs a normal regular expression without using a hostile pattern:
$ perl -e 'my $re = qr/^user-[0-9]+$/; print "matched\n" if "user-42" =~ $re'
matched
This proves only that an ordinary expression works. It does not prove that a vulnerable release is safe, and it does not test the CVEs. Avoid copying proof-of-concept input from an advisory into a production service or attaching it to a health check.
Check the bundled Module::CoreList version only as a documentation sanity check:
$ perl -MModule::CoreList -e 'print "$Module::CoreList::VERSION\n"'
5.20200601_28
Perl 5.28.3 updated that module from 5.20190419 to 5.20200601_28. This is a useful confirmation when comparing a 5.28 installation with the release notes, but it is not a security test and should not replace the runtime package check.
5. Update safely if the host is behind
If the runtime is older than the vendor's fixed package, use the operating system's normal security update process. This changes installed files and may affect applications, so schedule it, check your rollback path and test the service afterwards. An administrator is required:
$ sudo apt update
$ sudo apt install --only-upgrade perl perl-base perl-modules-5.38
$ perl -e 'print "$^V\n"'
Package names vary by distribution and Perl series. Do not paste the perl-modules-5.38 name unchanged on another release. First inspect available versions with your package manager, then use the vendor's documented security update. If your host is deliberately pinned to Perl 5.28, use the vendor's backported package rather than compiling a different interpreter beside it without checking which binary the service starts.
After an update, restart only the affected service if its process keeps the old interpreter loaded. Follow the service's maintenance procedure, then repeat the version check in the service runtime and run its application tests. If the update causes a regression, use the package manager's normal downgrade or snapshot recovery procedure; do not delete Perl files by hand.
6. Reduce exposure while patching
Do not accept arbitrary regular expressions merely because they are convenient. Prefer a fixed set of named patterns, or validate a user selector against an allow-list before selecting a pattern in code. Set sensible input and execution limits at the application or worker boundary. These controls reduce denial-of-service risk, but they are not a substitute for a patched Perl.
Keep the distinction clear: a pattern supplied by an attacker is a security boundary problem, while a fixed application pattern can still be expensive or buggy. If you need a security decision about a suspected vulnerability, preserve the input, Perl version, package version and service identity, then report it through your organisation's incident process. Do not put sensitive exploit data in a public issue.
Done means
- You checked the exact Perl path and version used by the relevant service.
- You recorded the distribution package version, not just the documentation version.
- You identified whether untrusted input can become a Perl regular expression.
- You used a harmless smoke test and did not run a memory-corruption proof of concept.
- Any update has an owner, a maintenance window, a verification test and a recovery path.
- Temporary input limits or allow-lists do not replace the package security update.