Browse Source

Merge pull request #9301 from electron/post-message-origin-check

Use isSameOrigin helper when checking postMessage targetOrigin
Kevin Sawicki 8 years ago
parent
commit
f84c75aa1a

+ 1 - 1
lib/browser/guest-window-manager.js

@@ -309,7 +309,7 @@ ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', function (event,
   // The W3C does not seem to have word on how postMessage should work when the
   // origins do not match, so we do not do |canAccessWindow| check here since
   // postMessage across origins is useful and not harmful.
-  if (guestContents.getURL().indexOf(targetOrigin) === 0 || targetOrigin === '*') {
+  if (targetOrigin === '*' || isSameOrigin(guestContents.getURL(), targetOrigin)) {
     const sourceId = event.sender.id
     guestContents.send('ELECTRON_GUEST_WINDOW_POSTMESSAGE', sourceId, message, sourceOrigin)
   }

+ 34 - 0
spec/chromium-spec.js

@@ -1,4 +1,5 @@
 const assert = require('assert')
+const fs = require('fs')
 const http = require('http')
 const path = require('path')
 const ws = require('ws')
@@ -618,6 +619,39 @@ describe('chromium feature', function () {
       })
       document.body.appendChild(webview)
     })
+
+    describe('targetOrigin argument', function () {
+      let serverURL
+      let server
+
+      beforeEach(function (done) {
+        server = http.createServer(function (req, res) {
+          res.writeHead(200)
+          const filePath = path.join(fixtures, 'pages', 'window-opener-targetOrigin.html')
+          res.end(fs.readFileSync(filePath, 'utf8'))
+        })
+        server.listen(0, '127.0.0.1', function () {
+          serverURL = `http://127.0.0.1:${server.address().port}`
+          done()
+        })
+      })
+
+      afterEach(function () {
+        server.close()
+      })
+
+      it('delivers messages that match the origin', function (done) {
+        let b
+        listener = function (event) {
+          window.removeEventListener('message', listener)
+          b.close()
+          assert.equal(event.data, 'deliver')
+          done()
+        }
+        window.addEventListener('message', listener)
+        b = window.open(serverURL, '', 'show=no')
+      })
+    })
   })
 
   describe('creating a Uint8Array under browser side', function () {

+ 24 - 0
spec/fixtures/pages/window-opener-targetOrigin.html

@@ -0,0 +1,24 @@
+<html>
+<body>
+<script type="text/javascript" charset="utf-8">
+  const url = require('url')
+  if (url.parse(window.location.href, true).query.opened != null) {
+    // Ensure origins are properly checked by removing a single character from the end
+    window.opener.postMessage('do not deliver substring origin', window.location.origin.substring(0, window.location.origin.length - 1))
+    window.opener.postMessage('do not deliver file://', 'file://')
+    window.opener.postMessage('do not deliver http without port', 'http://127.0.0.1')
+    window.opener.postMessage('do not deliver atom', 'atom://')
+    window.opener.postMessage('do not deliver null', 'null')
+    window.opener.postMessage('do not deliver \\:/', '\\:/')
+    window.opener.postMessage('do not deliver empty', '')
+    window.opener.postMessage('deliver', window.location.origin)
+  } else {
+    const opened = window.open(`${window.location.href}?opened=true`, '', 'show=no')
+    window.addEventListener('message', function (event) {
+      window.opener.postMessage(event.data, '*')
+      opened.close()
+    })
+  }
+</script>
+</body>
+</html>