Strawman: MIME type for fonts

For a little while now, it’s been possible for websites to embed fonts that all major browsers will pick up on. This of course implies fonts being served as HTTP resources. But it turns out that nobody has bothered to assign any of the common font formats a MIME type.1 Fonts being embedded on the web nowadays come in two flavors and three kinds of container: you either have TrueType or PostScript CFF-style outline glyphs, and they are in a bare OpenType (really sfnt) container, or else compressed with either WOFF or EOT. (I am ignoring SVG fonts, which are spottily supported and open several cans of worms that I don’t want to get into right now.) In the future, people might also want to embed TTC font collections, which are also in a sfnt container and could thus also be compressed with WOFF—not sure about EOT there—and bare PostScript Type 1 fonts, but neither of these is supported in any browser at present, as far as I know. There is no official MIME type for any of these combinations; therefore, people deploying fonts over HTTP have been making them up. Without trying very hard, I found real sites using all of: application/ttf, application/otf, application/truetype, application/opentype, application/woff, application/eot, any of the above with an x-prefix, or any of the above in font/ instead of application/ (with or without the x-). There is no top-level font MIME category, making this last particularly egregious.

All of these made-up types work because browsers don’t pay any attention to the content type of a web-embedded font; they look at the data stream, and if it’s recognizably a font, they use it. Such sniffing has historically caused serious problems—recall my old post regarding CSS data theft—so you might expect me to be waving red flags and arguing for the entire feature to be pulled until we can get a standard MIME category for fonts, standard subtypes for the common ones, and browsers to start ignoring fonts served with the wrong type. But I’m not. I have serious misgivings about the whole the server-supplied Content-Type header is gospel truth, content sniffing is evil thing, and I think the font situation makes a nice test case for moving away from that model a bit.

Content types are a security issue because many of the file formats used on the web are ambiguous. You can make a well-formed HTML document that is simultaneously a well-formed CSS style sheet or JavaScript program, and attackers can and have taken advantage of this. But this isn’t necessarily the case for fonts. The sfnt container and its compressed variants are self-describing, unambiguously identifiable binary formats. Browsers thoroughly validate fonts before using them (because an accidentally malformed font can break the OS’s text drawing code), and don’t allow them to do anything but provide glyphs for text. A good analogy is to images: browsers also completely ignore the server’s content-type header for anything sent down for an <img>, and that doesn’t cause security holes—because images are also in self-describing binary formats, are thoroughly validated before use, and can’t do anything but define the appearance of a rectangle on the screen. We do not need filtering on the metadata, because we have filtering on the data itself.

Nonetheless, there may be value in having a MIME label for fonts as opposed to other kinds of binary blobs. For instance, if the server doesn’t think the file it has is a font, shouldn’t it be able to convince the browser of that, regardless of whether the contents of the file are indistinguishable from a font? (Old hands may recognize this as one of the usual rationales for not promoting text/plain to text/html just because the HTTP response body happens to begin with <!DOCTYPE.) The current draft standard algorithm for content sniffing takes this attitude with images, recommending that browsers only treat HTTP responses as images if their declared content type is in the image/ category, but ignore the subtype and sniff for the actual image format. With that in mind, here’s my proposal: let’s standardize application/font as the MIME type for all fonts delivered over the Internet, regardless of their format. Browsers should use only fonts delivered with that MIME type, but should detect the actual format based on the contents of the response body.

I can think of two potential problems with this scheme. First, it would be good if browsers could tell servers (using the normal Accept: mechanism) which specific font formats they understand. Right now, it’s reasonable to insist that browsers should be able to handle either TrueType or PostScript glyph definitions, in either bare sfnt or compressed WOFF containers, and ignore the other possibilities, but that state won’t endure forever. SVG fonts might become useful someday (if those cans of worms can be resolved to everyone’s satisfaction), or someone might come up with a new binary font format that has genuine advantages over OpenType. I think this should probably be handled with accept parameters, for instance Accept: application/font;container=sfnt could mean I understand all OpenType fonts but no others. The other problem is, what if someone comes up with a font format that can’t reliably be distinguished from an OpenType font based on the file contents? Well, this is pretty darn unlikely, and we can put it into the RFC defining application/font that future font formats need to be distinguishable or else get their own MIME type. The sfnt container keeps its magic number (and several other things that ought to be in the file header) in the wrong place, but as long as all the other font formats that we care about put their magic number at the beginning of the file where it belongs, that’s not a problem.


1 To be precise, there is a standard MIME type for a font format: RFC 3073 defines application/font-tdpfr for the Bitstream PFR font format, which nobody uses anymore, except possibly some proprietary television-related products. Bitstream appear to have been trying to get it used for web fonts back in the days of Netscape 4, and then to have given up on it, probably because the font foundries’ attitude was NO YOU CAN’T HAS LICENSE FOR WEBS until just last year.

Responses to “Strawman: MIME type for fonts”

  1. Paolo

    application/font-foobar or application/font+foobar?

  2. John Drinkwater

    I understand the purpose of application/ for anything not video|image|message etc, but throwing all the font-types into one application/font mime seems really ugly too. If you’re given video/x-msvideo, you know what the file is, just not what is contained… Here are some other lovely suggestions:

    application/font.opentype
    image/font+opentype
    1. Zack Weinberg

      But the whole point of the proposal is that we don’t need more than one MIME type for all font formats! If we needed a type per format, the Right Thing would clearly be to register a top-level font/ category.

      1. John Drinkwater

        If we needed a type per format, the Right Thing would clearly be to register a top-level font/ category. Then the right thing is the right thing to do, want me to write an RFC?

        Just imagine if the right thing hadn’t been adhered to:

        application/image?type=png
        application/video?type=avi&amp;codec=…

        OMG NO

        The more timely option here (standardisation) is the one to take. Suggest font/otf, font/woff and just start using it.

        1. Zack Weinberg

          Why do you say OMG NO? That’s exactly what I think should have been done, except without any annotations. Subtype information belongs in-band, and in fact is in-band for all the types you mention.

  3. John P

    Please, no.

    There are only a moderate number of font formats common on today’s web. Why not just give each their own proper MIME type and be done with it?

    I can see no particular reason to deviate from what is done for image/video formats, other than to the complex set of exceptions that is today’s web. You yourself present two reasons why not to do it, but no list of pros.

    MIME types get used as meta-data in circumstances way beyond HTTP delivery to web browsers, and are often the basis for deciding which applications/libraries can handle a format. You can’t expect every font handling app to support all font formats on one MIME type.

    Again, just because use in today’s browsers doesn’t need more than one MIME type for fonts is no excuse for doing this poorly.

    1. Zack Weinberg

      I see having only one MIME type encompassing all font formats as an improvement over the way things are currently done. I think it is wrong to dispatch for per-format processing based on metadata rather than file contents, and I wish to force people to stop doing that (and to stop designing file formats which require dispatch based on metadata because the contents are ambiguous).

      I have good reasons for this position, but I think I need to write a whole article explaining them. Please stay tuned.

  4. Crash

    the idea of application/font is good, but it would break many implementations. file -ib foobat.ttf would always return application/font. Even if it returns application/font;container=foo many programs would strip the part after ;, since they do the same with ;charset=. mime.types file (for example used by Lighttpd) could solve this, but as far as I know the files doesn’t contain any metadata behind the MIME type. Implementation shouldn’t be aware of that or use the same algorithm for stripping everything behind ;.

    So even if you deprecate the other MIME type defintitions, it would take years to change this. Same for font/foobar.

    1. Zack Weinberg

      Well, that’s a tricky case; my attitude is that the information currently stuffed into the MIME subtype belongs in-band and only in-band, but file(1) is the program that other programs invoke to perform inspection of in-band magic numbers, so it oughta be able to produce more detail if requested. At present it is reasonable to insist that any program claiming to handle application/font should handle both common sfnt variants and WOFF compression, but there might be more divergence in the future, e.g. if SVG fonts ever take off.

      On the whole I’d say do the application/font;container=foo thing and fix the breakage.