diff --git a/src/client/beacon.ts b/src/client/beacon.ts index 6a7d70c..1e3c27e 100644 --- a/src/client/beacon.ts +++ b/src/client/beacon.ts @@ -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); }, }); diff --git a/src/client/css.ts b/src/client/css.ts index 47afe46..c2d1fda 100644 --- a/src/client/css.ts +++ b/src/client/css.ts @@ -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]); + }, +}); diff --git a/src/client/element.ts b/src/client/element.ts index f319606..29be462 100644 --- a/src/client/element.ts +++ b/src/client/element.ts @@ -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); - } + }, }); diff --git a/src/client/history.ts b/src/client/history.ts index eb80602..7dfa671 100644 --- a/src/client/history.ts +++ b/src/client/history.ts @@ -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]); }, }); diff --git a/src/client/import.ts b/src/client/import.ts index fafe095..11becf3 100644 --- a/src/client/import.ts +++ b/src/client/import.ts @@ -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)}")` )(); diff --git a/src/client/index.ts b/src/client/index.ts index 83f12b8..ffa18bd 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -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 = {}; + + 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); +} diff --git a/src/client/postmessage.ts b/src/client/postmessage.ts index bf9c8dd..2a946a7 100644 --- a/src/client/postmessage.ts +++ b/src/client/postmessage.ts @@ -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] = "*"; }, }); diff --git a/src/client/requests/fetch.ts b/src/client/requests/fetch.ts index ec3e76d..b06f1ef 100644 --- a/src/client/requests/fetch.ts +++ b/src/client/requests/fetch.ts @@ -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]); }, }); diff --git a/src/client/requests/websocket.ts b/src/client/requests/websocket.ts index 43fa158..3747c39 100644 --- a/src/client/requests/websocket.ts +++ b/src/client/requests/websocket.ts @@ -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 + ) ); }, }); diff --git a/src/client/requests/xmlhttprequest.ts b/src/client/requests/xmlhttprequest.ts index 1b1bb78..834d4c9 100644 --- a/src/client/requests/xmlhttprequest.ts +++ b/src/client/requests/xmlhttprequest.ts @@ -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]; + }, +}); diff --git a/src/client/window.ts b/src/client/window.ts index de92a93..092a60f 100644 --- a/src/client/window.ts +++ b/src/client/window.ts @@ -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); }, });