KShell & KMacroExpander - are we screwed?

Oswald Buddenhagen ossi at kde.org
Fri Oct 5 15:52:01 CEST 2007


as previously discussed with puthuhn, we (well, *you*, in fact :-P) have
a serious problem. A short wrap-up first:

 * A short introduction into cmd semantics:
 * - Variable expansion is done first, without regard to *any* escaping -
 *   if something looks like an existing variable, it is replaced.
 * - Then follows regular tokenization by the shell. &, &&, | and || are
 *   command delimiters. ( and ) are command grouping operators; they are
 *   recognized only a the start resp. end of a command; mismatched )s are
 *   an error if any (s are present. <, > are just like under UNIX - they can
 *   appear *anywhere* in a command, perform their function and are cut out.
 *   @ at the start of a command is eaten (local echo off - no function as
 *   far as cmd /c is concerned). : at the start of a command declares a label,
 *   which effectively means the remainder of the line is a comment - note that
 *   command separators are not recognized past that point.
 *   ^ is the escape char for everything including itself.
 *   cmd ignores *all* special chars between double quotes, so there is no
 *   way to escape the closing quote. Note that the quotes are *not* removed
 *   from the resulting command line.
 * - Then follows argument splitting as described in
 *   http://msdn2.microsoft.com/en-us/library/ms880421.aspx .
 *   Note that this is done by the called application and therefore might
 *   be subject to completely different semantics, in fact.

the last point is suboptimal, but well, who cares. heh.
point two poses no significant problems, i think. the code to create
escaping that works on both levels is just ugly, nothing else.
the first point is a killer, though - unless somebody knows a solution
(in which case the rest of the mail is irrelevant).

kshell::quotearg quotes a single argument so it can be just appended to
a shell command line in a safe way. but we cannot guarantee the safety
(and by extension security) under windows. we could stuff each token
separately with dummy escapes (^) until no known variables are
referenced. of course, this does not help with variables that get into
the shell by ways not known to kshell.
additionally, weird variable names can be constructed from multiple
tokens - a low-level function like quotearg cannot do anything against
kshell::joinargs and kmacroexpander::expandmacrosshellquote are
similarly affected - their output is often used more or less directly as
a shell command. suppose the last part is true, they could
"dummy-escape" the string, assuming it is complete command. but they
still don't know if variables don't get to the shell from other sources
than the current environment.

possible solutions:
- ignore the problem. assume that a) regular urls, filenames, etc.
  don't produce existing variable names by chance and b) the regular
  environment does not contain anything dangerous and an attacker
  won't be able to manipulate the environment, so passing weird
  parameters intentioally won't help him.
  i guess anybody who considers this solution seriously should be shot.
- ban % from arguments. unrealistic - too common in urls. also,
  implementing error paths would mean quite some api magic now.
- screw cmd, v1: kprocess::setshellcommand is nuked again (at least on
  windows). user-provided commands are only subjected to
  kshell::splitargs and direct execution via kprocess (is special
  support for batch files needed?). the fear is that removing the
  kprocess function will only lead to devs home-growing equivalent code
  which is even worse, usually.
  v1a (applicable only to KRun, as the other variants have no proper
  error reporting facilities): refuse commands that contain % and at the
  same time reqire a shell. eeek.
- screw cmd, v2: use a posix shell under windows. things would be so
  much simpler for kde developers. windows power users would be
  surprised at first. otoh, they should be used to a complete lack of
  consistency when it comes to command lines. :=)

unless somebody has a better idea, i vote for screw cmd v2, and as a
last resort v1 for windows only.

Hi! I'm a .signature virus! Copy me into your ~/.signature, please!
Chaos, panic, and disorder - my work here is done.

More information about the Kde-windows mailing list