Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: disable creation of window.ipfs attribute in Firefox #495

Merged
merged 4 commits into from
Jun 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions add-on/manifest.firefox.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"default_title": "__MSG_pageAction_titleNonIpfs__",
"default_popup": "dist/popup/page-action/index.html"
},
"content_scripts": [ ],
"protocol_handlers": [
{
"protocol": "web+dweb",
Expand Down
30 changes: 25 additions & 5 deletions add-on/src/contentScripts/ipfs-proxy/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@ const injectScript = require('./inject-script')

function init () {
const port = browser.runtime.connect({ name: 'ipfs-proxy' })

// Forward on messages from background to the page and vice versa
port.onMessage.addListener((data) => {
if (data && data.sender && data.sender.startsWith('postmsg-rpc/')) {
window.postMessage(data, '*')
}
})

window.addEventListener('message', (msg) => {
if (msg.data && msg.data.sender && msg.data.sender.startsWith('postmsg-rpc/')) {
port.postMessage(msg.data)
Expand All @@ -24,8 +22,30 @@ function init () {
injectScript(rawCode)
}

// Restricting window.ipfs to Secure Context
// See: https://github.com/ipfs-shipyard/ipfs-companion/issues/476
if (window.isSecureContext) {
function injectIpfsProxy () {
// Skip if proxy is already present
if (window.ipfs) {
return false
}
// Restricting window.ipfs to Secure Context
// See: https://github.com/ipfs-shipyard/ipfs-companion/issues/476
if (!window.isSecureContext) {
return false
}
// Skip if not in HTML context
// Check 1/2
const doctype = window.document.doctype
if (doctype && doctype.name !== 'html') {
return false
}
// Check 2/2
if (document.documentElement.nodeName !== 'HTML') {
return false
}
// Should be ok by now
return true
}

if (injectIpfsProxy()) {
init()
}
38 changes: 37 additions & 1 deletion add-on/src/lib/ipfs-companion.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ module.exports = async function init () {
var contextMenus
var apiStatusUpdateInterval
var ipfsProxy
var ipfsProxyContentScript
const idleInSecs = 5 * 60
const browserActionPortName = 'browser-action-port'

Expand Down Expand Up @@ -60,6 +61,7 @@ module.exports = async function init () {
})
modifyRequest = createRequestModifier(getState, dnsLink, ipfsPathValidator, runtime)
ipfsProxy = createIpfsProxy(() => ipfs, getState)
ipfsProxyContentScript = await registerIpfsProxyContentScript()
registerListeners()
await setApiStatusUpdateInterval(options.ipfsApiPollMs)
await storeMissingOptions(
Expand Down Expand Up @@ -95,6 +97,33 @@ module.exports = async function init () {
}
}

// Register Content Script responsible for loading window.ipfs (ipfsProxy)
//
// The key difference between tabs.executeScript and contentScripts API
// is the latter provides guarantee to execute before anything else.
// https://github.com/ipfs-shipyard/ipfs-companion/issues/451#issuecomment-382669093
async function registerIpfsProxyContentScript (previousHandle) {
previousHandle = previousHandle || ipfsProxyContentScript
if (previousHandle) {
previousHandle.unregister()
}
if (!state.ipfsProxy || !browser.contentScripts) {
// no-op if window.ipfs is disabled in Preferences
// or if runtime has no contentScript API
// (Chrome loads content script via manifest)
return
}
const newHandle = await browser.contentScripts.register({
matches: ['<all_urls>'],
js: [
{file: '/dist/bundles/ipfsProxyContentScript.bundle.js'}
],
allFrames: true,
runAt: 'document_start'
})
return newHandle
}

// HTTP Request Hooks
// ===================================================================

Expand Down Expand Up @@ -544,13 +573,16 @@ module.exports = async function init () {
case 'useCustomGateway':
state.redirect = change.newValue
break
case 'ipfsProxy':
state[key] = change.newValue
ipfsProxyContentScript = await registerIpfsProxyContentScript()
break
case 'linkify':
case 'catchUnhandledProtocols':
case 'displayNotifications':
case 'automaticMode':
case 'dnslink':
case 'preloadAtPublicGateway':
case 'ipfsProxy':
state[key] = change.newValue
break
}
Expand Down Expand Up @@ -616,6 +648,10 @@ module.exports = async function init () {
contextMenus = null
ipfsProxy.destroy()
ipfsProxy = null
if (ipfsProxyContentScript) {
ipfsProxyContentScript.unregister()
ipfsProxyContentScript = null
}
await destroyIpfsClient()
}
}
Expand Down