mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 17:33:23 +01:00
parent
b29aa44a64
commit
9cf358a82a
@ -47,6 +47,7 @@
|
||||
],
|
||||
"default_locale": "en",
|
||||
"description": "__MSG_appDescription__",
|
||||
"host_permissions": ["file://*/*", "http://*/*", "https://*/*"],
|
||||
"icons": {
|
||||
"16": "images/icon-16.png",
|
||||
"19": "images/icon-19.png",
|
||||
@ -61,6 +62,7 @@
|
||||
"name": "__MSG_appName__",
|
||||
"permissions": [
|
||||
"storage",
|
||||
"scripting",
|
||||
"unlimitedStorage",
|
||||
"clipboardWrite",
|
||||
"http://localhost:8545/",
|
||||
|
@ -126,3 +126,18 @@ chrome.runtime.onMessage.addListener(() => {
|
||||
importAllScripts();
|
||||
return false;
|
||||
});
|
||||
|
||||
/*
|
||||
* This content script is injected programmatically because
|
||||
* MAIN world injection does not work properly via manifest
|
||||
* https://bugs.chromium.org/p/chromium/issues/detail?id=634381
|
||||
*/
|
||||
chrome.scripting.registerContentScripts([
|
||||
{
|
||||
id: 'inpage',
|
||||
matches: ['file://*/*', 'http://*/*', 'https://*/*'],
|
||||
js: ['inpage.js'],
|
||||
runAt: 'document_start',
|
||||
world: 'MAIN',
|
||||
},
|
||||
]);
|
||||
|
@ -6,6 +6,7 @@ import PortStream from 'extension-port-stream';
|
||||
import { obj as createThoughStream } from 'through2';
|
||||
|
||||
import { isManifestV3 } from '../../shared/modules/mv3.utils';
|
||||
import shouldInjectProvider from '../../shared/modules/provider-injection';
|
||||
|
||||
// These require calls need to use require to be statically recognized by browserify
|
||||
const fs = require('fs');
|
||||
@ -43,7 +44,9 @@ if (
|
||||
) {
|
||||
setupPhishingStream();
|
||||
} else if (shouldInjectProvider()) {
|
||||
injectScript(inpageBundle);
|
||||
if (!isManifestV3()) {
|
||||
injectScript(inpageBundle);
|
||||
}
|
||||
setupStreams();
|
||||
}
|
||||
|
||||
@ -57,12 +60,7 @@ function injectScript(content) {
|
||||
const container = document.head || document.documentElement;
|
||||
const scriptTag = document.createElement('script');
|
||||
scriptTag.setAttribute('async', 'false');
|
||||
// Inline scripts do not work in MV3 due to more strict security policy
|
||||
if (isManifestV3()) {
|
||||
scriptTag.setAttribute('src', browser.runtime.getURL('inpage.js'));
|
||||
} else {
|
||||
scriptTag.textContent = content;
|
||||
}
|
||||
scriptTag.textContent = content;
|
||||
container.insertBefore(scriptTag, container.children[0]);
|
||||
container.removeChild(scriptTag);
|
||||
} catch (error) {
|
||||
@ -264,100 +262,6 @@ function notifyInpageOfStreamFailure() {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the provider should be injected
|
||||
*
|
||||
* @returns {boolean} {@code true} Whether the provider should be injected
|
||||
*/
|
||||
function shouldInjectProvider() {
|
||||
return (
|
||||
doctypeCheck() &&
|
||||
suffixCheck() &&
|
||||
documentElementCheck() &&
|
||||
!blockedDomainCheck()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the doctype of the current document if it exists
|
||||
*
|
||||
* @returns {boolean} {@code true} if the doctype is html or if none exists
|
||||
*/
|
||||
function doctypeCheck() {
|
||||
const { doctype } = window.document;
|
||||
if (doctype) {
|
||||
return doctype.name === 'html';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the extension (suffix) of the current document is prohibited
|
||||
*
|
||||
* This checks {@code window.location.pathname} against a set of file extensions
|
||||
* that we should not inject the provider into. This check is indifferent of
|
||||
* query parameters in the location.
|
||||
*
|
||||
* @returns {boolean} whether or not the extension of the current document is prohibited
|
||||
*/
|
||||
function suffixCheck() {
|
||||
const prohibitedTypes = [/\.xml$/u, /\.pdf$/u];
|
||||
const currentUrl = window.location.pathname;
|
||||
for (let i = 0; i < prohibitedTypes.length; i++) {
|
||||
if (prohibitedTypes[i].test(currentUrl)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the documentElement of the current document
|
||||
*
|
||||
* @returns {boolean} {@code true} if the documentElement is an html node or if none exists
|
||||
*/
|
||||
function documentElementCheck() {
|
||||
const documentElement = document.documentElement.nodeName;
|
||||
if (documentElement) {
|
||||
return documentElement.toLowerCase() === 'html';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current domain is blocked
|
||||
*
|
||||
* @returns {boolean} {@code true} if the current domain is blocked
|
||||
*/
|
||||
function blockedDomainCheck() {
|
||||
const blockedDomains = [
|
||||
'adyen.com',
|
||||
'ani.gamer.com.tw',
|
||||
'blueskybooking.com',
|
||||
'cdn.shopify.com/s/javascripts/tricorder/xtld-read-only-frame.html',
|
||||
'docs.google.com',
|
||||
'dropbox.com',
|
||||
'gravityforms.com',
|
||||
'harbourair.com',
|
||||
'sharefile.com',
|
||||
'uscourts.gov',
|
||||
'webbyawards.com',
|
||||
];
|
||||
const currentUrl = window.location.href;
|
||||
let currentRegex;
|
||||
for (let i = 0; i < blockedDomains.length; i++) {
|
||||
const blockedDomain = blockedDomains[i].replace('.', '\\.');
|
||||
currentRegex = new RegExp(
|
||||
`(?:https?:\\/\\/)(?:(?!${blockedDomain}).)*$`,
|
||||
'u',
|
||||
);
|
||||
if (!currentRegex.test(currentUrl)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects the current page to a phishing information page
|
||||
*
|
||||
|
@ -34,6 +34,7 @@ cleanContextForImports();
|
||||
import log from 'loglevel';
|
||||
import { WindowPostMessageStream } from '@metamask/post-message-stream';
|
||||
import { initializeProvider } from '@metamask/providers/dist/initializeInpageProvider';
|
||||
import shouldInjectProvider from '../../shared/modules/provider-injection';
|
||||
|
||||
restoreContextAfterImports();
|
||||
|
||||
@ -43,14 +44,16 @@ log.setDefaultLevel(process.env.METAMASK_DEBUG ? 'debug' : 'warn');
|
||||
// setup plugin communication
|
||||
//
|
||||
|
||||
// setup background connection
|
||||
const metamaskStream = new WindowPostMessageStream({
|
||||
name: 'metamask-inpage',
|
||||
target: 'metamask-contentscript',
|
||||
});
|
||||
if (shouldInjectProvider()) {
|
||||
// setup background connection
|
||||
const metamaskStream = new WindowPostMessageStream({
|
||||
name: 'metamask-inpage',
|
||||
target: 'metamask-contentscript',
|
||||
});
|
||||
|
||||
initializeProvider({
|
||||
connectionStream: metamaskStream,
|
||||
logger: log,
|
||||
shouldShimWeb3: true,
|
||||
});
|
||||
initializeProvider({
|
||||
connectionStream: metamaskStream,
|
||||
logger: log,
|
||||
shouldShimWeb3: true,
|
||||
});
|
||||
}
|
||||
|
93
shared/modules/provider-injection.js
Normal file
93
shared/modules/provider-injection.js
Normal file
@ -0,0 +1,93 @@
|
||||
/**
|
||||
* Determines if the provider should be injected
|
||||
*
|
||||
* @returns {boolean} {@code true} Whether the provider should be injected
|
||||
*/
|
||||
export default function shouldInjectProvider() {
|
||||
return (
|
||||
doctypeCheck() &&
|
||||
suffixCheck() &&
|
||||
documentElementCheck() &&
|
||||
!blockedDomainCheck()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the doctype of the current document if it exists
|
||||
*
|
||||
* @returns {boolean} {@code true} if the doctype is html or if none exists
|
||||
*/
|
||||
function doctypeCheck() {
|
||||
const { doctype } = window.document;
|
||||
if (doctype) {
|
||||
return doctype.name === 'html';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the extension (suffix) of the current document is prohibited
|
||||
*
|
||||
* This checks {@code window.location.pathname} against a set of file extensions
|
||||
* that we should not inject the provider into. This check is indifferent of
|
||||
* query parameters in the location.
|
||||
*
|
||||
* @returns {boolean} whether or not the extension of the current document is prohibited
|
||||
*/
|
||||
function suffixCheck() {
|
||||
const prohibitedTypes = [/\.xml$/u, /\.pdf$/u];
|
||||
const currentUrl = window.location.pathname;
|
||||
for (let i = 0; i < prohibitedTypes.length; i++) {
|
||||
if (prohibitedTypes[i].test(currentUrl)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the documentElement of the current document
|
||||
*
|
||||
* @returns {boolean} {@code true} if the documentElement is an html node or if none exists
|
||||
*/
|
||||
function documentElementCheck() {
|
||||
const documentElement = document.documentElement.nodeName;
|
||||
if (documentElement) {
|
||||
return documentElement.toLowerCase() === 'html';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current domain is blocked
|
||||
*
|
||||
* @returns {boolean} {@code true} if the current domain is blocked
|
||||
*/
|
||||
function blockedDomainCheck() {
|
||||
const blockedDomains = [
|
||||
'uscourts.gov',
|
||||
'dropbox.com',
|
||||
'webbyawards.com',
|
||||
'cdn.shopify.com/s/javascripts/tricorder/xtld-read-only-frame.html',
|
||||
'adyen.com',
|
||||
'gravityforms.com',
|
||||
'docs.google.com',
|
||||
'harbourair.com',
|
||||
'ani.gamer.com.tw',
|
||||
'blueskybooking.com',
|
||||
'sharefile.com',
|
||||
];
|
||||
const currentUrl = window.location.href;
|
||||
let currentRegex;
|
||||
for (let i = 0; i < blockedDomains.length; i++) {
|
||||
const blockedDomain = blockedDomains[i].replace('.', '\\.');
|
||||
currentRegex = new RegExp(
|
||||
`(?:https?:\\/\\/)(?:(?!${blockedDomain}).)*$`,
|
||||
'u',
|
||||
);
|
||||
if (!currentRegex.test(currentUrl)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
Loading…
Reference in New Issue
Block a user