Skip to content

Commit

Permalink
fix(react-dom): check if iframe belongs to the same origin
Browse files Browse the repository at this point in the history
Accessing the contentDocument of a HTMLIframeElement can cause the browser
to throw, e.g. if it has a cross-origin src attribute.
Safari will throw an uncatchable error when the access results in "Blocked a frame with origin". e.g:

```javascript
try {
 $0.contentDocument.defaultView
} catch (err) {
  console.log('err', err)
}

> Blocked a frame with origin X from accessing a frame with origin Y. Protocols, domains, and ports must match.
> err – TypeError: null is not an object (evaluating '$0.contentDocument.defaultView')
```

A safety way is to access one of the cross origin properties: Window or Location
Which might result in "SecurityError" DOM Exception and it is compatible to Safari.

```javascript
try {
 $0.contentWindow.location.href
} catch (err) {
 console.log('err', err)
}

> err – SecurityError: Blocked a frame with origin "http://localhost:3001" from accessing a cross-origin frame. Protocols, domains, and ports must match.
```

https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
  • Loading branch information
renanvalentin committed Mar 15, 2019
1 parent 2aabdf5 commit a77230a
Showing 1 changed file with 19 additions and 4 deletions.
23 changes: 19 additions & 4 deletions packages/react-dom/src/client/ReactInputSelection.js
Expand Up @@ -40,15 +40,30 @@ function isInDocument(node) {
);
}

function isSameOriginFrame(iframe) {
try {
// Accessing the contentDocument of a HTMLIframeElement can cause the browser
// to throw, e.g. if it has a cross-origin src attribute.
// Safari will throw an uncatchable error when the access results in "Blocked a frame with origin". e.g:
// iframe.contentDocument.defaultView;
// A safety way is to access one of the cross origin properties: Window or Location
// Which might result in "SecurityError" DOM Exception and it is compatible to Safari.
// https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl

const canReadHrefAttribute = iframe.contentWindow.location.href;
return canReadHrefAttribute != null;
} catch (err) {
return false;
}
}

function getActiveElementDeep() {
let win = window;
let element = getActiveElement();
while (element instanceof win.HTMLIFrameElement) {
// Accessing the contentWindow of a HTMLIframeElement can cause the browser
// to throw, e.g. if it has a cross-origin src attribute
try {
if (isSameOriginFrame(element)) {
win = element.contentWindow;
} catch (e) {
} else {
return element;
}
element = getActiveElement(win.document);
Expand Down

0 comments on commit a77230a

Please sign in to comment.