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, {
apply() {
// argArray[0] = encodeUrl(argArray[0]);
// return Reflect.apply(target, thisArg, argArray);
return null;
// goodybye spyware~
client.Proxy(navigator, "sendBeacon", {
apply(ctx) {
ctx.return(null);
},
});

View file

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

View file

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

View file

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

View file

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

View file

@ -1,21 +1,4 @@
import "./scope.ts";
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";
import { decodeUrl } from "./shared";
declare global {
interface Window {
@ -23,3 +6,101 @@ declare global {
$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, {
apply(target, thisArg, argArray) {
if (typeof argArray[1] === "string") argArray[1] = "*";
Reflect.apply(target, thisArg, argArray);
import { client } from ".";
client.Proxy(window, "postMessage", {
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
import { client } from "..";
import { encodeUrl, rewriteHeaders } from "../shared";
window.fetch = new Proxy(window.fetch, {
apply(target, thisArg, argArray) {
argArray[0] = encodeUrl(argArray[0]);
return Reflect.apply(target, thisArg, argArray);
client.Proxy(window, "fetch", {
apply(ctx) {
ctx.args[0] = encodeUrl(ctx.args[0]);
},
});
Headers = new Proxy(Headers, {
construct(target, argArray, newTarget) {
argArray[0] = rewriteHeaders(argArray[0]);
return Reflect.construct(target, argArray, newTarget);
client.Proxy(window, "Headers", {
construct(ctx) {
ctx.args[0] = rewriteHeaders(ctx.args[0]);
},
});
Request = new Proxy(Request, {
construct(target, argArray, newTarget) {
if (typeof argArray[0] === "string") argArray[0] = encodeUrl(argArray[0]);
return Reflect.construct(target, argArray, newTarget);
client.Proxy(window, "Request", {
construct(ctx) {
if (typeof ctx.args[0] === "string") ctx.args[0] = encodeUrl(ctx.args[0]);
},
});
Response.redirect = new Proxy(Response.redirect, {
apply(target, thisArg, argArray) {
argArray[0] = encodeUrl(argArray[0]);
return Reflect.apply(target, thisArg, argArray);
client.Proxy(Response, "redirect", {
apply(ctx) {
ctx.args[0] = encodeUrl(ctx.args[0]);
},
});

View file

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

View file

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

View file

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