Skip to main content.
home | support | download

Back to List Archive

Re: [SWISH-E:380] RE: Using Parentheses

From: Eli's List Clearing House <lch(at)>
Date: Sat Jul 18 1998 - 13:55:42 GMT
Marjolein Katsma wrote:
> 1. To have SWISH-E execute a search, one needs to form a command line. That

One needs to fomr an argument vector.

> 2. This command line is then sent to the shell for execution. (By pressing

This need not be true. One can exec() the program directly, but this is
more complicated.

> 3. The shell will interpret the command line, execute what it can, and
> return the result (or an error code). 

When the shell is involved, yes.

> 4. ==> There are many different shells. Different shells have different
> special characters with a special meaning in the command line. Even the
> same special characters may be interpreted differently or in a different
> order by different shells.

True. BUT I am fairly confident that perl will use /bin/sh (Bourne shell)
for system() and open(FOO,"...|"). Run these to check:

perl -e 'system(q(ps|grep $$))'
perl -e 'open(FOO, q(ps|grep $$|));print <FOO>'

> When some kind of user interface allows the user to type in a string which
> becomes (or becomes part of) a command line, the user interface should take
> appropriate action to prevent any special characters from being interpreted
> by the shell rather than by the intended program. In particular, a SWISH-E
> interface should prevent the shell from interpreting ANY special character
> which is typed in as part of a query string.

You should be runing with perl in "taint" mode since that will make perl
complain loudly if you do insecure things. Use "#!/path/to/perl -T" as
the first line of the perl script. And read the perlsec(1) man page (or
"perldoc perlsec".)

> Actually, the Perl program for a search as generated by AutoSwish quotes
> the query string:
>     open(SWISH, "$swish -w \"$query\" -m $results -f $index|"); 

Double quotes are bad there.

      open(SWISH, "$swish -w '$query' -m $results -f $index|"); 

Double quotes allow things to be interpolated, single quotes do not.

> However, depending on what shell you're running, this may in fact 1) not
> work and 2) leave your sytem wide open to malicious attack!

Quoting conventions of "" vs '' are the same in sh, csh, ksh, bash, zsh,
tcsh, and probably most other shells. (Perl, too). Note that quotes within
quotes are different. In the open I wrote above perl will not see the
single quotes as special, since they are in double quotes. When the
shell gets it, there will be no outer quotes and the inner ones will
be active.

> My literature suggests that Bourne-type shells are most usual on System V
> type Unix systems, while C-type shells are usually found on BSD type Unix

Virtually all modern Unices have both sh and csh. (Unless they have 
bash and tcsh, which are free.)

> Well, I *have* tested this (I'm running on BSD with a C shell). That was
> well over a month ago (right after I translated the script generated by
> AutoSwish into PHP) - and I tested with some help from Unix-knowledgeable

What is PHP?

> and known-to-be-friendly people. One thing became very clear very soon:
> enclosing a search string in quotes when that contains any of the special
> characters for the C shell DOES NOT WORK. Any of those special characters

Nod. Change "any" to "many" though. Wildcard expansion like * and ?
will not occur.

> This is of course the reason I am NOT enclosing any search string in
> quotes: I'm escaping the command line (escaping the query string will have
> the same effect) instead. This is of course *also* the reason why PHP
> actually has an EscapeShellCmd() function which escapes *every* special

Use quotemeta() in perl. In a double quote context, you can invoke it like

      open(SWISH, "$swish -w \Q$query\E -m $results -f $index|"); 

Note that all non alpha-numerics get escaped by quotemeta, including

> 2. The documentation should not make clear "the need for quotes around the
> query string to make sure it is parsed appropriately." as you suggest. What
> it *should* do is make clear that an interface to SWISH-E should prevent
> *any* special character in a query string from being interpreted by *any*
> shell; and that the only secure way to do this is to *escape* every special
> character.

The sample perl scripts should run with -w to enable warnings, -T to enable
taint checks, and "use strict" to enforce good programing practices.

When I first came to swish I was very disappointed with the sample CGI
and wrote a new one with security very much in mind. I wrote to the
list and said that mine was available at

There are some bugs in that, because I have not kept it in sync with
the cgi I use, but those bugs are not signficant security holes --
since I do not escape "-"s in the input, the user can pass extra
options to swish-e. The other bugs are cosmetic. It is necessary
to run that with perl version 5.004 or higher, or else the delete()
statement might fail. Since there are known security holes in all
previous versions of perl, you should be running 5.004 anyway for
external services.

One major problem RE this discussion is that that cgi will not /let/
the user put parenthesis into the query.

Maybe I will try to fix it this weekend.

> I'm no Perl expert, but if Perl does not already have a function which does
> the equivalent of PHP's EscapeShellCmd() function, I'm sure a Perl expert
> would have no problem writing one of those nice Perl-one-liners using
> regular expressions to do exactly the same thing.


	$query =~ s/([^A-Za-z0-9])/\\$1/g;

Or use quotemeta:

	$query = quotemeta($query);

> (Actually, I think it's bordering on the irresponsible to release AutoSwish
> which creates scripts which could leave the user's system open to attack.

I would agree. 

> Final note: special characters (which may be typed in by a user) which
> should be escaped are (separated by spaces for readability):
> 	& ; ` ' " | * ? ~ < > ^ ( ) [ ] { } $ \

You should not rely upon such a list, but should escape all non-
alphanumerics so you don't have to worry about new evironments.

> And oh yes, you do of course realize that even people who can install and
> compile SWISH-E may *not* have the option of using a different shell?

If they don't have the option of using perl with the latest security
fixes then they will never be able to write a secure perl cgi.

now working on an Apache/mod_perl version of his search.cgi
Received on Sat Jul 18 08:01:36 1998