Understanding MIME Types
A MIME type (Multipurpose Internet Mail Extensions type), also known as a media type or content type, is a standard label that identifies the format of a file or data being transmitted over the internet. Originally developed for email attachments, MIME types are now used throughout the web to tell browsers and other clients how to interpret and handle the data they receive. When a web server sends a file to a browser, it includes a Content-Type header that specifies the MIME type, and the browser uses this information to decide how to process the response.
MIME types are essential for the correct functioning of the web. Without them, browsers would have no reliable way to distinguish between an HTML page, a JPEG image, a JavaScript file, or a PDF document. The server's declaration of content type drives the browser's rendering and security decisions, making proper MIME type configuration a matter of both functionality and security.
MIME Type Format
A MIME type consists of two parts separated by a forward slash: a type and a subtype. Some MIME types also include optional parameters:
type/subtype; parameter=value
The type represents the general category of data (text, image, application, audio, video, font, multipart). The subtype identifies the specific format within that category. For example:
text/html- An HTML documentimage/png- A PNG imageapplication/json- JSON datatext/css- A CSS stylesheet
Parameters provide additional details. The most common parameter is charset, which specifies the character encoding:
Content-Type: text/html; charset=utf-8
Common MIME Types
Here are the MIME types you will encounter most frequently in web development:
Text Types
text/html- HTML documentstext/css- CSS stylesheetstext/javascript- JavaScript files (alsoapplication/javascript)text/plain- Plain text with no special formattingtext/xml- XML documentstext/csv- Comma-separated values
Application Types
application/json- JSON dataapplication/pdf- PDF documentsapplication/xml- XML dataapplication/zip- ZIP archivesapplication/octet-stream- Arbitrary binary data (default for unknown binary formats)application/x-www-form-urlencoded- HTML form dataapplication/ld+json- JSON-LD structured data
Image Types
image/jpeg- JPEG imagesimage/png- PNG imagesimage/gif- GIF imagesimage/svg+xml- SVG vector graphicsimage/webp- WebP imagesimage/avif- AVIF images
Audio and Video Types
audio/mpeg- MP3 audioaudio/ogg- OGG audiovideo/mp4- MP4 videovideo/webm- WebM video
Font Types
font/woff- WOFF fontfont/woff2- WOFF2 fontfont/ttf- TrueType fontfont/otf- OpenType font
Multipart Types
multipart/form-data- Form data with file uploadsmultipart/byteranges- Partial content responses
The Content-Type Header
When a web server responds to a request, it includes a Content-Type header that declares the MIME type of the response body. The browser relies on this header to decide how to handle the response:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1234
<!DOCTYPE html>
<html>...
Web servers determine the MIME type based on file extensions, configuration files (like Apache's mime.types or .htaccess AddType directives), or application logic. Misconfigured servers may send incorrect MIME types, causing browsers to mishandle content. For example, serving a JavaScript file as text/plain will cause the browser to refuse to execute it as a script (when X-Content-Type-Options: nosniff is set).
MIME Sniffing
MIME sniffing (also called content sniffing) is a browser behavior where the browser ignores the declared Content-Type and instead examines the content itself to guess the actual type. Browsers introduced this behavior to handle the many misconfigured servers on the early web that served files with incorrect or missing MIME types.
While MIME sniffing improves compatibility with poorly configured servers, it creates a significant security vulnerability. An attacker can exploit MIME sniffing by uploading a file that looks like one type but is interpreted as another. For example:
- An attacker uploads a file with a
.jpgextension that actually contains HTML and JavaScript. The server serves it asimage/jpeg, but the browser sniffs the content, detects HTML, and renders it as a web page, executing the embedded JavaScript. - A file served as
text/plaincould be sniffed astext/htmlif it contains HTML-like content, allowing XSS attacks through uploaded text files. - User-generated content served from the same origin as your application could be reinterpreted in dangerous ways.
X-Content-Type-Options: nosniff
The X-Content-Type-Options security header was created to address MIME sniffing attacks. The only valid value is nosniff:
X-Content-Type-Options: nosniff
When this header is present, the browser strictly follows the MIME type declared in the Content-Type header and never performs content sniffing. Specifically:
- Scripts will only execute if served with a valid JavaScript MIME type (
text/javascript,application/javascript). - Stylesheets will only apply if served with
text/css. - Images, fonts, and other resources are handled according to their declared type.
This header should be set on every response from your server. In Apache:
Header always set X-Content-Type-Options "nosniff"
In Nginx:
add_header X-Content-Type-Options "nosniff" always;
See our guide on configuring security headers for complete examples.
Best Practices for MIME Types
- Always set Content-Type: Never rely on the browser to guess the MIME type. Explicitly declare the correct type for every response.
- Always set X-Content-Type-Options: nosniff: This prevents browsers from overriding your Content-Type declaration, closing MIME sniffing attack vectors.
- Use correct MIME types: Serve JavaScript as
text/javascript, CSS astext/css, HTML astext/html, and so on. Incorrect types cause functional problems whennosniffis active. - Include charset for text types: Always specify
charset=utf-8for HTML, CSS, JavaScript, and other text-based content to prevent character encoding attacks. - Validate user uploads: Do not trust file extensions. Validate uploaded file content against the expected MIME type. Use server-side libraries that inspect file headers (magic bytes) to verify the actual file type.
- Serve user uploads from a separate domain: If your application allows user file uploads, serve them from a different domain (or subdomain) so that even if MIME sniffing occurs, the uploaded content runs in a different origin and cannot access your application's cookies or DOM.
- Use application/octet-stream for downloads: When serving files intended for download rather than display, use
application/octet-streamwith aContent-Disposition: attachmentheader to force the browser to download rather than render the file.
MIME Types and Content Security Policy
MIME types interact closely with Content Security Policy. CSP's script-src directive controls which scripts can execute, but the browser also requires scripts to have a valid JavaScript MIME type. With both CSP and X-Content-Type-Options: nosniff in place, an attacker faces multiple barriers: the injected script must come from an approved source, must have the correct MIME type, and must pass any nonce or hash requirements. This layered approach provides robust defense against XSS and content injection attacks.
A WAF can add an additional layer by inspecting uploaded files and response content to ensure MIME types are correct before they reach the browser.
Summary
MIME types are a fundamental building block of the web that tell browsers how to interpret the content they receive. Correct MIME type configuration, combined with the X-Content-Type-Options: nosniff header, prevents MIME sniffing attacks that can lead to XSS and other client-side vulnerabilities. Always declare accurate Content-Type headers, validate uploaded content, and deploy nosniff alongside your other security headers to maintain a secure web application.
Need help securing your infrastructure? Explore NOC.org plans to get started.