kevin-mizu / domloggerpp

A browser extension that allows you to monitor, intercept, and debug JavaScript sinks based on customizable configurations.
https://x.com/kevin_mizu
GNU General Public License v3.0
395 stars 35 forks source link

DomLogger++ doesn't detect sink in [https://public-firing-range.appspot.com/address/index.html] #10

Open sazoukis opened 2 months ago

sazoukis commented 2 months ago

Not sure why, but when testing https://public-firing-range.appspot.com/address/index.html with DomLogger++ and using Dom Invader config, it doesn't detect the common sinks when the source is location.hash

kevin-mizu commented 2 months ago

Hey 👋

Thanks for reporting it! As discussed on Twitter, the JavaScript injection in the extension takes about 15-20ms, which is too much for an inline script at the top of a document :(

For readers, no worries, it doesn't impact an inline script in the middle of the document (e.g., https://mizu.re/) or a script loaded via src.

I'm currently working on a fix, but it's super hard because I'm dependent on how browser extensions work. If anyone has an idea on how to fix this, please do not hesitate to propose :D

kevin-mizu commented 1 month ago

Hey @sazoukis :wave:

I was thinking about how to properly fix this issue, but I haven't found a clean solution yet. The fact that the extension script gets overridden by the page loading isn't something I can address at the extension level.

However, an interesting point is that scripts loaded by the DOM and scripts loaded by the extension aren't in the same queue. This means that a potential solution could be to replace with on all the in-scope response documents.

For example:

  1. Expose a server that returns an empty no-cache response (this is really important to force the browser to fetch it every time). In PHP, this can be done like this:
header("Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate");
header("Pragma: no-cache");
header("Expires: 0");
header("Surrogate-Control: no-store");
  1. On Burp, set up a match-and-replace rule that loads the associated script (make sure not to use your own file to avoid leaking sensitive information to your server!):

image

  1. Go to the page, and it should work properly now :)

URL: https://public-firing-range.appspot.com/address/location.hash/eval#1+1

Config:

{
  "hooks": {
    "EVAL": {
      "function": [
        "eval"
      ]
    }
  },
  "config": {},
  "removeHeaders": [
    "content-security-policy",
    "x-frame-options"
  ]
}

image

I will try to find a better way to fix this, but it should work fine for the moment :D

Cheers, Kévin.