It looks like Twitter is using SFSafariViewController for their in-app browser. This is the system-recommended way of creating an in-app browser. It prevents the embedding app (Twitter in this case) from reading website data and injecting JavaScript into the view. You can also break out of the session into Safari pretty trivially by hitting the Safari button in the lower right corner.
Apps that implement a custom web browser using WKWebView (e.g. IG) are much worse and can do those nefarious things.
Came here to say this. Custom webviews like Facebook likes to use are another matter but SFSafariViewController is for all intents and purposes real Safari with per-app cookies, storage, etc to bust tracking.
And I have to say, I would be pretty irritated if every site demanded to open in my main browser. Many if not most links I tap are quick one and dones I’d prefer to not clutter up my tabs.
I disagree. If it's a link to the web, I want my main, default browser everytime. No exceptions. The context switching is never an issue for me.
App browsers screw up magic links too. I wish they'd go away.
> And I have to say, I would be pretty irritated if every site demanded to open in my main browser. Many if not most links I tap are quick one and dones I’d prefer to not clutter up my tabs.
Sure, but why does that have to imply that you get "per-app cookies, storage, etc"? What I want is a Safari tab as a modal temporarily overlaying the app. It is a tab of my regular web browser, with access to my regular web-browsing profile, and without the app having access to it any more than the app would have access to a tab it caused to open in regular Safari — except that 1. it doesn't show up in Safari's tabs, only as a window "stuck on top of" the particular app; and 2. the window knows what it's displaying is ephemeral, so it's easy to close it and return to the app by just swiping it away. (A lot like the Safari long-press preview modal, actually.)
Basically, SFSafariViewController should work less like an isolated browsing session, and more like the way OS file-pickers work in desktop OSes — where the UI-as-client makes a synchronous request to another app-as-IPC-server to pop a window, and then blocks until that window goes away.
I do agree that SFSafariViewController should use the newer style of sheet that can be pulled down on to be be dismissed. It makes more sense than the current navigation stack style presentation, and the extra context of the spawning app being visible around the top edges under the sheet would be helpful in app switcher.
The reason SFSafariViewController switched to per-app containers is because the older behavior in iOS 9/10 where it used the same environment as the browser proper was being rampantly abused for advertising/tracking purposes, dampening the benefits of it being out-of-process and isolated from the spawning application. I suppose it might be nice to have a setting to toggle this behavior, but it'd need to have disclaimers with red text next to it to prevent advertisers, etc social engineering users into toggling modes.
> the older behavior in iOS 9/10 where it used the same environment as the browser proper was being rampantly abused for advertising/tracking purposes
How did this work, exactly? Was the app able to observe/interact with the SFSafariViewController in any way? In my mind, the SFSafariViewController should literally "be" a Safari tab, in the sense that once it's open, the spawning app has no more connection to it than it would have to a tab in Safari itself which it caused to open; other than the fact that this tab would be 1. modal on top of the app, like a sheet; and 2. the app would be told when you closed this sheet, so that it could pause anything actively going on "underneath" the sheet until it was closed.
(And, to be clear, the Safari tab would be running _in_ Safari, and just composited onto the sheet, rather than running inside the app process in any way. This is how OS file-pickers et al work, which is what I was trying to get across with that comparison.)
The closest analogy would actually be within the browser itself: one browser tab using JS window.open(target=_blank, opener=false) to open another browser tab within the same browsing profile, where the new tab loads a page from a different origin; where when that new tab gets focused, the original tab gets obscured, and so the page it has loaded is given a visibilityStateChanged event; followed by another one when you close the new tab and the original tab comes back to focus.
No, apps didn’t have any more ability to observe/interact with the view controller than they do now. SFSafariViewController has always been a separate process spawned by the OS, not the app. It was for all intents and purposes a “real” Safari tab the app couldn’t touch.
The way tracking was happening is by apps putting an identifier in the URL, which JavaScript put into the linked page by the authors (social media widgets, Google Analytics, etc) would pick up on the cookies and other identifiers in the SFSafariViewController session carried over from “real” Safari and then tie those with the URL identifier. Boom, Twitter, etc have a nicely fleshed out tracking/advertising profile to attribute to that clicked link, even though they didn’t use a custom webview.
This is exactly how tracking works with regular browser tabs, too. The only way to mitigate it is to give each app its own separate Safari container for SFSafariViewController to run in and encourage devs to use SFSafariViewController instead of the full browser.
What you describe can be achieved by the app opening the page via the system browser. I don’t see any benefit of using a tab in the app instead. The swipe-left gesture at the bottom makes app switching super fast, making rapid switching between app and page a better experience than dragging and re-opening.
Why shouldn't clicking a link open your browser application? It's done that the entire history of the web and computing.
Embedding a browser in apps to try to keep users "engaged with your brand" after they have already clicked a link to leave for the web is a new thing and is erroneous. Why would you be irritated that clicking a web link opens the link in the browser? That's what's supposed to happen.
Because I don't necessarily want the link I'm visiting cluttering my history and tabs, and I probably don't want the site in question to have access to my cookies and whatnot. It's much more likely that I'll check out random links in apps (HN client, reddit, twitter, etc) if I know SFSafariViewController will be there to act as a wall between the visited site and my primary browsing setup.
The only thing I can see acting as a replacement is iOS offering to open links from external apps in a private browsing tab instead of a regular one.
> * probably don't want the site in question to have access to my cookies and whatnot*
Er, why not? Sites don't get access to any random old cookie, they get access to cookies they themselves have set before (more or less). Why should a tap from a native app be any different wrt cookie access than if you navigated to the site yourself in the web browser?
> Sites don't get access to any random old cookie, they get access to cookies they themselves have set before (more or less).
Well, kinda. Remember Facebook are able to track people around the web using their famous embedded Like button. This happens regardless of whether the button is clicked.
This is unfortunately under-reported, so I'll make do with linking to, of all places, BuzzFeed:
This behaviour is possible because most browsers aren't configured to block third party cookies. Make sure you've set yours to do so, and embedded content like Facebook's like button will see you as a fresh user every time.
Why should this clutter up your tabs, though? Hitting the back button/making the back gesture should (given a sane implementation) close the tab and return you to the native app where you clicked the link, no?
This already happens when apps open links in safari. There’s a little back button in the top left of the screen to go back to the app which opened that webpage.
Many apps have this setting but some don't. When they do it is invariably buried in the most inconvenient and hard to find place, different in every app, named something non-obvious, moved every year or so when some PM decides that the settings screen needs rearranging, and it is never synced or saved so you have to set it separately on every device and again whenever you get a new device, in every app.
Hell, I remember that both Facebook and Instagram used to have this setting! I uninstalled both of them quite some time ago, but I assume from the gripes in the article that this option has been removed.
If it’s like the one in Google Maps, it’s just an ad for Chrome. Chrome shows in the list whether or not it’s installed, with an option to get it from the App Store.
On the other hand I am almost always annoyed at apps opening websites in SFSafariViewController, and would prefer to be able to completely disable it and have it always open in the real browser.
Still, apps do this against the interest of the user, to keep them inside their app.
In some apps even if you find a setting that disables this "feature", they then don't open links not in my default browser (firefox) nor in safari, but chrome.
So it sounds like the solution here is to not cater to Open Web Advocacy's particular flavor of advocacy as the article prescribes, but in fact, prohibit apps from using any webview except the official one provided by the OS.
That's a very large assumption, one I think is outright false considering the discussion I've read about this post. The issue is that apps are allowed to embed webviews to do malicious things.
No, it's a large assumption that users want to open a link in an in-app browser. Why would they? On the other hand, there are clear motives for the app to keep users in the app as much as possible. Because the in-app browser in general is a degraded experience, for example being logged out of habitual websites, the user won't navigate the web as usual, and will soon return to the app. It's nothing but a dark pattern.
Your opinion is in the minority, even among the very technical folks I've seen discussing this issue. It's entirely false to reclassify a feature many users want as a dark pattern.
Let me give you an example personally: I want my RSS feed reader to use an in-app browser. Because unless I am going to get significantly more in depth, I just want to see the page content, and then swipe or back out to where I was in my feed very quickly.
iOS already does this, and that hasn't solved the problem. The issue is that the system-provided webview (well, on iOS, one of the two of them) allows the native app full control over it.
And on Android, that would mean Firefox couldn't use Gecko. Screw that.
I really like the simplicity of this proposal, and how Adrian compares it to X-Frame-Options: DENY which has been in place for a decade now and has solved the problem of clickjacking and unauthorized framing for regular websites.
My hunch is that having X-Frame-Options: DENY start applying to native mobile apps wouldn't be feasible because it would break too much existing stuff that didn't intend to opt-out of native embedding, but having different syntax (X-Frame-App-Options: DENY for example) would solve this need very effectively.
It's interesting to note that Google have already taken steps in this direction: Google sign-in now detects if it is running in an in-app embedded browser and shows you an error telling you to use the native browser instead: https://developers.googleblog.com/2021/06/upcoming-security-...
If a native app has as much control over the webpage as it seems to, I'd be surprised if it's not able to strip the header. Or point through a proxy that strips it, and ignore the ensuing HTTPS errors, or some other workaround.
Yea - in-app browsers are just more code... so Google could modify webkit mobile distros to adhere to this behavior but if Facebook was willing to compile their own library (which, honestly, they probably do already anyways) they would need to voluntarily comply with respecting such headers... right now I think this is do-able, app store controllers have a firm enough grasp on the market they could boot any apps that refuse to play nice - but it will require enforcement efforts.
Another option is to force these browser plugins to be shared objects that the app store has more control over but then you'll wander into the territory of how to enforce it on every fork of firefox and the like.
Editing to add: Oh legacy apps are a huge can of worms here - most businesses don't bother updating out of date app versions so folks with older phones will probably be stuck with perpetually insecure apps. But legacy apps and the "tight" control Google & Apple have are sort of perpetual issues to any sort of security.
Apple actually has really tight quality control over the applications found on the app store. If your app is found to have a vulnerability, it goes away immediately. That is why you don't have apps with malware or apps rooting the device or apps replacing the launcher via an exploit.
This is not a custom header (i.e. one with no UA semantics), it is a standardized header called X-Frame-Options which requires the “X-“ for browsers to recognize it. The prefix is an artifact of the era the header was introduced in.
When I used to work in mobile advertising, advertisers and tech vendors were always so desperate for this, because it would let them track users across apps and not just websites, so I’m not super sold on enabling it by default.
> Seem familiar? This is framing, merely in app form. But this time, the framed website has no way to framebust.
Click the safari button. It opens it in your normal browser. Better behaved apps (shout out to Apollo) will let you set a config that sends off links to safari directly.
The only apps I know of that don’t have this button are Facebook messenger and TikTok, to nobodies surprise, 2 reasonably badly behaved apps. I think Instagram still does as well, but that’s not a surprise.
You can still escape the app context via the sharing menu though, although that is somewhat more involved.
> Click the safari button. It opens it in your normal browser.
This is a solution to a different problem. The problem is the website can't prevent itself from being loaded in these frames like it can for <iframe>.
I think there's a good chance Google will actually end up implementing this because they've already had a push to not allow Google login screen in webviews.
In app browsers are a real problem for online stores and e-commerce, the issue being they (mostly) don’t maintain session cookies when a user clicks the “open in Safari/browser” button. This is disastrous for shopping carts.
Say your are an advertiser with an ad click or have a visitor come organically from social. They like your products and place them in their cart and go to checkout, at checkout they want to use Apple Pay or their saved card details. These aren’t available in most IABs, so they click the “open in browser” button, but now they have lost their cookie and have an empty cart! This causes a massive drop out rate at checkout.
I run a store that sells personalised items, it takes time for a customer to prepare their item before going to checkout. We experienced something like a 30% drop out rate from Facebook ads due to this.
The “work around” was to detect users in an IAB and display a message on first navigation attempt to prompt them to click the “open in browser” button early.
The fact that Facebook let this happen shows that have very little interest I’m making the advertising experience better for advertisers. They just want to keep users in Facebook.
Author of the krausefx.com post here: I don't believe there is a universal way of detecting this, however in the case of Instagram, the user agent string actually includes the "Instagram" string. For practical cases it's probably enough to collect user agents of the most used apps and check for those.
However, I believe all of this won't matter for too long after the press the last few days.
As someone pointed out already, Twitter does a good job with this. Reddit does a fine enough job, too.
However, tiktok doesn't allow users to break out of their in-app browser. This is especially frustrating when you wish to follow an artist on Spotify WITHOUT signing into Spotify in the tiktok app.
The tiktok thing is so annoying. It's not even possible to get the URL of the page you're viewing so you can open it in another app, and you can't long press any links to copy them either (neither in the in-app browser or in a user's bio). It makes it so frustrating when someone has social media links in their bio, because there's literally no way to open them in a different app short of manually typing out the URL. I understand why they do it (data collection/tracking), but it's a horrible user experience.
Yeah, and that frustrates the hell out of me, too, because I don't have Instagram and it varies (based on Zuck's mood, I guess) whether they will even allow me to view someone's profile without an account.
I see almost no reason to use mobile apps for Facebook, Instagram or Twitter today. Just use mobile web browser instead. The only thing is a dark mode for Facebook, but I believe it is achievable via DarkReader plugin for Firefox. Also, ad blockers are more or less working in browser, although Facebook is actively counteracts.
I wonder, by the way, why Reddit's "install app or continue with browser" popup isn't blocked by uBlock Origin. It is clearly an ad, and very malicious indeed.
Apple could solve this problem in Webkit. But Android is more complicated. On Android, third-party browser engines are allowed. Google cannot prevent an app from shipping its own browser engine for in-app browsing experience.
Apple is incentivized not to solve this because presently app creators can hijack these links to open in their own native code app, provided:
1. they have paid to join the apple developer program
2. they have validated ownership of their URL's domain with apple
3. they have submitted to all of the censorship requirements of the apple App Store (failure to do this one is what destroyed Tumblr and the Hong Kong anti-police protester app, you may recall)
4. they pay apple a cut of their sales
5. they buy mac workstations for all of their iOS mobile developers, to run xcode
Apple actually has a vested interest in apps supplanting the web, and has little incentive to improve web security features because Apple would prefer that new businesses simply use native iOS apps for everything (which sells more iPhones and locks both development investment as well as user eyeballs to their hardware).
The other-people's-apps-opening-your-site-in-their-custom-webview-and-adulterating-it problem doesn't go away if you onboard with Apple, build an app & register your domain for Universal Links. The custom webview is quite capable of blocking ULs.
The app would have to get much larger if they have to bundle most of a browser with it to avoid using the browser components on the phone. But sure, they could do that.
But to be in the app store an app has to comply with the rules. Google could decide to require compliance with that header. It's no loss to them, because the consequence would be that almost all Android users would use Chrome, and the tracking in the browser would still be controlled by Google.
I feel like I am in the extreme minority in that I pretty much never use an app for anything that already has a website. I just use the website on my phone.
The experience might be slightly worse, but I much prefer just staying in the browser on my phone for everything. Reddit, Twitter, the few times I log into Facebook, are all just using a browser. I just find it simpler, and I like when the interface is the same on my phone and desktop (which is why I use old Reddit)
I'm right there with you. I wonder why I even have a smartphone since I'm so app-averse, other than requiring the computing power to run any modern bloated website. I've had arguments with PMs instisting that, for example, a shopper in a supermarket is not going to download an app but they will visit a website that can offer equivalent functionality.
I'm with you also. But it is getting harder and harder. I'm convinced that Facebook are actively downgrading their in-browser mobile experience for this reason. They want to force you to use their app. Reddit, at least, are more honest about it - but also very annoying.
Features that used to work just fine (tagging people, editing comments) are becoming worse.
Facebook in a mobile browser also actively lies to you about Messenger notifications. It displays an icon saying that you have messages, but redirects you to install the Messenger app instead of displaying them. There aren't actually any messages present, so the entire thing is just a scam to get access to your phone.
It has gotten so bad that I now wait to I'm on my laptop before I post to Facebook.
I did try the app again recently and it was bad in other ways (eg not using my phone's photo picker. As the photo I wanted was on a cloud service I couldn't select it from the app)
Reddit I started to look at on my phone, but then it tried to bully me into installing an app. I like bullies much less than I like forums, so I do not look at Reddit on my phone anymore.
Matter fixed!
This works very well, I use the Instagram PWA instead of the app. It is feature-complete content-wise, so you can view everything you can in the app.
But it is not feature-complete in the other ways, so it has no advertisements (at least for me) or the new algorithmic feed. Just the old version of the Instagram home feed that is chronological.
Highly recommend it if you can live with the decrease in "smoothness" compared to the app.
> clickjacking. That’s when, for example, a website frames your site, then hijacks user input such that users are fooled into thinking they’re interacting with your site while they’re actually providing data to the (evil) containing site. Imagine typing your bank credentials into (what you think is) your bank website, whereas it’s in fact an evil site logging everything you’ve typed
Nitpick but isn’t this backwards? e.g. a clickjacking attack tricks you into thinking you are interacting with a harmless site, when in actuality you are clicking “buy now” on amazon in an invisible logged-in iframe.
That is just straight-up phishing, showing a fake Amazon form on your website that is served from a different domain. I'm not sure what you would overlay there.
Obviously you can't overlay anything for people who visit amazon.com, because they are not talking to your server at all.
The example (Twitter) does not use a web view - it uses SFSafariViewController.
This is the system browser as a modal over an app, a compromise for apps being able to retain navigational control (by having the user return to twitter when they hit 'Done') while not having the privacy, security and usability drawbacks of a webview.
While I agree that SFSafariViewController (or CustomTab on Android) is a security improvement it doesn't completely solve the security issue: The app could still decide to draw something that looks like an SFSafariViewController/CustomTab but is, in reality, a WebView with a key logger injected via JavaScript.
Right, this sort of malicious app issue imitating system UI to capture passwords is only really solvable this point by non technical means - App Store rejections, criminal penalties, etc.
Capturing a password is not going to be solved by a frame-busting header because the malicious app can just present its own content instead of rendering the requested enterprise/bank/etc login page.
Well, and new authentication tech like Passkeys/WebAuthn - the platform won't let a web view authenticate for domains other than ones associated with the native app.
As others have already mentioned, one needs to distinguish between WebViews and "in-app native browsers" / browser overlays (SFSafariViewController on iOS, CustomTab on Android). While WebViews are bad for all the reasons mentioned in the article, overlays do serve a purpose:
- The app gets notified when the website gets closed.
- The app is hidden underneath the overlay while the website is open. That is, the overlay is tied to the app and the user can't get lost or switch back to the app before they haven't closed the website.
All these are important, e.g., for OAuth, 2FA and payment-related applications.
Overlays are also way less bad than WebViews in terms of:
- UX: The overlay uses the cookies and settings of the native browser, looks familiar, and uses an up-to-date browser engine.
- Security for the host app: The website runs in a separate process
- Security for the user: They can see the URL and be (relatively) certain that the host app doesn't have access to the website and their interaction with it (i.e. no key logging).
So while I'd support busting out of WebViews (especially when they're opening paypal.com), I'm not so sure about overlays.
This proposal seems predicated on a fundamental misunderstanding of the security model of non-web applications.
A WebView is fully under control of the application presenting it. Even if the built-in APIs were extended to respect X-Frame-Options, applications can simply:
- Proxy the network requests on behalf of the webview API, stripping the X-Frame-Options header.
- Modify the behavior of the webview (e.g. via private API or twiddling internal state) to not respect X-Frame-Options.
- Embed their own web view implementation that ignores X-Frame-Options.
Apple and Google cannot guarantee that their code will ever see the X-Frame-Options header, nor can they guarantee that an embedded webview will even be implemented using their platform code.
All of this can be reason to reject an app during submission review. Google and Apple could update their guidelines and start enforcing them.
I mean if I would Apple I would go even stricter. In Info.plist you declare list of domains which can be accessed with webview and reason why. Just like you declare reason why you should have access to photos or a camera. Everything other would straight open in browser.
Also there is a solution to make component which acts as a webview, but in fact is blackboxed main browser which app has no access to, just like PHPicker photos select in ios 15
> Apple and Google cannot guarantee that their code will ever see the X-Frame-Options header, nor can they guarantee that an embedded webview will even be implemented using their platform code.
Apple absolutely can. They already out severe restrictions on what apps are allowed to use for rendering web views. They also approve every app. They can enforce whatever rule they want.
The App Store review process is not sufficient to provide such a strong technical guarantee.
The solution is not to add what amounts to an advisory flag to your page headers, and in the process, mislead users into believing in-app webviews are safe.
This is an incorrect understanding of how web views are implemented.
For SFSafariViewController, all the API allows you to do is essentially to present a full screen view that loads a particular URL. You can also register for callbacks for when a user dismisses the view or clicks the action button. There are no APIs that allow you to inject JS or read website data out of the view. The actual browsing logic powering the view is implemented out of process and you cannot modify the network requests that the view makes. If all your app wants to do is to display an in-app browser view, this is definitely the recommended path for security reasons.
For WKWebView, again most of the browsing and networking logic is handled out of process. However, because the API is designed to allow you to do pretty much anything you'd want to do with a web view up to and including implementing an entire browser, you get more power over what the view does. So you can do things like inject JS into the view.
However, it would be possible for the platform vendor to restrict use of the web view such that only certain more powerful APIs can be used by browser-style apps, while other less sensitive APIs can be used by all apps. This is because pretty much all of the APIs involve an IPC from the embedding process (e.g. an app under third party control) to another process that actually powers the view under the control of the browser engine (usually the content/renderer process). The content process can check that the embedding process has the proper permissions for each operation.
There is already precedence for limiting the power of web views. See https://webkit.org/blog/10882/app-bound-domains/ for instance, which allows a responsible app owner to allow their embedded web view to only load requests from particular domains.
> This is an incorrect understanding of how web views are implemented.
No, it’s not. Nothing requires you to use SFSafariViewController.
As you yourself noted, WKWebView exists and grants the application effectively complete control over it.
UIWebView also still exists, and despite being deprecated, remains usable.
Finally, even if everything but SFSafariViewController were removed from the OS, nothing stops the application developer from embedding their own replacement webview implementation.
> However, it would be possible for the platform vendor to restrict use of the web view such that only certain more powerful APIs can be used by browser-style apps, while other less sensitive APIs can be used by all apps.
Such a restriction would be equivalent to the existing SFSafariViewController, but regardless, I must reiterate: absolutely nothing stops the application developer from embedding their own replacement implementation.
> This is because pretty much all of the APIs involve an IPC from the embedding process (e.g. an app under third party control) to another process that actually powers the view under the control of the browser engine (usually the content/renderer process).
Again, nothing stops the application developer from embedding a replacement for your hypothetical sandboxed webview API.
At the same time Apple and Google have lists of hard requirements for applications that can be extended to include these - especially if part of this change over is presenting unified shared objects for apps to use to launch browsers.
That’s true, but I still don’t believe there exists a technical solution to this problem; I think this should be solved via:
(1) App Store policy, including requiring apps to disclose that they can/do capture embedded web browsing activity as part of their privacy disclosures.
(2) Privacy regulation. This is a very intentional dark-pattern used to violate users’ expectation of privacy, and should be addressed.
(3) User education — users should never trust an app-presented web view.
(4) An HTTP header that websites can use to explicitly opt out of being rendered in embedded in-app browser, reinforced by App Store policy that requires apps to respect and not to work around that header
> This means: If you’re logged into a website in your phone’s browser, but you click a link to that site from a native app’s webview, your logged-in state will not be honored. You’ll need to log in all over again.
> At best, this is irritating. At worst, it gives people the false impression that the website is broken or logged them out.
No, at worst, it uses the original/authentic website as phishing bait, and convinces the user to type a login and password for site A (the framed site) into application B (which shouldn't have access to it).
The article starts with historical anecdote from 1996, and talks about later frame-busting JS. At the time, you could also bust out of frames before JS was widely supported, simply by setting your HTML `A` element `target` attributes to `_top`.
If you were already generating your HTML back then, including having a function to generate a link, this was possibly a one-line change.
If you did this HTML-only frame-busting, you'd still appear within whatever questionable frames setup some other side had going, but as soon as someone tried to follow a link-- bam, now the site you host has either taken over the window, or are in an all-new window.
Frames initially seemed like a godsend, for arguably useful purposes, like keeping a floating table-of-contents sidebar on a large document (before CSS). My once employer, Electronic Book Technologies (EBT), makers DynaText that TBL considered, jumped on frames for this purpose, and were able to convert DynaWeb to leverage frames "overnight" from the same SGML source.
But frames did have some downsides even within a site, even if you didn't mess up the HTML (e.g., bookmarking of individual pages wasn't as usable/possible, and you could also somehow land on a page intended to be in a frameset but outside the frameset navigation UI context).
Besides the TotalNews example the article mentions, there were a lot of sites putting other sites inside frames, maybe as often due to misunderstanding or not realizing, rather than aggressively trying to freeload.
(At the same time as TotalNews, I'd built a fuzzy Web scraper in Java, and a prototype "personalized newspaper" that used it to get news articles and weather from other sides. I didn't know what to do about ads, which were brand new and image banners, so I just captured them while I was scraping, and re-presented them in the UI, at the bottom of the page whenever presenting data from the pages they were on. Such were the clumsy days of young Web innocence. :)
i've made a frameset site recently. With modern stuff you can have a single document display different content (or a frameset) depending on the name of the frame and push state a more representative url. This also solves the history navigation.
loading videos and pdf files into frames is also nice.
There have been a couple of these posts recently and they all contain the same flaw.
They talk about their experience on an iPhone and assume it's true on all ecosystems.
It's not true for mine (Firefox and Android). When following a link from Gmail it opens embedded within the Gmail app and the site has access to the same cookies as if I'd opened it in the browser.
And it's trivial and seamless to then open into full Firefox (position in page and form values are kept).
I think Chrome Android is more or less the same too.
Gmail may do that, but Android still offers developers "a webview that is basically a detached Chrome tab" and "a webview that you control and add your own chrome around".
Instagram offers me a UI that looks quite different to Gmail, so I suspect it's still using the latter.
Really, the proposal is to prevent people from implementing alternative web browsers? How about this:
- Want to control the experience? Implement your own app
- Want to be easily accessible to users without them having to install your app? Then accept them using any browser, including one embedded into Twitter
- Want to only support specific web browser? You can try to detect them using various tricks or convince them to support DRM. But, accept that many users will be driven away.
Exactly, if there are apps that are collecting data they they should not or being otherwise malicious then we should go after those apps - preferably via the law but the app store gatekeepers can also act. This is not something we need to throw out the entire concept of alternate user agents over.
> Proponents of native apps would also likely say: “If you had your own native app, this problem would be solved, because you can register a link handler that will automatically open all soundslice.com URLs in your native app.”
I believe the embedded-style webviews bypass this link-handling anyway.
There are a couple of problems with this proposal. First of all, it would prevent you from using webviews to implement any kind of browser. Which in the case of iOS means it would impossible to make an alternative browser to safari, because you aren't allowed to use an alternative browser engine.
Secondly, a lot of native apps rely on using websites controlled by the same entity that have x-frame-options set, and those would break if that suddenly caused it not to open.
Can you somehow detect that you're in a webview and instruct users to press the "open in browser" button? Perhaps via the user agent, or some other way?
A few years ago I worked on a web-based augmented reality app intended to be shared by users through services that often displayed links in webviews. Newer SFSafariViewController worked fine but WKWebView failed silently in a way that was impossible to detect. There was no way to determine if you were in a WKWebView except: adding a hidden DOM node somewhere in the format “(123) 456-7890”, real safari would automatically turn it into a detectable phone number link, whereas WKWebView would not. With that ugly hack, we’d have to display a message asking the user to open in safari and hope the app had deigned to put a safari button somewhere.
> There was no way to determine if you were in a WKWebView except: adding a hidden DOM node somewhere in the format “(123) 456-7890”, real safari would automatically turn it into a detectable phone number link
What about non-US users? And doesn't Android's browser do the same thing?
Also, what happens if the page has `<a target="_blank">` or `window.open`? Does it always open in the same frame/window/target?
Last time I dug around into this, there was a delegate that's called that allows the app to open a new window/tab as makes sense for the app and display the link. I've seen applications that respond to this delegate by just forcing the existing WebView to open the link. If you don't implement the delegate, as I recall, nothing happens with these sort of links, they just appear dead to the user.
I think the proposal of piggybacking on X-Frame-Options as expressed is just a smidgeon too coarse, and it needs a little more nuance.
My suggestion would be that web views that aren’t deliberately being an actual browser be classified as possessing some origin, preferably checked where possible by the OS to match an origin or custom scheme that’s associated with the app (thus generally tying into Android’s app links and iOS’s universal links). Of course, this is still technically fallible since browsers need to be able to disable it, so it’d become another thing for the app store reviewers to check.
Then, you apply your Content-Security-Policy’s frame-ancestors directive (the successor to X-Frame-Options, allowing more nuance than simple DENY/SAMEORIGIN: e.g. `Content-Security-Policy: frame-ancestors 'self' instagram:` would be same-origin or the Instagram app), and treat deny as “open in an external browser”, as proposed.
> Popular apps such as Instagram and Facebook don’t just use vanilla webviews. They use customized ones, with their own quirks.
This might be understandable, but also feels a bit odd. Why couldn't they just use what the system already providers, without bloating everything with their own implementation?
Then again, one could probably ask the same about desktop software that is commonly based on Electron, but in theory might as well be run through Firefox with some additional capabilities that locally running Electron apps would otherwise get. Then again, we kind of had PWAs on the desktop, which have been retired now as well: https://9to5google.com/2021/01/27/firefox-discontinues-work-...
Mobile app webviews (like those used by e.g. instagram, twitter) are in many ways a modern re-incarnation of the old exploitative frame embedding problem; but in this case, apps use webviews to track user behavior + keep them in their app.
To deal with the frame issue X-Frame-Options: DENY was developed so websites could opt out, but there is currently no recourse for users or website owners in the webview case.
The problem could be solved on the mobile OS level by having it interpret the presence of X-Frame-Options: DENY as disallowing webviews for particular sites, and instead open the OS default browser.
Conclusion:
> Our best bet is regulatory intervention, along the lines of what Open Web Advocacy is doing. In collecting my thoughts here, I hope to start this conversation. The modern version of TotalNews must be reined in.
Edit: forgot there was a frame separate from iframe
I like the general idea a lot: let sites say whether they're willing to be displayed this way. But two main disagreements:
* We can't reuse X-Frame-Options for this, because sites are already setting that without necessarily wanting to opt out of in-app browsers.
* I do think Apple and Google might be persuaded to require all IABs to respect this "I want my site to open in the user's default browser" directive, as an app store approval requirement. For example, their account security teams would likely be strongly in favor.
I do think Android's Custom Tabs and iOS' SFSafariViewController should still be allowed, however, since the embedding app can't exfiltrate site data, inject JS, etc.
I think non-platform browsers also use the same engine and webview, so if the platform implements "honor X-Frame-Options", won't it essentially lock out third party browsers? Like I won't be able to use Firefox Focus.
Maybe the app review process can catch this behaviour instead? ... That way, it can be permitted for browsers but not for apps with embed a webview? That might work for iOS where reviews are strict, but no idea whether it would on Android.
Yes, I think actual browsers should be allowed to do nothing when seeing it. Strongly against anything that would make it harder to use Firefox.
My understanding is that both app stores already have a concept of "this is a web browser" vs "this is an app that includes an in-app browser" and so this is pretty practical?
> There was indeed a time when this argument made sense: the years before 2015, which is when iOS 9 introduced a global Back button conveniently solving the problem. And of course Android has its global Back button. These days this argument holds no water.
Oh of course it does hold water. On Samsung's pretty recent Active Tab 3, opening a link in an app (e.g. RIF) in Chrome takes ages (I recently timed it, 80 seconds) because Chrome for whatever goddamn reason thinks it has to reload all the icons for the 100+ tabs I have open every time Android's completely bonkers memory manager decides it wants to suspend Chrome in background.
It’s always a terrible experience too. I’m never logged in, my password management app doesn’t work, and if I do want to login it’s a new browser so it trips all the security.
Related to the quirks of in-app browsers mentioned in the article, the Facebook, Instagram and Snapchat apps manage to break file uploading every few months, and take several weeks to fix it each time. I'm not sure why this in particular is such an achilles heel, but it's a surprisingly big problem for e.g. online stores advertizing on Instagram and offering personalized products.
You will never prevent people from downloading your html and rendering it, correctly or incorrectly. Attackers will just pull in an open source browser engine that supports mobile. Our smartphones were not made with security in mind. They are literal spyware.
I suspect the more likely use of OS-based frame busting is to circumvent ad blocking browsers. This is even the use case he mentions as an example.
Some apps lack this setting, whereas many do. Funny thing is that the Gmail programme on the iPhone offers this prompt, but it never saves my preference. I'd be amazed if a native app couldn't strip the header if it had as much control over the webpage as it appears to have. Alternately, you might use a proxy that removes it and ignore the resulting HTTPS problems.
I also have always the problem, that "in app browsers" don't recognize the native Apps I have installed and so links to youtube or Instagram e.g. do not open the native app but the browser version instead. Copy pasting links is my everyday browsing experience on twitter and linkedIn e.g.
Correct. In addition to the proposed solution, there should be a global setting on the phone that lets users decide that all web links in apps should open in browser; ask every time; or open in app every time. In addition, a per app setting that overrides the global setting should be available too.
Didn't the new EU regulation intend to forbid forcing users to use a specific browser? Embedding your preferred browser into some other app doesn't seem like an acceptable work around?
This! I most notably always fight google news: preventing it from dropping out of real-chrome into worst-chrome by opening in new tab has become finger memory...
iOS aside, I'm not sure there's anything to be done here. Apps could simply embed their own browser engine that lets them use webviews in whatever unfettered way they want. And on iOS, it's not unlikely that Apple will be required to open their walled garden to other browser engines in the future.
> Apps could simply embed their own browser engine that lets them use webviews in whatever unfettered way they want.
The biggest pro for consumers in having an app store is that the store can set regulations on apps. If Google says apps can't do this, then it's effectively dead. Of course, that would rely on Google effectively policing it.
Don't use web inside of an app, desktop or mobile for anything other than pure content. Use native for UI. Electron is doing it wrong and {NS,UI}WebView are abused too often to provide an entire app using a website.
On iOS this means you can't get notifications. Notifications are really important.
Apple won't do web notifications because it means then people wouldn't have to pay their 10x-over-the-industry-standard premium (30% instead of 3%) for bundled credit card processing if they buy stuff on the web and not via the App Store.
This seems to have changed. Web push is coming to mobile Safari next year. https://webkit.org/blog/12945/meet-web-push/ (Edit: better link - „Keep an eye out for Web Push on iOS and iPadOS in 2023.“)
I prefer not to use app if the same service is available through website. And those services that are not available through websites, they rarely involve any hyperlink to a third party. This may change in future if many essential services ditch their websites and switch exclusively to app. That's one of my nightmares.
Apps that implement a custom web browser using WKWebView (e.g. IG) are much worse and can do those nefarious things.