Hello,

After looking at the documentation of my shell, I propose the following patch for the command injection problem. (I assume this works for other Unix shells as well.)

Demo with some maliciously crafted file names:

$ ./jhead -cmd "ls &i" foo.jpg*
Cmd:ls "foo.jpg\`date\`"
foo.jpg`date`
Modified: foo.jpg`date`
Cmd:ls "foo.jpg;date"
foo.jpg;date
Modified: foo.jpg;date
Cmd:ls "foo.jpg\";date\""
foo.jpg";date"
Modified: foo.jpg";date"
Cmd:ls "foo.jpg\$HOME"
foo.jpg$HOME
Modified: foo.jpg$HOME

Greetings,
Bruno


diff -ru jhead-2.84/jhead.c jhead-2.84-mod/jhead.c
--- jhead-2.84/jhead.c  2008-10-04 18:10:35.000000000 +0200
+++ jhead-2.84-mod/jhead.c      2008-10-30 15:12:15.000000000 +0100
@@ -293,6 +293,33 @@

 #endif // MATTHIAS

+ //-------------------------------------------------------------------------- +// Escape an argument such that it is interpreted literally by the shell
+// (returns the number of written characters)
+ //--------------------------------------------------------------------------
+static int shellescape(char* to, const char* from)
+{
+       int i, j;
+       i = j = 0;
+
+// Enclosing characters in double quotes preserves the literal value of
+// all characters within the quotes, with the exception of $, `, and \.
+       to[j++] = '"';
+       while(from[i])
+       {
+               switch(from[i]) {
+                       case '"':
+                       case '$':
+                       case '`':
+                       case '\\':
+                               to[j++] = '\\';
+                       default:
+                               to[j++] = from[i++];
+               }
+       }
+       to[j++] = '"';
+       return j;
+}

 //--------------------------------------------------------------------------
 // Apply the specified command to the JPEG file.
@@ -316,13 +343,13 @@
         if (ApplyCommand[a] == '&'){
             if (ApplyCommand[a+1] == 'i'){
                 // Input file.
-                e += sprintf(ExecString+e, "\"%s\"",FileName);
+                e += shellescape(ExecString+e, FileName);
                 a += 1;
                 continue;
             }
             if (ApplyCommand[a+1] == 'o'){
                 // Needs an output file distinct from the input file.
-                e += sprintf(ExecString+e, "\"%s\"",TempName);
+                e += shellescape(ExecString+e, TempName);
                 a += 1;
                 TempUsed = TRUE;
                 unlink(TempName);// Remove any pre-existing temp file




--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to