Inspecting Safari on iPhone using the Safari (on desktop) DevTools

Harry Roberts explains how to inspect pages from MobileSafari (on your iDevice) using the Safari (on your Mac) DevTools.

It’s been a while since I’ve done this, but if I recall correctly you can — once set up — also debug pages in MobileSafari without needing a physical USB connection. It’ll run over Bluetooth.

Measuring Network Performance in Mobile Safari →

Debugging Intelligent Tracking Prevention in Safari

Simo Ahava:

The purpose of ITP is to prevent tracking tools’ access to data stored and processed in the browser. This involves things like blocking all third-party cookies and restricting the lifetime of first-party cookies.

In this article, I want to show you how to use the ITP Debug Mode. It’s a console logger that outputs all the actions taken by Intelligent Tracking Prevention on the user’s device or browser.

You can enable the logger using the “Enable Intelligent Tracking Prevention Debug Mode” option the Debug Menu.

ITP Debug Mode in Safari →

Stealing Local Files using the Web Share API (in Safari)

One of the features of the Web Share API is that it allows you to share files along with your share intent:

if (navigator.canShare && navigator.canShare({ files: filesArray })) {
    files: filesArray,
    title: 'Vacation Pictures',
    text: 'Photos from September 27 to October 14.',
  .then(() => console.log('Share was successful.'))
  .catch((error) => console.log('Sharing failed', error));
} else {
  console.log(`Your system doesn't support sharing files.`);

As unearthed by there’s a big security issue with it in Safari/MobileSafari:

The problem is that file: scheme is allowed and when a website points to such URL unexpected behavior occurs. In case such a link is passed to the navigator.share function an actual file from the user file system is included in the shared message which leads to local file disclosure when a user is sharing it unknowingly. The problem is not very serious as user interaction is required, however it is quite easy to make the shared file invisible to the user. The closest comparison that comes to mind is clickjacking as we try to convince the unsuspecting user to perform some action.

In their tests they’ve successfully stolen the local /etc/passwd or even the entire MobileSafari history (which is nothing more than a .sqlite file).

Apple first stated that they are only going to fix it in the Spring 2021 (!) Security Update, but after the post went public it now looks that they’ve changed course, as by now a fix has been committed into the Webkit Source:

+static Optional<URL> shareableURLForShareData(ScriptExecutionContext& context, const ShareData& data)
+    if (data.url.isNull())
+        return WTF::nullopt;
+    auto url = context.completeURL(data.url);
+    if (!url.isValid())
+        return WTF::nullopt;
+    if (!url.protocolIsInHTTPFamily() && !url.protocolIsData())
+        return WTF::nullopt;
+    return url;
-    Optional<URL> url;
-    if (!data.url.isNull()) {
-        url = context.completeURL(data.url);
-        if (!url->isValid())
-            return false;
-    }
+    if (!data.url.isNull() && !shareableURLForShareData(context, data))
+        return false;

Bonus points for naming that class WTF 😅

Apart from that quick fix in the code, the issue is also being discussed at the spec level in order to prevent other implementers from making the same mistake.

🤔 What about Chrome you might ask? Google Chrome (on Android) has an allowlist of permitted file extensions in place.

Stealing local files using Safari Web Share API →

Via Thomas Steiner (@tomayac) on Twitter

New WebKit Features in Safari 13.1

This year’s spring releases of Safari 13.1 for macOS Catalina, iPadOS, iOS, and watchOS bring a tremendous number of WebKit improvements for the web across Apple’s platforms. All of this with many more updates for improved privacy, performance, and a host of new tools for web developers.

These features stand out to me:

  • Pointer and Mouse Events on iPadOS
  • Web Animations API
  • Async Clipboard API
  • JavaScript Improvements: String.prototype.replaceAll() and Nullish Coalescing (??)
  • ResizeObserver
  • HTML enterkeyhint Attribute
  • Media APIs: Picture-in-Picture API and Remote Playback API
  • Subtitles and Captions

Great to see things like ResizeObserver finally make it into Safari. The Web Anmations even have gotten their own entry on the WebKit Blog.


The enterkeyhint attribute is something new to me. As the spec states, it allows you to set the word to be used on the enter button on virtual keyboards:

The enterkeyhint content attribute is an enumerated attribute that specifies what action label (or icon) to present for the enter key on virtual keyboards. This allows authors to customize the presentation of the enter key in order to make it more helpful for users.

Allowed values are:

  • enter: Typically inserting a new line.
  • done: Typically meaning there is nothing more to input and the IME will be closed.
  • go: Typically meaning to take the user to the target of the text they typed.
  • next: Typically taking the user to the next field that will accept text.
  • previous: Typically taking the user to the previous field that will accept text.
  • search: Typically taking the user to the results of searching for the text they have typed.
  • send: Typically delivering the text to its target.


New WebKit Features in Safari 13.1 →
Web Animations in Safari 13.1 →

How to enable HTTP3 in Chrome / Firefox / Safari

Mattias recently tweeted that his website can now be served over HTTP/3 “even though no browser supports it yet”.

While it’s true that no browser supports it out of the box right now, there are options to enable HTTP/3. Here’s how.

🧪 As with all experimental technolgy/features: things might break! Be warned!


Google Chrome

If you search chrome://flags you’ll find an option named “Experimental QUIC Protocol” which you can enable:

That alone however won’t do. You’ll also need to enable a specific HTTP3 version, apparently. This extra change cannot be done through chrome://flags, but only through a command line option.

To fully enable HTTP/3 in Chrome, you must launch it with the command line options --enable-quic --quic-version=h3-27 :

/Applications/Google\ Chrome\\ Chrome\ Canary --enable-quic --quic-version=h3-27


Set network.http.http3.enabled to true in about:config

At least Firefox 75 is required.


Safari Technology Preview Release 104 which was just released has added HTTP3 as an experimental feature. To enable it, you’ll first need to enable the “Develop” menu through its settings.

If you’re running (the unreleased) macOS 10.16 / iOS 14, you can now use the Develop menu and underneath Experimental Features enable it.

🙏 Thanks to Kai for digging up the fact that macOS 10.16 is required.


How to test this?

A good site to test your connection is Visit that site and open the DevTools of your browser (SHIFT+CMD+I). In the Network tab enable the protocol column and refresh the page.

Here’s an example of Firefox: is also a good site you can use. I did notice that Firefox for example sometimes loads that site using HTTP/1.1 and sometimes using HTTP/3 … experimental features, right? 😉


Did this help you out? Like what you see?
Thank me with a coffee.

I don't do this for profit but a small one-time donation would surely put a smile on my face. Thanks!

☕️ Buy me a Coffee (€3)

To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.

Webcam Hacking – The story of how I gained unauthorized Camera access on iOS and macOS

Amazing rundown by Ryan Pickren on how he gained unauthorized Camera access on iOS and macOS.

We started on a normal HTTP website and ended up on a bastardized blob URI in a Secure Context. Here is a quick summary of how we did it:

  1. Open evil HTTP website
  2. HTTP website becomes a data: URI
  3. data: URI becomes a blob: URI (with magic blank origin)
  4. Manipulate window.history (in 2 parts!)
  5. Create an about:blank iframe and document.write to it
  6. Dynamically give this iframe the sandbox attribute
  7. Attempt an impossible frame navigation using X-Frame-Options
  8. From within the iframe, a new popup and document.write to it
  9. Profit

From this popup, we can use the mediaDevices Web API to access the webcam (front or rear), microphone, screen sharing (macOS only) and much more!

The hack in action (user must have previously trusted, which is not unlikely):


Webcam Hacking – The story of how I gained unauthorized Camera access on iOS and macOS →

New WebKit Features in Safari 12.1

Jonathan Davis – Web Technologies Evangelist for Apple – has done a writeup on the new features that have landed in Safari 12.1, which is included with macOS Mojave 10.14.4 and iOS 12.2.

This release delivers web platform features that improve website integration with the operating system, new real-time communication capabilities, more compatible encrypted media support, and features that help developers reduce the need for polyfills.

Whilst Dark Mode most likely is the most touted feature, I’m especially excited to see Intersection Observer land as it allows you to do nifty stuff such as lazily load images, triggering events for position: sticky;, prefetch pages for links that are in the viewport, etc.

Supporting <input type="color" /> looks handy, yet (on iOS) I’d also like to be able to input a color hex code myself.

The <datalist> element also forms a nice addition, but the implementation (on iOS) needs some more work imho: the triangle on the right of the input makes me think it’s a dropdown. Upon tapping the input I get to see three of the defined options. Since I am under the impression that this control is a dropdown, I’m also left with the impression that I can only choose one of those three options that are initially presented … confusing.

Not mentioned in the post, but mentioned in the release notes, is the fact that Safari will now implicitly add rel="noopener" onto links that have target="_blank" set.

New WebKit Features in Safari 12.1 →
Safari 12.1 Release Notes →

🤔 Why should you care about rel="noopener"? Mathias Bynens – who else – has got you covered.

Rendering Sites Fullscreen in Safari on iPhone X / Introducing “User Agent Variables”

What the …?

By default, the new iPhone X in landscape mode will contain sites in the so called “safe area”, resulting in white bars being rendered on either side of the site (src).

The color, white by default, can be tweaked by altering the background-color on the <body> element. Do note that it’s only background-color though: it doesn’t take gradients/background images into account, so you won’t jump very far with this …

Cover it up!

By adding viewport-fit=cover to the viewport meta tag, it’s possible to make the site stretch out beyond the safe area so that it takes up the full width of the device (src)

<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">

Embracing the notch

Whilst the use of viewport-fit=cover indeed stretches out the site, it also has a side effect of “the notch” overlapping with the site’s content.

To cater for this, Apple has proposed the concept of “User Agent Variables”, accessible via the constant() function in CSS.

This function has been renamed to env()

The current list of proposed User Agent Variables is:

  • user-font-size: User’s requested font size
  • user-background-color: User’s requested background color
  • user-foreground-color: User’s requested foreground color
  • safe-area-inset-top: Inset, as a <length> from the top of the viewport to the title-safe content area.
  • safe-area-inset-right: Inset, as a <length> from the right of the viewport to the title-safe content area.
  • safe-area-inset-left: Inset, as a <length> from the left of the viewport to the title-safe content area.
  • safe-area-inset-bottom: Inset, as a <length> from the bottom of the viewport to the title-safe content area.

Using these safe-area-inset-* constants as the padding of a site, overlap of the notch can be prevented.

body {
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);

Additionally, these values can be used for elements that have position: absolute; / position: fixed; applied.

#element {
  position: fixed;

  /* default position */
  top: 0;

  /* “safe” position (iOS 11) */
  top: env(safe-area-inset-top);


Did this help you out? Like what you see?
Consider donating.

I don’t run ads on my blog nor do I do this for profit. A donation however would always put a smile on my face though. Thanks!

☕️ Buy me a Coffee ($3)

Safari Auto-Play Policy Changes for macOS

The Safari team:

Safari in macOS High Sierra uses an automatic inference engine to block media elements with sound from auto-playing by default on most websites. Safari 11 also gives users control over which websites are allowed to auto-play video and audio by opening Safari’s new “Websites” preferences pane, or through the “Settings for This Website…” option in the Safari menu. Further, a new power-saving feature prevents silent videos from auto-playing when either hidden in a background tab or otherwise off-screen.

Calling .play() on a <video> element will now return a Promise:

var promise = document.querySelector('video').play();

if (promise !== undefined) {
    promise.catch(error => {
        // Auto-play was prevented
        // Show a UI element to let the user manually start playback
    }).then(() => {
        // Auto-play started

Auto-Play Policy Changes for macOS →

Safari Technology Preview


Safari Technology Preview is a version of Safari for OS X, distributed by Apple, that includes a cutting-edge, in-development version of the WebKit browser engine. It’s a great way to test upcoming WebKit features and give feedback to the people building them when it’s most useful — early in development.

Think Webkit Nightly, but then in a Safari wrapped featureset (iCloud History, and iCloud Tabs). Features you can try now – which are currently not included in the latest stable Safari release – are ES6, Shadow DOM, CSP2, etc.

Safari Technology Preview →
Introducing Safari Technology Preview →