*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",
|
||||
"96": "icon@2x.png"
|
||||
},
|
||||
"permissions": ["proxy", "webRequest", "webRequestBlocking", "<all_urls>"],
|
||||
"permissions": ["proxy", "webRequest", "webRequestBlocking", "webNavigation", "<all_urls>"],
|
||||
"background": {
|
||||
"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 OnBeforeRequestDetailsType = WebRequest.OnBeforeRequestDetailsType;
|
||||
import OnBeforeSendHeadersDetailsType = WebRequest.OnBeforeSendHeadersDetailsType;
|
||||
|
@ -9,6 +9,7 @@ import OnRequestDetailsType = Proxy.OnRequestDetailsType;
|
|||
import HttpHeaders = WebRequest.HttpHeaders;
|
||||
import StreamFilter = WebRequest.StreamFilter;
|
||||
import HttpHeadersItemType = WebRequest.HttpHeadersItemType;
|
||||
import OnBeforeNavigateDetailsType = WebNavigation.OnBeforeNavigateDetailsType;
|
||||
|
||||
export {
|
||||
OnHeadersReceivedDetailsType,
|
||||
|
@ -21,4 +22,6 @@ export {
|
|||
HttpHeaders,
|
||||
StreamFilter,
|
||||
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 {
|
||||
BlockingResponse,
|
||||
OnBeforeNavigateDetailsType,
|
||||
OnBeforeRequestDetailsType,
|
||||
OnBeforeSendHeadersDetailsType,
|
||||
OnCompletedDetailsType,
|
||||
|
@ -10,11 +11,16 @@ import {
|
|||
OnHeadersReceivedDetailsType,
|
||||
OnRequestDetailsType,
|
||||
} 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 {
|
||||
private contentProviders: BaseProvider[] = [];
|
||||
private requests: Map<string, BaseProvider> = new Map();
|
||||
private requestData: Map<string, {}> = new Map();
|
||||
private navigations: Map<string, Promise<any>> = new Map();
|
||||
|
||||
constructor() {
|
||||
browser.webRequest.onHeadersReceived.addListener(
|
||||
|
@ -49,6 +55,9 @@ export default class WebEngine {
|
|||
urls: ["<all_urls>"],
|
||||
}
|
||||
);
|
||||
browser.webNavigation.onBeforeNavigate.addListener(
|
||||
this.handleNavigationRequest.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
private async headerHandler(
|
||||
|
@ -80,6 +89,20 @@ export default class WebEngine {
|
|||
private async requestHandler(
|
||||
details: OnBeforeRequestDetailsType
|
||||
): 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");
|
||||
}
|
||||
|
||||
|
@ -162,4 +185,105 @@ export default class WebEngine {
|
|||
|
||||
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