Bug 1355695 (CVE-2016-1238)
Summary: | CVE-2016-1238 perl: loading of modules from current directory | ||
---|---|---|---|
Product: | [Other] Security Response | Reporter: | Martin Prpič <mprpic> |
Component: | vulnerability | Assignee: | Red Hat Product Security <security-response-team> |
Status: | CLOSED WONTFIX | QA Contact: | |
Severity: | medium | Docs Contact: | |
Priority: | medium | ||
Version: | unspecified | CC: | apmukher, chris.travers, deisenst2, hhorak, jEPOYNET, jorton, jplesnik, mdshaikh, nupur.priya, perl-maint-list, peter, ppisar, psabata, rmeggins, sardella, security-response-team, slawomir, thoger, yozone |
Target Milestone: | --- | Keywords: | Security |
Target Release: | --- | ||
Hardware: | All | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | perl 5.22.3, perl 5.24.1 | Doc Type: | If docs needed, set a value |
Doc Text: |
It was found that perl can load modules from the current directory if not found in the module directories, via the @INC path. A local, authenticated attacker could create a specially crafted module in a writable directory and trick a user into running a perl program from that directory; if the module is not found in previous @INC paths, it will load and execute the attacker's module.
|
Story Points: | --- |
Clone Of: | Environment: | ||
Last Closed: | 2017-08-02 14:55:34 UTC | Type: | --- |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: | |||
Bug Depends On: | 1360425, 1411436 | ||
Bug Blocks: | 1354390, 1355696 | ||
Attachments: |
Description
Martin Prpič
2016-07-12 09:37:10 UTC
Created attachment 1178819 [details] CVE-2016-1238 maint-5.22-dot-in-inc.patch Created attachment 1178820 [details] CVE-2016-1238 maint-5.24-dot-in-inc.patch Acknowledgments: Name: the Perl project Upstream: John Lightsey (cPanel Security Team), Todd Rinaldo (cPanel Security Team) Created attachment 1182725 [details] CVE-2016-1238 maint-5.22-dot-in-inc.patch v2 Created attachment 1182726 [details] CVE-2016-1238 maint-5.24-dot-in-inc.patch v2 Upstream bug report, which remains private for now: https://rt.perl.org/Public/Bug/Display.html?id=127834 However, the issue is already public via other places including: http://www.gossamer-threads.com/lists/perl/porters/329911 https://www.debian.org/security/2016/dsa-3628 Created perl tracking bugs for this issue: Affects: fedora-all [bug 1360425] Please note that the fix does not fix the real cause -- having "." in Perl module search path list (@INC variable). It only patches every module bundled with upstream Perl (i.e. core modules) that loads another module which is deemed not to be delivered within upstream Perl (i.e. non-core modules). That is instead of not having "." in the default interpreter @INC array (see last lines of "perl -V" output), it changes some modules that do something like this: eval "require $module"; in this manner: + local @INC = @INC; + pop @INC if $INC[-1] eq '.'; eval "require $module"; That has these consequences: (1) It does not fix any of the thousands of modules distributed from CPAN or another upstream. And many of them are delivered by Fedora. (2) Applying the patches to perl package in Fedora will keep vulnerable Fedora packages that supersede some Perl core modules (i.e. dual-lived modules). E.g. Locale::Maketext module is delivered from perl-Locale-Maketext source package in Fedora. Not from perl source package. That means cloning this vulnerability to perl component is not enough. It should be cloned to perl-Locale-Maketext too. And probably to tens of other Fedora components. (3) It's possible that even plain "require Foo::Bar;" code not in the eval argument possess the vulnerability in Fedora. Even if Foo::Bar were core module. That's because Foo::Bar module can be delivered by a binary package that is not required when installing package that does the "require Foo::Bar;". Either on purpose or as a packaging bug. While I consider this case as improbable (upstream worked very hard on the patches, Fedora tries to specify all dependencies between packages), I cannot exclude it. Fedora maintainers will deliver the upstream patches as part of new perl versions 5.22.3 and 5.24.1 in the beginning of August. Fedora maintainers will patch the dual-lived modules independently. Due to nature of this bug, Fedora maintainers are pondering removing the "." path from the default @INC globally on the perl interpreter level. At least in F26 and probably F25. And adding the "." to the specific few modules that depends on it (inc::latest, inc::Module::Install). (In reply to Petr Pisar from comment #8) > Please note that the fix does not fix the real cause -- having "." in Perl > module search path list (@INC variable). It only patches every module > bundled with upstream Perl (i.e. core modules) that loads another module > which is deemed not to be delivered within upstream Perl (i.e. non-core > modules). That is correct. The thing is that "." has been in @INC for way too long, and hence it's relied on, and its removal will cause breakage. The info we got indicates that upstream may proceed with removing it in the future versions, but it's quite a big change for minor release. Hence this partial and more complicated fix to address recently-discovered cases where this issue has significant impact. I think this frankly a bad fix for the wrong problem. Removing the . may cause problems but doing it at the module level is likely to have very serious side effects. I am of the view that merely compiling a module should not have side effects. A patch suggested in most places (i.e Peter's patch above minus the dynamic scoping) adds very strange order-dependent bugs to programs. At least insisting that @INC should be localized bfore the modification helps. But changing inc just because a module was compiled strikes me as very, very bad practice and in fact I have been bitten by the order-dependent implications of the Debian approach to this "fix" already. The problem is not that a Perl module might include stuff from the wrong directories. The problem is that a perl *script* might. So I think the security concern here is rather badly scoped. This is NOT a module vulnerability unless modules are *adding* . to the INC directory. The right way, I think, to see this problem is that a program might not be written to address the implications of the INC directory. So if the concern is that if someone has a nightly run of prove running as root in their /tmp directory then the correct solution is to add to bin/prove: no lib '.'; That fixes the problem nicely and far more completely than the proposed fix here does and it does so without side effects. Keeping the fix limited to scripts rather than libraries ensures that exploits are prevented and that breakage is not a real problem. Insisting that one fixes it by removing the current directory from any possible position in @INC also means it cannot be carelessly added back in by using the -I. flag. So the proposed fix is rather overinclusive (and needlessly breaking) and underinclusive (in no way eliminating the vulnerabilities). I will give you a good example of the problem of making this the module's responsibility: use base Now without this sort of change, you do: use base 'MyNamespace::Submodule'; And away you go. With this sort of change, suddenly that breaks unless you do: use MyNamespace::Submodule; use base 'MyNamespace::Submodule'; Now you will note this ends up almost exactly equivalent except that the import() routine is run (more opportunity for malicious code if that is what you are worried about). So you haven't eliminated vulnerabilities. You have only increased annoyance. So, really, this is best seen as a script vulnerability, not a module one. Keep concerns cleanly separated and everyone wins. As a note, I put together a blog post which includes an exploit of this sort, how administrators can secure their systems and some general guidelines for Perl module developers. It also discusses a serious bug Debian included with their effort to fix this problem as well as recommendations for what Red Hat and others can do to help mitigate this problem. http://ledgersmbdev.blogspot.se/2016/07/notes-on-security-separation-of.html The best option for a resolution from Red Hat would be clear guidelines on Perl module development, an auditing of existing bin/ scripts to add no lib '.' where apropriate, and an option for sysadmins to be able to remove the '.' from @INC globally on a per system basis. But making the contents of INC the module's responsibility is a very bad idea and a system that cannot be readily understood cannot be readily secured. In original patch, a version was renamed to an incorrect one in a single core module distribution in perl (PathTools, carrying Path::Spec) Fixing commit: http://perl5.git.perl.org/perl.git/commitdiff/b13c68bf perl-5.22.2-362.fc24 has been pushed to the Fedora 24 stable repository. If problems still persist, please make note of it in this bug report. perl-5.22.2-354.fc23 has been pushed to the Fedora 23 stable repository. If problems still persist, please make note of it in this bug report. I've worked out what I believe to be a mitigation for this: Create the file CustomStartupCode.pm with the following content and place it somewhere in your @INC path (I placed it in /usr/lib/perl5/site_perl/5.8.8 for EL5): package CustomStartupCode; our $VERSION = 1.00; BEGIN { # CVE-2016-1238 Mitigation pop @INC if $INC[-1] eq '.'; } 1; ... Add the following to /etc/profile: PERL5OPT=-mCustomStartupCode export PERL5OPT Close any open shells, open a new one and issue: perl -le 'print "@INC"' ...the resulting list should no longer have the lone "." at the end. (In reply to Peter Ajamian from comment #21) > I've worked out what I believe to be a mitigation for this: > > Create the file CustomStartupCode.pm with the following content and place it > somewhere in your @INC path (I placed it in /usr/lib/perl5/site_perl/5.8.8 > for EL5): > Since RHEL-6, perl is compiled with -Dusesitecustomize option which provides /usr/local/share/perl5/sitecustomize.pl location for these system-wide initialization code. One can put the "pop @INC if $INC[-1] eq '.';" line there and then any perl invocation will execute it automatically on each Perl interpreter start-up. (One can selectively disable this feature by "-f" perl's run-time option.) Because all the upstream patches so far fixed only core modules and even they contain controversial changes, like the "base" module lost its ability to load optional modules, I think the most conservative fix would be not to fix it at all and only document that those who feel the urge to change the behavior, they can add the line into the /usr/local/share/perl5/sitecustomize.pl file. Such change will provide complete fix for all Perl modules, including non-core or third-party modules. (In reply to Petr Pisar from comment #22) > Since RHEL-6, perl is compiled with -Dusesitecustomize option which provides > /usr/local/share/perl5/sitecustomize.pl location for these system-wide > initialization code. Right, I only gave the above mitigation the way I did because it works in RHEL5. Certainly it is simpler to just use sitecustomize.pl for RHEL6 and 7. Current upstream situation is this: Modules bundled with Perl are sanitized to remove the trailing '.' from @INC before loading optional modules. 'base' module was reverted to original state, i.e. it does not sanitize @INC at all. Next Perl release, 5.26.0, will not have the '.' in @INC. When will the rpm with the real fix be released? The real fix is not have "." in the default @INC array at all. As the removal constitutes a serious change in the behavior (e.g. it breaks 8 % of CPAN distributions <http://cpan.simcop2387.info/failed.html>), I do not believe it's reasonable to deliver this fix in a frame of already released products like RHEL-7. You can definitely count with the fix in RHEL-8 or rh-perl526 software collection. Just to confirm, a remediation will not be provided via a patch to the package and the vendor recommended remediation for RHEL5 using Perl5 is Comment 21? Just to confirm as external auditors are asking. Apologies, we're RHEL6 so Comment #22 but same basic confirmation that a backport fix via the package won't be be provided based on the concerns expressed in Comment #26. Mitigation: The following examples will remove '.' from the module path : RHEL6 and above : Create a file /usr/local/share/perl5/sitecustomize.pl containing the line "pop @INC if $INC[-1] eq '.';" RHEL5: Create a perl module with the same code in a BEGIN block, and use the 'PERL5OPT=-m<module-name>' environment variable to load it before execution of a perl program. |