mirror of
https://github.com/MercuryWorkshop/scramjet.git
synced 2025-05-13 22:40:01 -04:00
YUes I am god
This commit is contained in:
parent
5024e19c08
commit
c61e62ec91
6 changed files with 56 additions and 8 deletions
|
@ -110,7 +110,8 @@ export class ScramjetClient {
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const module of modules) {
|
for (const module of modules) {
|
||||||
if (module.enabled()) module.default(this, this.global);
|
if (!module.enabled || module.enabled())
|
||||||
|
module.default(this, this.global);
|
||||||
else module.disabled(this, this.global);
|
else module.disabled(this, this.global);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,35 @@
|
||||||
import { ScramjetClient } from "../client";
|
import { ScramjetClient } from "../client";
|
||||||
|
import { POLLUTANT } from "../shared/realm";
|
||||||
|
|
||||||
export default function (client: ScramjetClient) {
|
export default function (client: ScramjetClient) {
|
||||||
client.Proxy("window.postMessage", {
|
client.Proxy("window.postMessage", {
|
||||||
apply(ctx) {
|
apply(ctx) {
|
||||||
// so we need to send the real origin here, since the recieving window can't possibly know.
|
// so we need to send the real origin here, since the recieving window can't possibly know.
|
||||||
// except, remember that this code is being ran in a different realm than the invoker, so if we ask our `client` it may give us the wrong origin
|
// except, remember that this code is being ran in a different realm than the invoker, so if we ask our `client` it may give us the wrong origin
|
||||||
// but, the first argument given will be polluted with the real realm
|
// if we were given any object that came from the real realm we can use that to get the real origin
|
||||||
|
// and this works in every case EXCEPT for the fact that all three arguments can be strings which are copied instead of cloned
|
||||||
|
// so we have to use `$setrealm` which will pollute this with an object from the real realm
|
||||||
|
const pollutant = ctx.this[POLLUTANT] || {};
|
||||||
|
|
||||||
// this obtains a reference to the Function object of the real realm
|
// and now we can steal Function from the caller's realm
|
||||||
const {
|
const {
|
||||||
constructor: { constructor: Function },
|
constructor: { constructor: Function },
|
||||||
} = ctx.args[0];
|
} = pollutant;
|
||||||
|
|
||||||
// and finally, invoking the stolen Function will execute inside the caller's realm
|
// invoking stolen function will give us the caller's globalThis, remember scramjet has already proxied it!!!
|
||||||
const callerGlobalThis: Self = Function("return globalThis")();
|
const callerGlobalThisProxied: Self = Function("return globalThis")();
|
||||||
const callerClient: ScramjetClient =
|
const callerClient: ScramjetClient =
|
||||||
callerGlobalThis[ScramjetClient.SCRAMJET];
|
callerGlobalThisProxied[ScramjetClient.SCRAMJET];
|
||||||
|
|
||||||
|
// this WOULD be enough but the source argument of MessageEvent has to return the caller's window
|
||||||
|
// and if we just call it normally it would be coming from here, which WILL NOT BE THE CALLER'S because the accessor is from the parent
|
||||||
|
// so with the stolen function we wrap postmessage so the source will truly be the caller's window (remember that function is scramjet's!!!)
|
||||||
|
const wrappedPostMessage = Function(
|
||||||
|
"data",
|
||||||
|
"origin",
|
||||||
|
"transfer",
|
||||||
|
"this(data, origin, transfer)"
|
||||||
|
);
|
||||||
|
|
||||||
ctx.args[0] = {
|
ctx.args[0] = {
|
||||||
$scramjet$origin: callerClient.url.origin,
|
$scramjet$origin: callerClient.url.origin,
|
||||||
|
@ -24,6 +38,8 @@ export default function (client: ScramjetClient) {
|
||||||
|
|
||||||
// * origin because obviously
|
// * origin because obviously
|
||||||
if (typeof ctx.args[1] === "string") ctx.args[1] = "*";
|
if (typeof ctx.args[1] === "string") ctx.args[1] = "*";
|
||||||
|
|
||||||
|
wrappedPostMessage.call(ctx.fn, ctx.args[0], ctx.args[1], ctx.args[2]);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
export function getOwnPropertyDescriptorHandler(target, prop) {
|
export function getOwnPropertyDescriptorHandler(target, prop) {
|
||||||
let realDescriptor = Reflect.getOwnPropertyDescriptor(target, prop);
|
let realDescriptor = Reflect.getOwnPropertyDescriptor(target, prop);
|
||||||
if (!realDescriptor) return realDescriptor;
|
return realDescriptor;
|
||||||
|
|
||||||
let d: PropertyDescriptor = {};
|
let d: PropertyDescriptor = {};
|
||||||
|
|
||||||
|
|
26
src/client/shared/realm.ts
Normal file
26
src/client/shared/realm.ts
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import { ScramjetClient } from "../client";
|
||||||
|
import { config } from "../shared";
|
||||||
|
|
||||||
|
export const POLLUTANT = Symbol.for("scramjet realm pollutant");
|
||||||
|
|
||||||
|
export default function (client: ScramjetClient, self: typeof globalThis) {
|
||||||
|
// object.$setrealm({}).postMessage(...)
|
||||||
|
// the empty object is the "pollutant" which can reconstruct the real realm
|
||||||
|
// i explain more in postmessage.ts
|
||||||
|
Object.defineProperty(self.Object.prototype, config.setrealmfn, {
|
||||||
|
value(pollution: {}) {
|
||||||
|
// this is bad!! sites could detect this
|
||||||
|
Object.defineProperty(this, POLLUTANT, {
|
||||||
|
value: pollution,
|
||||||
|
writable: false,
|
||||||
|
configurable: true,
|
||||||
|
enumerable: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
writable: false,
|
||||||
|
configurable: false,
|
||||||
|
enumerable: false,
|
||||||
|
});
|
||||||
|
}
|
|
@ -16,12 +16,16 @@ export class ScramjetController {
|
||||||
importfn: "$scramjet$import",
|
importfn: "$scramjet$import",
|
||||||
rewritefn: "$scramjet$rewrite",
|
rewritefn: "$scramjet$rewrite",
|
||||||
metafn: "$scramjet$meta",
|
metafn: "$scramjet$meta",
|
||||||
|
setrealmfn: "$scramjet$setrealm",
|
||||||
wasm: "/scramjet.wasm.js",
|
wasm: "/scramjet.wasm.js",
|
||||||
shared: "/scramjet.shared.js",
|
shared: "/scramjet.shared.js",
|
||||||
worker: "/scramjet.worker.js",
|
worker: "/scramjet.worker.js",
|
||||||
thread: "/scramjet.thread.js",
|
thread: "/scramjet.thread.js",
|
||||||
client: "/scramjet.client.js",
|
client: "/scramjet.client.js",
|
||||||
codecs: "/scramjet.codecs.js",
|
codecs: "/scramjet.codecs.js",
|
||||||
|
flags: {
|
||||||
|
serviceworkers: true,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
this.config = Object.assign({}, defaultConfig, config);
|
this.config = Object.assign({}, defaultConfig, config);
|
||||||
|
|
1
src/types.d.ts
vendored
1
src/types.d.ts
vendored
|
@ -28,6 +28,7 @@ interface ScramjetConfig {
|
||||||
importfn: string;
|
importfn: string;
|
||||||
rewritefn: string;
|
rewritefn: string;
|
||||||
metafn: string;
|
metafn: string;
|
||||||
|
setrealmfn: string;
|
||||||
wasm: string;
|
wasm: string;
|
||||||
shared: string;
|
shared: string;
|
||||||
worker: string;
|
worker: string;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue