Subject: | Security problem: improper shell escaping in whiptail, cdialog and kdialog backends |
Date: | Sun, 27 Sep 2015 12:35:09 +0200 |
To: | bug-UI-Dialog [...] rt.cpan.org |
From: | Matthijs Kooijman <matthijs [...] stdin.nl> |
Hi,
it seems that the whiptail, cdialog and kdialog backends apply some
improper escaping in their shell commands, causing special characters
present in menu item titles to be interpreted by the shell. This
includes the backtick evaluation operator, so this constitutues a
security issue, allowing execution of arbitrary commands if an attacker
has control over the text displayed in a menu.
Here's a minimal script showing the problem:
#!/usr/bin/perl
use UI::Dialog;
my $d = new UI::Dialog ( order => ["whiptail"], height => 20, listheight => 5, debug => 1);
my @items = (1, "Running Debian `cat /etc/debian_version `");
my $selected = $d->menu( text => "Correctly escaped `here`", list => \@items);
Which produces:
Debug: /usr/bin/whiptail --menu "Correctly escaped \`here\`" "20" "65" "5" "1" "Running Debian \\`cat /etc/debian_version \\`"
┌───────────────────────────────────────────────────────────────┐
│ Correctly escaped `here` │
│ │
│ 1 Running Debian \8.0 │
As you can see, the ` are escaped using \, but then the \ is
additionally escaped itself, voiding its use. Adding some debugging
output in the menu() function in Backend/Whiptail.pm showed that this
line escapes the `:
my $args = $self->_pre($caller,@_);
And this line then additionally escapes the \, breaking things:
my $command = $self->_mk_cmnd(" --menu",@_);
This problem only occurs for the "list" option, not for the "text"
option. I suspect that plain strings work and strings in arrays break,
perhaps because _pre references arrays instead of copying them? I
haven't actually confirmed this, though.
What's interesting is that the zenity backend also uses shell commands,
but does not have this problem. Looking at its list() function (which is
called by menu()), it is similar to Whiptail's menu() but has:
my $command = $self->_mk_cmnd(" --list",$args);
so it passes $args instead of @_. Applying the same change to Whiptail
also makes Whiptail work correctly, but my Perl-fu is not strong enough
to know why, or if this would be a solution.
I suspect that some other functions (checklist(), radiolist(), perhaps
others) will suffer from the same problem, but I have not tested this.
I would think this problem would need a CVE assigned and perhaps be
coordinated with the Linux distribution security teams. Let me know if
you want to do this, else I'll contact the Debian security team and ask
them to handle this.
Gr.
Matthijs
Message body not shown because it is not plain text.