*Add navigation monitoring system to hijack search results and attempt to resolve via web3
This commit is contained in:
parent
1443b2d79a
commit
f3ee68679b
|
@ -8,7 +8,7 @@
|
||||||
"48": "icon.png",
|
"48": "icon.png",
|
||||||
"96": "icon@2x.png"
|
"96": "icon@2x.png"
|
||||||
},
|
},
|
||||||
"permissions": ["proxy", "webRequest", "webRequestBlocking", "<all_urls>"],
|
"permissions": ["proxy", "webRequest", "webRequestBlocking", "webNavigation", "<all_urls>"],
|
||||||
"background": {
|
"background": {
|
||||||
"scripts": ["background.js"]
|
"scripts": ["background.js"]
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { WebRequest, Proxy } from "webextension-polyfill";
|
import { WebRequest, Proxy, Tabs, WebNavigation } from "webextension-polyfill";
|
||||||
import OnHeadersReceivedDetailsType = WebRequest.OnHeadersReceivedDetailsType;
|
import OnHeadersReceivedDetailsType = WebRequest.OnHeadersReceivedDetailsType;
|
||||||
import OnBeforeRequestDetailsType = WebRequest.OnBeforeRequestDetailsType;
|
import OnBeforeRequestDetailsType = WebRequest.OnBeforeRequestDetailsType;
|
||||||
import OnBeforeSendHeadersDetailsType = WebRequest.OnBeforeSendHeadersDetailsType;
|
import OnBeforeSendHeadersDetailsType = WebRequest.OnBeforeSendHeadersDetailsType;
|
||||||
|
@ -9,6 +9,7 @@ import OnRequestDetailsType = Proxy.OnRequestDetailsType;
|
||||||
import HttpHeaders = WebRequest.HttpHeaders;
|
import HttpHeaders = WebRequest.HttpHeaders;
|
||||||
import StreamFilter = WebRequest.StreamFilter;
|
import StreamFilter = WebRequest.StreamFilter;
|
||||||
import HttpHeadersItemType = WebRequest.HttpHeadersItemType;
|
import HttpHeadersItemType = WebRequest.HttpHeadersItemType;
|
||||||
|
import OnBeforeNavigateDetailsType = WebNavigation.OnBeforeNavigateDetailsType;
|
||||||
|
|
||||||
export {
|
export {
|
||||||
OnHeadersReceivedDetailsType,
|
OnHeadersReceivedDetailsType,
|
||||||
|
@ -21,4 +22,6 @@ export {
|
||||||
HttpHeaders,
|
HttpHeaders,
|
||||||
StreamFilter,
|
StreamFilter,
|
||||||
HttpHeadersItemType,
|
HttpHeadersItemType,
|
||||||
|
Tabs,
|
||||||
|
OnBeforeNavigateDetailsType,
|
||||||
};
|
};
|
||||||
|
|
124
src/webEngine.ts
124
src/webEngine.ts
|
@ -3,6 +3,7 @@ import browser from "@lumeweb/webextension-polyfill";
|
||||||
import BaseProvider from "./contentProviders/baseProvider.js";
|
import BaseProvider from "./contentProviders/baseProvider.js";
|
||||||
import {
|
import {
|
||||||
BlockingResponse,
|
BlockingResponse,
|
||||||
|
OnBeforeNavigateDetailsType,
|
||||||
OnBeforeRequestDetailsType,
|
OnBeforeRequestDetailsType,
|
||||||
OnBeforeSendHeadersDetailsType,
|
OnBeforeSendHeadersDetailsType,
|
||||||
OnCompletedDetailsType,
|
OnCompletedDetailsType,
|
||||||
|
@ -10,11 +11,16 @@ import {
|
||||||
OnHeadersReceivedDetailsType,
|
OnHeadersReceivedDetailsType,
|
||||||
OnRequestDetailsType,
|
OnRequestDetailsType,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
import { getTld, isDomain, isIp, normalizeDomain } from "./util.js";
|
||||||
|
import tldEnum from "@lumeweb/tld-enum";
|
||||||
|
import { resolve } from "@lumeweb/kernel-dns-client";
|
||||||
|
import { blake2b, bufToHex } from "libskynet";
|
||||||
|
|
||||||
export default class WebEngine {
|
export default class WebEngine {
|
||||||
private contentProviders: BaseProvider[] = [];
|
private contentProviders: BaseProvider[] = [];
|
||||||
private requests: Map<string, BaseProvider> = new Map();
|
private requests: Map<string, BaseProvider> = new Map();
|
||||||
private requestData: Map<string, {}> = new Map();
|
private requestData: Map<string, {}> = new Map();
|
||||||
|
private navigations: Map<string, Promise<any>> = new Map();
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
browser.webRequest.onHeadersReceived.addListener(
|
browser.webRequest.onHeadersReceived.addListener(
|
||||||
|
@ -49,6 +55,9 @@ export default class WebEngine {
|
||||||
urls: ["<all_urls>"],
|
urls: ["<all_urls>"],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
browser.webNavigation.onBeforeNavigate.addListener(
|
||||||
|
this.handleNavigationRequest.bind(this)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async headerHandler(
|
private async headerHandler(
|
||||||
|
@ -80,6 +89,20 @@ export default class WebEngine {
|
||||||
private async requestHandler(
|
private async requestHandler(
|
||||||
details: OnBeforeRequestDetailsType
|
details: OnBeforeRequestDetailsType
|
||||||
): Promise<BlockingResponse> {
|
): Promise<BlockingResponse> {
|
||||||
|
const navId = this.getNavigationId(details);
|
||||||
|
let navRedirect: boolean | string = false;
|
||||||
|
if (this.navigations.has(navId)) {
|
||||||
|
try {
|
||||||
|
await this.navigations.get(navId);
|
||||||
|
} catch (e: any) {
|
||||||
|
navRedirect = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (navRedirect && navRedirect !== details.url) {
|
||||||
|
return { redirectUrl: navRedirect as string };
|
||||||
|
}
|
||||||
|
|
||||||
return this.processHandler(details, "handleRequest");
|
return this.processHandler(details, "handleRequest");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,4 +185,105 @@ export default class WebEngine {
|
||||||
|
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async handleNavigationRequest(details: OnBeforeNavigateDetailsType) {
|
||||||
|
if (!details.url) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDomain(details.url) || isIp(details.url)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const originalUrl = new URL(details.url);
|
||||||
|
const hostname = normalizeDomain(originalUrl.hostname);
|
||||||
|
|
||||||
|
if (["chrome:"].includes(originalUrl.protocol)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("google.com" === hostname) {
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
originalUrl.searchParams.has("client") &&
|
||||||
|
originalUrl.searchParams.get("client")?.includes("firefox")
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let resolveRequest: any, rejectRequest: any;
|
||||||
|
|
||||||
|
let promise = new Promise((resolve, reject) => {
|
||||||
|
resolveRequest = resolve;
|
||||||
|
rejectRequest = reject;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.navigations.set(this.getNavigationId(details), promise);
|
||||||
|
|
||||||
|
let queriedUrl = originalUrl.searchParams.get("q") as string;
|
||||||
|
let queriedHost = queriedUrl;
|
||||||
|
try {
|
||||||
|
let queriedUrlUbj = new URL(queriedUrl);
|
||||||
|
queriedHost = queriedUrlUbj.hostname;
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
if (tldEnum.list.includes(getTld(queriedHost))) {
|
||||||
|
resolveRequest();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isIp(queriedHost)) {
|
||||||
|
resolveRequest();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/[\s_]/.test(queriedHost)) {
|
||||||
|
resolveRequest();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let dns;
|
||||||
|
|
||||||
|
try {
|
||||||
|
dns = await resolve(queriedHost, {});
|
||||||
|
} catch (e) {
|
||||||
|
resolveRequest();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dns) {
|
||||||
|
resolveRequest();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!queriedUrl.includes("://")) {
|
||||||
|
queriedUrl = `http://${queriedUrl}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
rejectRequest(queriedUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getNavigationId(details: any) {
|
||||||
|
return `${details.tabId}_${bufToHex(
|
||||||
|
blake2b(new TextEncoder().encode(details.url))
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static cancelRequest(tabId: number) {
|
||||||
|
const handler = (details: OnBeforeRequestDetailsType): BlockingResponse => {
|
||||||
|
if (details.tabId !== tabId) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
browser.webRequest.onBeforeRequest.removeListener(handler);
|
||||||
|
|
||||||
|
return { cancel: true };
|
||||||
|
};
|
||||||
|
|
||||||
|
browser.webRequest.onBeforeRequest.addListener(
|
||||||
|
handler,
|
||||||
|
{ urls: ["<all_urls>"] },
|
||||||
|
["blocking"]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue