pionxzh / wakaru

🔪📦 Javascript decompiler for modern frontend
https://wakaru.vercel.app/
MIT License
228 stars 11 forks source link

[module-detection] js-xss #80

Open 0xdevalias opened 7 months ago

0xdevalias commented 7 months ago

This relates to the 'module-detection' feature described in the following issue:

Overview

Code

Unminifying this source (Ref):

Original (prettified) - https://github.com/0xdevalias/chatgpt-source-watch/blob/e2b8c1d5cec79c7f48f81f93b4ee83d42e549a86/unpacked/_next/static/chunks/pages/_app.js#L55420-L55441 ```js // unpacked/_next/static/chunks/pages/_app.js, lines 55420-55441 138: function (U, B, G) { var Y = G(56855), V = G(43310), Z = G(91611); function J(U, B) { return new Z(B).process(U); } ((B = U.exports = J).filterXSS = J), (B.FilterXSS = Z), (function () { for (var U in Y) B[U] = Y[U]; for (var G in V) B[G] = V[G]; })(), "undefined" != typeof window && (window.filterXSS = U.exports), (function () { return ( "undefined" != typeof self && "undefined" != typeof DedicatedWorkerGlobalScope && self instanceof DedicatedWorkerGlobalScope ); })() && (self.filterXSS = U.exports); }, ```
Source (unpacked) ```js // module-138.js var Y = require(56855); var V = require(43310); var Z = require(91611); function J(U, B) { return new Z(B).process(U); } ((exports = module.exports = J).filterXSS = J), (exports.FilterXSS = Z), (function () { for (var U in Y) exports[U] = Y[U]; for (var G in V) exports[G] = V[G]; })(), "undefined" != typeof window && (window.filterXSS = module.exports), (function () { return ( "undefined" != typeof self && "undefined" != typeof DedicatedWorkerGlobalScope && self instanceof DedicatedWorkerGlobalScope ); })() && (self.filterXSS = module.exports); ```

Transformed (unminified)

// module-138.js
import Y from "module-56855.js";
import V from "module-43310.js";
import Z from "module-91611.js";

export function filterXSS(U, B) {
  return new Z(B).process(U);
}

exports = filterXSS;
export default filterXSS;

(() => {
  for (const U in Y) {
    exports[U] = Y[U];
  }
  for (const G in V) {
    exports[G] = V[G];
  }
})();

if (typeof window != "undefined") {
  window.filterXSS = module.exports;
}

if (
  (() =>
    typeof self != "undefined" &&
    typeof DedicatedWorkerGlobalScope != "undefined" &&
    self instanceof DedicatedWorkerGlobalScope)()
) {
  self.filterXSS = module.exports;
}

Searching for some of those symbols on GitHub code search:

Of those results, this looks the most promising:

// js-xss/lib/index.js, lines 7-51
var DEFAULT = require("./default");
var parser = require("./parser");
var FilterXSS = require("./xss");

function filterXSS(html, options) {
  var xss = new FilterXSS(options);
  return xss.process(html);
}

exports = module.exports = filterXSS;
exports.filterXSS = filterXSS;
exports.FilterXSS = FilterXSS;

(function () {
  for (var i in DEFAULT) {
    exports[i] = DEFAULT[i];
  }
  for (var j in parser) {
    exports[j] = parser[j];
  }
})();

if (typeof window !== "undefined") {
  window.filterXSS = module.exports;
}

function isWorkerEnv() {
  return (
    typeof self !== "undefined" &&
    typeof DedicatedWorkerGlobalScope !== "undefined" &&
    self instanceof DedicatedWorkerGlobalScope
  );
}
if (isWorkerEnv()) {
  self.filterXSS = module.exports;
}

Based on the above, it looks like the following modules (in this bundle) are also related to js-xss:

Note: I haven't traced the related imports beyond the first level detailed above, but that would be useful to do to fully identify the related modules from this library (or it's dependencies).

pionxzh commented 7 months ago

I would lower the priority of this a bit because it won't change how we unminify the code.

0xdevalias commented 7 months ago

I would lower the priority of this a bit because it won't change how we unminify the code

@pionxzh nods definitely doesn't need to be high priority at all. I just wanted to make sure to document some of the modules I identify manually to help add to the more general 'module detection' feature #41; and I figured it was probably better to keep them separate from the main thread.

Let me know if this sort of thing isn't useful, or if you'd prefer it be done in a different way or similar too.

0xdevalias commented 7 months ago

Using the madge CLI/lib that I mentioned in another issue (Ref), I was able to automatically find/generate a graph of all of the module dependencies related to this.

Note that I could have narrowed down on this by first creating a larger image of all the dependencies in a chunk/etc, finding something that looked like a lib like this, then running it again on that module.

Note also that I haven't manually checked through all of the modules mentioned here yet, but I suspect that at least one of them will likely be app/another libraries code unrelated to this module (though since I haven't unpacked the full bundle, maybe that code will be in another chunk and not represented here too)

.madgerc ```jsonc // See: https://github.com/pahen/madge#configuration { "fileExtensions": ["js"], "detectiveOptions": { "es6": { "mixedImports": true, "skipTypeImports": true }, "ts": { "mixedImports": true, "skipTypeImports": true } } } ```
⇒ npx madge --image 138.svg stage3-unminified/pages/_app/module-138.js

(blue has dependencies, green doesn't)

138

madge --json output ```bash ⇒ npx madge --json stage3-unminified/pages/_app/module-138.js { "module-12665.js": [], "module-138.js": [ "module-43310.js", "module-56855.js", "module-91611.js" ], "module-25766.js": [ "module-50694.js", "module-53140.js" ], "module-40101.js": [ "module-25766.js", "module-53140.js" ], "module-43310.js": [ "module-12665.js" ], "module-50694.js": [ "module-66380.js" ], "module-53140.js": [], "module-56855.js": [ "module-12665.js", "module-40101.js" ], "module-66380.js": [], "module-91611.js": [ "module-12665.js", "module-40101.js", "module-43310.js", "module-56855.js" ] } ```