Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

securing bash script

2 views
Skip to first unread message

houghi

unread,
Jan 3, 2010, 6:43:05 PM1/3/10
to
I have a script that should only show the man page of a command that I
enter. It uses the exec part and a field that you enter. I am on a Linux
machine.

However instead of entering just e.g. "man" to get the command "man man"
running, you could also enter "man; rm * -rf" and do whatever naughty
stuff you desire. That last one will first run `man man` and then `rm *
-rf`

Obviously not very safe. I could also use || or && or perhaps some other
things as well.

One method might be to see if all characters are 'real' characters, but
I am afraid that I might miss something. Does anybody have a good place
where I might find more information on this on how to do it in a safe
way or anybody any ideas?

The code:

<?php
// Add ?code to see the code
if (isset($_GET['code'])) { die(highlight_file(__FILE__, 1)); }
//
$ext=$_POST['name'];
?>
Enter a program name where you would like to see the man page:<br>
<form method="POST" action="<?php echo $PHP_SELF;?>">
<input type="text" name="name">
<input type="submit" name="submit" value="Submit!">
</form>

<?php
if(isset($ext)) {

$command="man";
$command="$command $ext";
// Output of the command
$raw=exec("$command",$out);
echo "Output for <b>$command</b><hr><pre>";
// Do things to the output if needed
$output=$out;
// The actual output
for($i=0;$i<=count($out);$i++)
echo $output[$i]."<br>";
echo "</pre>";
}

?>

houghi
--
Quote correct (NL) http://www.briachons.org/art/quote/
Zitiere richtig (DE) http://www.afaik.de/usenet/faq/zitieren
Quote correctly (EN) http://www.netmeister.org/news/learn2quote.html

r0g

unread,
Jan 3, 2010, 11:39:25 PM1/3/10
to


Avoid passing any user input to you bash command full stop, it's almost
always a bad and dangerous idea. The best solution is whitelisting where
possible. If all you want is man pages for installed apps it should be
simple enough to build such a whitelist. Indeed if you can do that it's
not much more effort to just grab the text of the man pages upfront and
save them in static files or a database so you don't need to be
contantly running shell commands.

If you absolutely can't avoid passing user input to a CLI make sure you
only accept a VERY limited character set, just a-z A-Z 0-9 - . and _
Itself a form of whitelisting.


Roger.

Message has been deleted
Message has been deleted

"Álvaro G. Vicario"

unread,
Jan 4, 2010, 5:03:10 AM1/4/10
to
El 04/01/2010 10:10, houghi escribi�:

> houghi wrote:
>>> If you absolutely can't avoid passing user input to a CLI make sure you
>>> only accept a VERY limited character set, just a-z A-Z 0-9 - . and _
>>> Itself a form of whitelisting.
>>
>> OK. I thought so, but wanted to be sure that there is nothing that is
>> already in php that does some sort of check.
>
> Here is what I use where $ext is the data enterd.
>
> $ext=strip_tags($ext);

I've always wondered why people apply HTML filters to input that is not
supposed to be HTML. I hate posting comments to blogs just to find out
that half of my text was removed because I started with "if x<y then".
The appropriate handling for "<" and ">" chars is escaping them; even in
HTML.

In this case, escapeshellcmd() and escapeshellarg() work pretty well
under Linux/Unix. (Of course, protecting against stuff like "cat
/etc/passwd" is an entirely different issue.)


> $ext=preg_replace('/[^a-zA-Z0-9+_.@-]/i','',$ext);
>
> Obviously I could write a test around it, but for now this is good
> enough for me.


--
-- http://alvaro.es - �lvaro G. Vicario - Burgos, Spain
-- Mi sitio sobre programaci�n web: http://borrame.com
-- Mi web de humor satinado: http://www.demogracia.com
--

Message has been deleted

"Álvaro G. Vicario"

unread,
Jan 4, 2010, 10:24:23 AM1/4/10
to
El 04/01/2010 15:31, houghi escribi�:

> �lvaro G. Vicario wrote:
>>> $ext=strip_tags($ext);
>>
>> I've always wondered why people apply HTML filters to input that is not
>> supposed to be HTML.
>
> The reason I apply them is because they should not be entering html
> code.

>
>> I hate posting comments to blogs just to find out
>> that half of my text was removed because I started with "if x<y then".
>> The appropriate handling for "<" and">" chars is escaping them; even in
>> HTML.
>
> Obviously. And thanks for the pointer to x<y. Not applicable here as
> ther should NOT be any html code in it. Could happen if a copy and paste
> went wrong.

I meant the very opposite: stripping HTML tags makes sense only if the
input *is* HTML. Otherwise, you're just removing substrings of the input
in a random fashion. In the best scenario, it won't harm. In the worst
scenario, you'll run something like...

backup_my_data --user='John' --password='ab<hk%>'

... and never know it's failing.

>> In this case, escapeshellcmd() and escapeshellarg() work pretty well
>> under Linux/Unix. (Of course, protecting against stuff like "cat
>> /etc/passwd" is an entirely different issue.)
>

> They are interesting to know. However it won't be sufficient as I want
> to avoid especially the "cat /etc/passwd" type of things.
> So when I enter "man;cat /etc/passwd" it will result in:
> man mancatetcpasswd
>
> And as this won't work, it also won't show things I don't want to show.
>
> But even if I would paswordprotect it and give only me the password, I
> want to aoid that I myself do something stupid. I am much more afraid of
> me doing something stupid then a hacker doing something smart. ;-)

Just take into account that the syntax of bash can get pretty
complicate. If you want to avoid "man;cat /etc/passwd" you have to
consider "man || cat /etc/passwd" and a huge bunch of variations, while
still being able to do the stuff you need.

Michael Fesser

unread,
Jan 4, 2010, 12:09:21 PM1/4/10
to
.oO(houghi)

>�lvaro G. Vicario wrote:
>>> $ext=strip_tags($ext);
>>
>> I've always wondered why people apply HTML filters to input that is not
>> supposed to be HTML.
>

>The reason I apply them is because they should not be entering html
>code.

It only becomes HTML if you/your application treats it like that. Until
then <foo> is just a normal string. Or in other words: If you always do
the normal and required validating/escaping, then a string containing
HTML tags will behave exactly the same way as without them. It only
becomes HTML if you print it back to an HTML page without escaping,
which of course would open the door for XSS attacks.

IMHO there's hardly a reason to use strip_tags() at all. In most cases
it simply doesn't matter if there are HTML tags or not, as long as the
string is properly handled. A string is a string, be it -foo- or <foo>.

>> In this case, escapeshellcmd() and escapeshellarg() work pretty well
>> under Linux/Unix. (Of course, protecting against stuff like "cat
>> /etc/passwd" is an entirely different issue.)
>

>They are interesting to know. However it won't be sufficient as I want
>to avoid especially the "cat /etc/passwd" type of things.
>So when I enter "man;cat /etc/passwd" it will result in:
>man mancatetcpasswd

Exactly. And because of this you can safely remove the strip_tags() -
the < and > chars will be killed by the regex already.

As an alternative to the replacing of invalid chars you could also do a
preg_match() test and reject all input that doesn't match the pattern.

BTW: In a case-insensitive match you don't need both upper- and lower-
case letters in the pattern. This regex does the same as yours:

/[^a-z\d+_.@-]/i

Micha

Message has been deleted
Message has been deleted

C. (http://symcbean.blogspot.com/)

unread,
Jan 5, 2010, 8:09:58 AM1/5/10
to
On Jan 4, 5:38 pm, houghi <hou...@houghi.org.invalid> wrote:

> Michael Fesser wrote:
> > Exactly. And because of this you can safely remove the strip_tags() -
> > the < and > chars will be killed by the regex already.
>
> I agree it is a bit overkill

>
> > BTW: In a case-insensitive match you don't need both upper- and lower-
> > case letters in the pattern. This regex does the same as yours:
>
> > /[^a-z\d+_.@-]/i
>
> Thanks.
>
> houghi

RTFM for escapeshellcmd()

C.

Message has been deleted
0 new messages