refactor: automatic proxy constructor

This commit is contained in:
velzie 2024-07-19 13:52:34 -04:00
parent eba3e759fd
commit 80d51ed7a7
No known key found for this signature in database
GPG key ID: 048413F95F0DDE1F
11 changed files with 192 additions and 131 deletions

View file

@ -1,10 +1,8 @@
// import { encodeUrl } from "./shared"; import { client } from ".";
navigator.sendBeacon = new Proxy(navigator.sendBeacon, { // goodybye spyware~
apply() { client.Proxy(navigator, "sendBeacon", {
// argArray[0] = encodeUrl(argArray[0]); apply(ctx) {
ctx.return(null);
// return Reflect.apply(target, thisArg, argArray);
return null;
}, },
}); });

View file

@ -1,3 +1,4 @@
import { client } from ".";
import { rewriteCss } from "./shared"; import { rewriteCss } from "./shared";
const cssProperties = [ const cssProperties = [
@ -13,14 +14,9 @@ const cssProperties = [
]; ];
// const jsProperties = ["background", "backgroundImage", "mask", "maskImage", "listStyle", "listStyleImage", "borderImage", "borderImageSource", "cursor"]; // const jsProperties = ["background", "backgroundImage", "mask", "maskImage", "listStyle", "listStyleImage", "borderImage", "borderImageSource", "cursor"];
CSSStyleDeclaration.prototype.setProperty = new Proxy( client.Proxy(CSSStyleDeclaration.prototype, "setProperty", {
CSSStyleDeclaration.prototype.setProperty, apply(ctx) {
{ if (cssProperties.includes(ctx.args[0]))
apply(target, thisArg, argArray) { ctx.args[1] = rewriteCss(ctx.args[1]);
if (cssProperties.includes(argArray[0])) },
argArray[1] = rewriteCss(argArray[1]); });
return Reflect.apply(target, thisArg, argArray);
},
}
);

View file

@ -127,18 +127,21 @@ Object.defineProperty(Element.prototype, "innerHTML", {
}, },
}); });
MutationObserver.prototype.observe = new Proxy(MutationObserver.prototype.observe, { MutationObserver.prototype.observe = new Proxy(
apply(target, thisArg, argArray) { MutationObserver.prototype.observe,
if (argArray[0] === documentProxy) argArray[0] = document; {
apply(target, thisArg, argArray) {
if (argArray[0] === documentProxy) argArray[0] = document;
return Reflect.apply(target, thisArg, argArray); return Reflect.apply(target, thisArg, argArray);
},
} }
}); );
document.createTreeWalker = new Proxy(document.createTreeWalker, { document.createTreeWalker = new Proxy(document.createTreeWalker, {
apply(target, thisArg, argArray) { apply(target, thisArg, argArray) {
if (argArray[0] === documentProxy) argArray[0] = document; if (argArray[0] === documentProxy) argArray[0] = document;
return Reflect.apply(target, thisArg, argArray); return Reflect.apply(target, thisArg, argArray);
} },
}); });

View file

@ -1,17 +1,14 @@
import { client } from ".";
import { encodeUrl } from "./shared"; import { encodeUrl } from "./shared";
window.history.pushState = new Proxy(window.history.pushState, { client.Proxy(window.history, "pushState", {
apply(target, thisArg, argArray) { apply(ctx) {
argArray[2] = encodeUrl(argArray[2]); ctx.args[2] = encodeUrl(ctx.args[2]);
return Reflect.apply(target, thisArg, argArray);
}, },
}); });
window.history.replaceState = new Proxy(window.history.replaceState, { client.Proxy(window.history, "replaceState", {
apply(target, thisArg, argArray) { apply(ctx) {
argArray[2] = encodeUrl(argArray[2]); ctx.args[2] = encodeUrl(ctx.args[2]);
return Reflect.apply(target, thisArg, argArray);
}, },
}); });

View file

@ -2,7 +2,8 @@ import { encodeUrl } from "../shared/rewriters/url";
window.$sImport = function (base) { window.$sImport = function (base) {
return function (url) { return function (url) {
let resolved = new URL(url, base).href; const resolved = new URL(url, base).href;
return function () {}.constructor( return function () {}.constructor(
`return import("${encodeUrl(resolved)}")` `return import("${encodeUrl(resolved)}")`
)(); )();

View file

@ -1,21 +1,4 @@
import "./scope.ts"; import { decodeUrl } from "./shared";
import "./window.ts";
import "./event.ts";
import "./native/eval.ts";
import "./location.ts";
import "./trustedTypes.ts";
import "./requests/fetch.ts";
import "./requests/xmlhttprequest.ts";
import "./requests/websocket.ts";
import "./element.ts";
import "./storage.ts";
import "./css.ts";
import "./history.ts";
import "./worker.ts";
import "./beacon.ts";
import "./origin.ts";
import "./import.ts";
import "./postmessage.ts";
declare global { declare global {
interface Window { interface Window {
@ -23,3 +6,101 @@ declare global {
$sImport: any; $sImport: any;
} }
} }
type ProxyCtx = {
fn: Function;
this: any;
args: any[];
newTarget: Function;
return: (r: any) => void;
};
class ScramjetClient {
Proxy(
target: any,
prop: string,
handler: {
construct?(ctx: ProxyCtx): any;
apply?(ctx: ProxyCtx): any;
}
) {
const value = Reflect.get(target, prop);
delete target[prop];
const h: ProxyHandler<any> = {};
if (handler.construct) {
h.construct = function (
target: any,
argArray: any[],
newTarget: Function
) {
let returnValue: any = null;
const ctx: ProxyCtx = {
fn: target,
this: null,
args: argArray,
newTarget: newTarget,
return: (r: any) => {
returnValue = r;
},
};
handler.construct(ctx);
if (returnValue) {
return returnValue;
}
return Reflect.construct(ctx.fn, ctx.args, ctx.newTarget);
};
}
if (handler.apply) {
h.apply = function (target: any, thisArg: any, argArray: any[]) {
let returnValue: any = null;
const ctx: ProxyCtx = {
fn: target,
this: thisArg,
args: argArray,
newTarget: null,
return: (r: any) => {
returnValue = r;
},
};
handler.apply(ctx);
if (returnValue) {
return returnValue;
}
return Reflect.apply(ctx.fn, ctx.this, ctx.args);
};
}
target[prop] = new Proxy(value, h);
}
get url(): URL {
return new URL(decodeUrl(location.href));
}
init() {
console.log("SCRAMJET INIT");
}
}
export const client = new ScramjetClient();
client.init();
// @ts-ignore
const context = import.meta.webpackContext("./", {
recursive: true,
});
for (const key of context.keys()) {
context(key);
}

View file

@ -1,6 +1,7 @@
window.postMessage = new Proxy(window.postMessage, { import { client } from ".";
apply(target, thisArg, argArray) {
if (typeof argArray[1] === "string") argArray[1] = "*"; client.Proxy(window, "postMessage", {
Reflect.apply(target, thisArg, argArray); apply(ctx) {
if (typeof ctx.args[1] === "string") ctx.args[1] = "*";
}, },
}); });

View file

@ -1,35 +1,28 @@
// ts throws an error if you dont do window.fetch // ts throws an error if you dont do window.fetch
import { client } from "..";
import { encodeUrl, rewriteHeaders } from "../shared"; import { encodeUrl, rewriteHeaders } from "../shared";
window.fetch = new Proxy(window.fetch, { client.Proxy(window, "fetch", {
apply(target, thisArg, argArray) { apply(ctx) {
argArray[0] = encodeUrl(argArray[0]); ctx.args[0] = encodeUrl(ctx.args[0]);
return Reflect.apply(target, thisArg, argArray);
}, },
}); });
Headers = new Proxy(Headers, { client.Proxy(window, "Headers", {
construct(target, argArray, newTarget) { construct(ctx) {
argArray[0] = rewriteHeaders(argArray[0]); ctx.args[0] = rewriteHeaders(ctx.args[0]);
return Reflect.construct(target, argArray, newTarget);
}, },
}); });
Request = new Proxy(Request, { client.Proxy(window, "Request", {
construct(target, argArray, newTarget) { construct(ctx) {
if (typeof argArray[0] === "string") argArray[0] = encodeUrl(argArray[0]); if (typeof ctx.args[0] === "string") ctx.args[0] = encodeUrl(ctx.args[0]);
return Reflect.construct(target, argArray, newTarget);
}, },
}); });
Response.redirect = new Proxy(Response.redirect, { client.Proxy(Response, "redirect", {
apply(target, thisArg, argArray) { apply(ctx) {
argArray[0] = encodeUrl(argArray[0]); ctx.args[0] = encodeUrl(ctx.args[0]);
return Reflect.apply(target, thisArg, argArray);
}, },
}); });

View file

@ -1,18 +1,20 @@
import { decodeUrl } from "../../shared/rewriters/url"; import { client } from "..";
import { BareClient } from "../shared"; import { BareClient } from "../shared";
const client = new BareClient(); const bare = new BareClient();
WebSocket = new Proxy(WebSocket, { client.Proxy(window, "WebSocket", {
construct(target, args) { construct(ctx) {
return client.createWebSocket( ctx.return(
args[0], bare.createWebSocket(
args[1], ctx.args[0],
target, ctx.args[1],
{ ctx.fn as typeof WebSocket,
"User-Agent": navigator.userAgent, {
Origin: new URL(decodeUrl(location.href)).origin, "User-Agent": navigator.userAgent,
}, Origin: client.url.origin,
ArrayBuffer.prototype },
ArrayBuffer.prototype
)
); );
}, },
}); });

View file

@ -1,23 +1,17 @@
import { client } from "..";
import { encodeUrl, rewriteHeaders } from "../shared"; import { encodeUrl, rewriteHeaders } from "../shared";
XMLHttpRequest.prototype.open = new Proxy(XMLHttpRequest.prototype.open, { client.Proxy(XMLHttpRequest.prototype, "open", {
apply(target, thisArg, argArray) { apply(ctx) {
if (argArray[1]) argArray[1] = encodeUrl(argArray[1]); if (ctx.args[1]) ctx.args[1] = encodeUrl(ctx.args[1]);
return Reflect.apply(target, thisArg, argArray);
}, },
}); });
XMLHttpRequest.prototype.setRequestHeader = new Proxy( client.Proxy(XMLHttpRequest.prototype, "setRequestHeader", {
XMLHttpRequest.prototype.setRequestHeader, apply(ctx) {
{ let headerObject = Object.fromEntries([ctx.args]);
apply(target, thisArg, argArray) { headerObject = rewriteHeaders(headerObject);
let headerObject = Object.fromEntries([argArray]);
headerObject = rewriteHeaders(headerObject);
argArray = Object.entries(headerObject)[0]; ctx.args = Object.entries(headerObject)[0];
},
return Reflect.apply(target, thisArg, argArray); });
},
}
);

View file

@ -1,3 +1,4 @@
import { client } from ".";
import { encodeUrl } from "../shared/rewriters/url"; import { encodeUrl } from "../shared/rewriters/url";
import { locationProxy } from "./location"; import { locationProxy } from "./location";
@ -78,38 +79,32 @@ export const documentProxy = new Proxy(document, {
}, },
}); });
Function.prototype.apply = new Proxy(Function.prototype.apply, { client.Proxy(Function.prototype, "apply", {
apply(target, thisArg, argArray) { apply(ctx) {
if (argArray[0] === windowProxy) { if (ctx.args[0] === windowProxy) {
argArray[0] = window; ctx.args[0] = window;
} else if (argArray[0] === documentProxy) { } else if (ctx.args[0] === documentProxy) {
argArray[0] = document; ctx.args[0] = document;
} }
return Reflect.apply(target, thisArg, argArray);
}, },
}); });
Function.prototype.call = new Proxy(Function.prototype.call, { client.Proxy(Function.prototype, "call", {
apply(target, thisArg, argArray) { apply(ctx) {
if (argArray[0] === windowProxy) { if (ctx.args[0] === windowProxy) {
argArray[0] = window; ctx.args[0] = window;
} else if (argArray[0] === documentProxy) { } else if (ctx.args[0] === documentProxy) {
argArray[0] = document; ctx.args[0] = document;
} }
return Reflect.apply(target, thisArg, argArray);
}, },
}); });
Function.prototype.bind = new Proxy(Function.prototype.bind, { client.Proxy(Function.prototype, "bind", {
apply(target, thisArg, argArray) { apply(ctx) {
if (argArray[0] === windowProxy) { if (ctx.args[0] === windowProxy) {
argArray[0] = window; ctx.args[0] = window;
} else if (argArray[0] === documentProxy) { } else if (ctx.args[0] === documentProxy) {
argArray[0] = document; ctx.args[0] = document;
} }
return Reflect.apply(target, thisArg, argArray);
}, },
}); });