Default @INC current-directory limit in Perl 5.26+
0 reputation · 30 Jul 2021, 13:56 UTC
0 reputation · 30 Jul 2021, 13:56 UTC
Assess whether a legacy Perl application can be deployed on Perl 5.26 or later without changing code that implicitly loads modules from the current working directory.
Perl 5.26 removed the current directory from the default @INC module search path, while earlier releases included it by default. Setting PERL_USE_UNSAFE_INC=1 restores the older behavior but re-enables accidental loading from writable directories. Explicit path declarations such as use lib are the documented alternative, but the extent of implicit dependencies in existing code is unknown.
35775 reputation · 30 Jul 2021, 19:12 UTC
Starting with Perl 5.26, the current working directory (.) is no longer included in the default @INC search path. If a legacy application relies on implicit loading of modules from the directory where the script is executed, it will fail with a "Can't locate ... in @INC" error when migrated to Perl 5.26 or later.
Depending on your security requirements and the ability to modify the source code, use one of the following three approaches:
To restore legacy behavior without changing code, set the following environment variable in your deployment shell or systemd unit:
export PERL_USE_UNSAFE_INC=1
Warning: This is considered "unsafe" because it allows Perl to load modules from any writable directory the process happens to be in, which could lead to arbitrary code execution if an attacker can place a file in a directory the application accesses.
Modify the application entry point to explicitly add the required directories to @INC. Using FindBin is the most portable way to reference the script's own directory regardless of where the user is when they call the script:
use FindBin;
use lib "$FindBin::Bin";
If only a few specific files are loaded from the current directory, replace implicit require or do calls with explicit relative paths:
# Instead of: require "my_module";
require "./my_module.pl";
To verify if your current environment is affected, run the following command. On Perl 5.26+, the output should not contain a dot (.) unless the unsafe flag is set:
perl -e 'print join("\n", @INC)'
To identify potentially breaking code, search your codebase for use, require, or do statements that load files without a leading slash or dot. These are the candidates that relied on the implicit @INC behavior.
When documenting deployments across versions, specify the Perl Runtime Version as a prerequisite. For environments spanning pre- and post-5.26, document the PERL_USE_UNSAFE_INC variable as a legacy compatibility flag, but mark it as "Deprecated/Security Risk" to encourage a transition to use lib.
Diagnostic Note: Does the application change its working directory (chdir) during execution? If so, PERL_USE_UNSAFE_INC=1 may cause unpredictable module loading as the "current directory" shifts, making explicit paths via FindBin the only stable solution.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.