Out-of-Process iframes (OOPIFs)

For Developers‎ > ‎ Design Documents‎ > ‎

Out-of-Process iframes (OOPIFs)

This page provides an overview of Chromium's support for out-of-process iframes (OOPIFs), which allow a child frame of a page to be rendered by a different process than its parent frame. OOPIFs were motivated by security goals like the Site Isolation project, since they allow a renderer process to be dedicated to a single web site, even when cross-site iframes are present.  OOPIFs are a general mechanism, though, and can be used for other features than security (e.g., the <webview> tag in Chrome Apps).

 
Supporting OOPIFs required a large architecture change to Chromium.  At a high level, the browser process now tracks subframes directly, and core parts of the browser (e.g., painting, input events, navigation, etc) have been updated to support OOPIFs.  Many other features in Chromium now combine information from frames in multiple processes when operating on a page, such as Accessibility or Find-in-Page.

Current Uses

The first use of OOPIFs was  --isolate-extensions mode, which launched to Chrome Stable in M56.  This mode uses OOPIFs to keep web iframes out of privileged extension processes, which offers a second line of defense against malicious web iframes that might try to compromise an extension process to gain access to extension APIs.  This mode also moves extension iframes on web pages into extension processes.

Experimental Uses

We are currently running field trials to use OOPIFs rather than the plugin infrastructure to implement GuestViews (e.g., <webview> tags in Chrome Apps). This mode is primarily an architectural cleanup, and it should provide better feature support within GuestViews in the long term. This can be enabled as " Cross process frames for guests" in about:flags.
 
For performance experiments, the --top-document-isolation command line flag puts all cross-site iframes across all tabs into a single subframe process. The goal is to keep the main document in each tab responsive despite potentially slow iframes. Note that this is still an early prototype, and we are still investigating the tradeoff between the extra parallelism and memory overhead to determine if there are cases this is worthwhile. Note that OOPIFs cannot be used for same-site frames (which may synchronously script each other), and we have no current plans to use them for cross-thread frames in the same process. This mode can also be enabled as "Top document isolation" in about:flags.
 
Beyond this, the --site-per-process command line flag enables an experimental security mode that causes all renderer processes to be dedicated to a single site. This provides strong isolation for all web sites, but it tends to create many more renderer processes than Chromium's default process model. Before launching this mode, we are likely to limit it to only isolating a subset of high-value or high-risk sites. This mode can also be enabled as "Out of process iframes" in about:flags.
 
Please file any bugs observed in these modes using the component Internals>Sandbox>SiteIsolation.

Project Resources

Architecture Overview

Frame Representation

Much of the logic in the content module has moved from being tab-specific to frame-specific, since each frame may be rendered in different processes over its lifetime.
Proxies
 
Documents that have references to each other (e.g., from the frame tree, window.opener, or named windows) can interact via JavaScript.  When the documents are same-site, they must live in the same process to allow synchronous access.  When they are cross-site, they can live in different processes but need a way to route messages to each other, for calls like postMessage.  Same-site documents with references to each other are grouped together using the SiteInstance class, as described on the Process Models page.
 

To support cross-process interactions like postMessage on a document's DOMWindow, Chromium must keep a proxy for the DOMWindow in each of the other processes that can reach it.  As shown in the diagram at right, this allows a document from site A to find a proxy in its own process for a DOMWindow that is currently active on site B.  The proxy can then forward the postMessage call to the browser and then to the correct document in the process for site B.


OOPIFs require each renderer process to keep track of proxy DOMWindows for all reachable frames, both main frames and subframes.
Browser Process
Chromium keeps track of the full frame tree for each tab in the browser process.  WebContents hosts a tree of FrameTreeNode objects, mirroring the frame tree of the current page.  Each FrameTreeNode contains frame-specific information (e.g., the frame's name, origin, etc).  Its RenderFrameHostManager is responsible for cross-process navigations in the frame, and it supports replicating state and routing messages from proxies in other processes to the active frame.
Renderer Process

In each renderer process, Chromium tracks of proxy DOMWindows for each reachable frame, allowing JavaScript code to find frames and send messages to them.  We try to minimize the overhead for each of the proxy DOMWindows by not having a document, widget, or full V8 context for them.


Frame-specific logic in the content module's RenderView and RenderViewHost classes has moved into routable RenderFrame and RenderFrameHost classes.  We have one full RenderFrame (in some process) for every frame in a page, and we have a corresponding but slimmed down RenderFrameProxy as a placeholder in the other processes that can reference it.  These proxies are shown with dashed lines in the diagram below, which depicts one BrowsingInstance (i.e., group of related windows) with two tabs, containing two subframes each.
 



Inside Blink
 
 
 
Blink has LocalFrame and LocalDOMWindow classes for frames that are in-process, and it has RemoteFrame and RemoteDOMWindow classes for the proxies that live in other renderer processes.  The remote classes have very little state: generally only what is needed to service synchronous operations.  A RemoteDOMWindow does not have a Document object or a widget.
LocalFrame and RemoteFrame inherit from the Frame interface.  While downcasts from Frame to LocalFrame are possible, this will likely cause bugs with OOPIFs unless extra care is taken.  LocalFrame corresponds to WebLocalFrame (in the public API) and content::RenderFrame, while RemoteFrame corresponds to WebRemoteFrame and content::RenderFrameProxy.
 

Blink has the ability to swap any frame between the local and remote versions.  (This replaces the old "swapped out RenderViewHost" implementation that Chromium used for cross-process navigations.)


It is worth noting that the <webview> implementation is being migrated to work on top of the new OOPIF infrastructure. For the most part, Blink code will be able to treat a <webview> similar to an <iframe>.  However, there is one important difference: the parent frame of an <iframe> is the document that contains the <iframe> element, while the root frame of a <webview> has no parent and is itself a main frame.  It will likely live in a separate frame tree.

 
This support for OOPIFs and <webview> has several major implications for Blink:
  • Page's main frame may be local or remote. There are a number of places that assume that main frame will always be local (e.g., the current drag and drop implementation always uses the main frame's event handler to perform hit-testing). These places will need to change.
  • More generally, any given frame in the frame tree may be remote. Thus, we are rewriting code like the web page serializer, which depended on iterating through all the frames in one process to generate the saved web page.
  • Layout and rendering were formerly coordinated by the main frame. This (and other code like this) needs to change to use a new concept: the local frame root. The local frame root for a given LocalFrame A is the highest LocalFrame that is a part of a contiguous LocalFrame subtree that includes frame A. In code form:
        LocalFrame* localRootFor(LocalFrame* frame) {
            LocalFrame* local_root = frame;
            while (local_root && local_root->parent()->isLocalFrame())
                local_root = toLocalFrame(local_root->parent());
            return local_root;
        }
    These contiguous LocalFrame subtrees are important in Blink because they synchronously handle layout, painting, event routing, etc.
Some earlier information on the refactoring goals can be found in the  FrameHandle design doc, however that is largely obsolete.
 
Note: We are attempting to minimize the memory requirements of RemoteFrames and RemoteDOMWindows, because there will be many more than in Chromium before OOPIFs.  Before, the space required for swapped out RenderViewHosts was O(tabs * processes) within a BrowsingInstance, and most BrowsingInstances only contain 1 or 2 tabs.  OOPIFs will require O(frames * processes) space for proxies.  This could be much higher, because the number of frames can be much larger than the number of tabs, and because the number of processes will increase based on cross-site frames.  Fortunately, RemoteFrames require far less memory than LocalFrames, and not all cross-site iframes will require separate processes.
 

Navigation

Chromium now has support for cross-process navigations within subframes when using the --isolate-extensions or --site-per-process flags. Rather than letting the renderer process intercept the navigation and decide if the browser process should handle it, all navigations will be intercepted in the browser process's network stack. If the navigation crosses a site boundary that requires isolation (according to our Site Isolation policy), the browser process will swap the frame's renderer process. This can be done because the browser process knows the full frame tree, as described above. Until PlzNavigate launches, this is implemented using CrossSiteResourceHandler to transfer navigations to a different process when needed.


A tab's session history also becomes more complicated when subframes may be rendered by different processes. Currently, Blink takes care of tracking the frame tree in each HistoryItem in the renderer process, and the browser process just tracks each back/forward entry using NavigationEntry. We are removing the frame tracking logic from Blink's HistoryController to keep track of each frame's navigations in the browser process directly.


We will also change the representation of a tab's session history to more closely match the HTML5 spec. Rather than cloning the frame tree for each HistoryItem, we will keep track of each frame's session history separately in the browser process, and we will use a separate "joint session history" list for back and forward navigations. Each entry in this list will have a tree of pointers to each frame's corresponding session history item. We expect this to require changes to the session restore logic as well.


All details of navigation refactoring are described in this design document.

Rendering

To render an iframe in a different process than its parent frame, the browser process passes information back and forth between the renderer processes and helps the GPU process composite the images together in the correct sizes and locations.  We use the Surfaces implementation to maintain a set of textures from multiple renderer processes, compositing them into a single output image.  More details are available in this   design document.

Input Events

Similar to rendering, we use the Surfaces implementation to do hit testing in the browser process to deliver input events directly to the intended frame's renderer process.  We are also starting to manage focus in the browser process to send keyboard events directly to the renderer process of the focused frame.  More details are available in this design document.

转载于:https://www.cnblogs.com/huangguanyuan/p/9917627.html

Nginx 的 X-Options 是通过 HTTP 请求头来控制网页是否允许被嵌入到 iFrames 中的一个安全策略。这个请求头可以帮助防止点击劫持(Clickjacking)攻击和其他类型的中间人攻击。Nginx 支持 X-Frame-Options 参数主要有四个,它们分别是: 1. **DENY**: 这是最严格的选项,告诉浏览器不允许任何框架加载包含该页面的内容。这意味着页面将完全禁止被嵌入到其他网站的 iFrames 中。 2. **SAMEORIGIN**: 这种模式允许当前域下的页面可以在相同的来源(通常是同一顶级域名下)中被嵌入到 iFrames 中。这意味着在同一域内,你可以将一个页面嵌入到另一个页面的 iFrames 中,而外部来源则不允许这样做。 3. **ALLOW-FROM url**: 这是一种更灵活的选项,允许从指定 URL 加载页面内容。这对于需要跨源嵌入内容的情况非常有用,但需要注意的是,如果恶意站点可以访问并修改这个 URL,那么仍然存在一定的风险。 4. **NOTSET**(默认值): 如果没有设置 X-Frame-Options,浏览器将按照其默认策略行事。对于现代浏览器,默认策略往往比较宽松,因此推荐明确设定此参数以增强安全性。 要启用或改变 X-Frame-Options 设置,在 Nginx 的配置文件中,通常会放在 `http` 或 `server` 区段中,使用如下语法: ```nginx # 在 http 段落中全局设置 add_header X-Frame-Options "DENY"; # 或者在 server 块中针对特定服务器设置 server { # ... 其他设置 ... add_header X-Frame-Options "SAMEORIGIN"; # ... 其他设置 ... } ``` 每个网站的安全需求各不相同,因此需要根据实际情况选择合适的参数。在考虑这些设置时,重要的是理解每种参数所带来的安全性和用户体验之间的权衡。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值