Safari User Agent Strings and Why Version Tokens Are Frozen
This article provides a comprehensive overview of the Safari web browser's user agent string structure across both macOS and iOS devices. Additionally, it explains why Apple and the WebKit team have intentionally frozen and simplified specific version tokens within this string to combat user-agent sniffing, enhance user privacy, and prevent websites from breaking when new browser and operating system updates are released.
What the Safari User Agent String Looks Like
A user agent (UA) string is a text identification that a web browser sends to every website it connects to. Historically, it was designed to tell the server what operating system and browser the user is running.
Today, a standard Safari user agent string on a desktop Mac looks like this:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15
On an iPhone, the mobile Safari user agent string looks like this:
Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1
Here is a breakdown of what these specific tokens mean:
- Mozilla/5.0: A legacy token used by all modern browsers to claim general compatibility with standard web rendering.
- (Macintosh; Intel Mac OS X 10_15_7): The platform and operating system token.
- AppleWebKit/605.1.15: The rendering engine powering Safari and its build version.
- (KHTML, like Gecko): Another legacy token indicating that WebKit behaves similarly to the KHTML and Gecko rendering engines.
- Version/17.4: The actual marketing version of the Safari browser currently in use.
- Mobile/15E148: Included on iOS devices to indicate a mobile interface.
- Safari/605.1.15: Identifies the browser itself as Safari.
The Problem of User-Agent Sniffing
User-agent sniffing is the practice where websites read the browser's UA string to determine how to display a webpage or which features to enable. Instead of checking if a browser actually supports a specific piece of code, the website looks at the version numbers in the UA string and makes an assumption.
This practice is fragile. When browser makers update version numbers or change the formatting of the UA string, poorly coded websites often misinterpret the new numbers. For example, when browsers transitioned from version 9 to version 10, many websites only read the first digit ("1") and blocked the browser, assuming it was an outdated version 1.
Why Safari Froze and Simplified Its Tokens
To stop user-agent sniffing and its negative side effects, the WebKit team froze most of the version tokens in the Safari UA string. If you look closely at the macOS UA string example above, you will notice several inaccuracies that are kept there intentionally.
1. Preventing Website Breakage The macOS version
token is permanently frozen at 10_15_7 (macOS Catalina).
Even if a user is running macOS 14 (Sonoma) on an Apple Silicon M3 chip,
Safari still reports that it is running on an Intel
processor with OS X 10_15_7. When Apple transitioned from
macOS 10 to macOS 11, websites relying on user-agent sniffing failed to
recognize the "11" and broke. Freezing the OS version and CPU
architecture ensures legacy websites continue to function properly.
Similarly, the AppleWebKit/605.1.15 token has been frozen
for years, even though the WebKit engine is updated constantly.
2. Enhancing User Privacy Web trackers use a technique called "browser fingerprinting" to identify and track users across the internet without using cookies. By combining a user's exact operating system version, hardware architecture, and browser build number, trackers can create a unique profile for an individual. By freezing and simplifying the UA string, Apple forces every Mac user to broadcast the exact same system information. This makes it significantly harder for trackers to distinguish one Safari user from another.
3. Forcing Modern Feature Detection By making the UA string an unreliable source for system specifications, Apple forces web developers to abandon user-agent sniffing. Instead, developers must use "feature detection." Feature detection means writing code that directly asks the browser if it supports a specific capability before running it, rather than guessing based on the browser's name or version number. This results in a more stable, future-proof web that works across all browsers, regardless of what their user agent string says.