|Subject:||Flaws in Perl code due to unsafe module load path|
|Date:||Mon, 04 Apr 2016 22:22:56 -0500|
|From:||John Lightsey <lightsey [...] debian.org>|
|To:||team [...] security.debian.org, perl5-security-report [...] perl.org, Todd Rinaldo <toddr [...] cpanel.net>|
Hi there, I need some guidance from the Perl and Debian security teams on how to handle vulnerabilities related to Perl's inclusion of the current working directory in its default module load path. Todd raised this issue on the p5p list in 2012 when he was updating cPanel to Perl 5.14. The cPanel Security Team (my day job) took note of the problem late last year while we were auditing for local file read and write attacks. The problem was pervasive in cPanel's codebase and we resolved the issues with the assumption that this was a well established Perl behavior and cPanel's code was responsible for mitigating the risks. This work led to the discovery of several other interesting flaws in open source code and we've been working with the upstream authors to get those resolved. I started putting together a conference talk to summarize all of the work cPanel had put into this effort, the flaws we found and the tools we used. At that same time, Todd was putting together a patch submission to revisit the 2012 decision to leave the '.' in @INC in Perl. The more we've looked at this problem though, the more convinced we've become that this needs to be handled and resolved as a vulnerability in Perl itself. The major problem with this behavior is that it unexpectedly puts a user at risk whenever they execute any Perl scripts from a directory that is writable by other accounts on the system. For instance, if I'm logged in as root and I change directory into /tmp or an account's home directory, I can run any shell commands that are written in C, Python or Ruby without fear. The same isn't true for any shell commands that are written in Perl, since a significant proportion of Perl scripts will execute code in the current working directory whenever they are run. For example, if a user on a shared system creates the file /tmp/Pod/Perldoc/Toterm.pm, and then I log in as root, change directory to /tmp, and run "perldoc perlrun", it will execute the code they have placed in the file. The most severe example I've found on Debian is that apt-get will load and execute the /tmp/Log/Agent.pm file regardless of the directory it is started from since it automatically changes directory to /tmp. To reproduce this: mkdir -p /tmp/Log echo '`wall hello`;die;' >/tmp/Log/Agent.pm sudo apt-get update A very simplistic analysis of my personal Debian laptop shows that over 40% of the perl scripts have this behavior. You can run the same analysis with this ugly shell command: grep '^#!/usr/bin/perl' /usr/*bin/* | cut -d ':' -f 1 | xargs -n1 /bin/sh -c 'TEST="$0"; if [ "`strace -f perl -c \"$TEST\" 2>&1 | grep '\''stat(\"\..*\.pm\"'\''`" != "" ] ; then echo "Vulnerable: $TEST"; else echo "Not vulnerable: $TEST"; fi' Or to test an individual script you can do something like this: strace -f /usr/bin/perldoc perldoc 2>&1 | grep 'stat("\..*\.pm"' This kind of analysis definitely underestimates the number of affected scripts though. So...with all that explanation said... My question is, which codebase is supposed to fix this issue? I figure there are four possible answers to which piece of code was responsible for preventing these types of attacks: 1) The Perl interpreter for placing the '.' in @INC. 2) Any module that fails to remove the '.' from @INC before attempting to load other modules that are not specified as hard requirements. 3) Any script that loads any modules that end up exhibiting this behavior. 4) End users must avoid running Perl scripts in directories that other users can modify. The only vulnerable code is code that moves to an unsafe location on its own. At cPanel we started off with approach #3, then ended up leaning towards #1. I can probably provide a fairly good list of places that need to be fixed in Debian once I know exactly where to focus. I haven't contacted Debian's Perl team about this problem. Please CC whoever should be informed from that team if they are not already on the perl-security or debian-security lists.
Message body not shown because it is not plain text.