24

I sometimes want to run untrusted JavaScript, mainly for CTFs. It can be obfuscated JavaScript code or something like JSFuck. The point is, I know nothing about the code and just want to quickly see its output.

Of course, I don't want the JavaScript code to affect the other open pages/tabs. We can assume no exploit is available for the JavaScript interpreter/compiler/browser. Of course, I can do static analysis on the code, but that takes a lot of time and I may prefer to do dynamic analysis and just look at the output.

What's a good way to run arbitrary JavaScript code?

7
  • 2
    The answers below by mentallurg and CBHacking do a good job of describing some of the possible threats (more-or-less in increasing order of paranoia) and what you can do to mitigate those threats. As expected, the more paranoid you are, the more effort it takes to mitigate. If you are really paranoid, you might be best off firing up a spare computer using a Ubuntu (or the distro of your choice) live-bootable USB, and opening the web page using the browser there. – mti2935 Dec 28 '20 at 13:38
  • 1
    Fire up a virtual machine and run it in a browser. Beware though, the JS might seem innocuous because you haven't triggered the correct environment for it to misbehave so it could very well behave differently in your main browser. – MonkeyZeus Dec 28 '20 at 15:00
  • Put a breakpoint on the script and step through it line by line with a debugger if it's reasonably short and you just want to understand what's going on. – Bergi Dec 28 '20 at 21:40
  • 7
  • 2
    @PeterMortensen en.wikipedia.org/wiki/Capture_the_flag#Computer_security – Dan M. Dec 29 '20 at 16:45
31

It depends on what risks are acceptable for you. For some people running browser with a separate profile is sufficient. Some would run it within a separate Docker container. The others would run it within a virtual machine like VMware, Virtual Box or QEMU.

2
  • 3
    Or on separate (physical) hardware? On an isolated network or DMZ? – Peter Mortensen Dec 29 '20 at 16:14
  • 26
    @PeterMortensen on a brand new Raspberry Pi with the wi-fi chip removed in a Faraday cage connected to a generator which you incinerate after using? – user253751 Dec 29 '20 at 18:28
19

Assuming no exploits exist for the browser - which is a dangerous assumption in some ways, but is also kind of the default assumption any time we load a web page with scripting enabled - just use a private/incognito window and the browser's dev tools, on a page with no origin of interest ([[about:blank]] or similar usually works fine).

That way, the script can't leverage any stored tokens (cookies, etc.) to learn anything about your browsing or to attack any sites you're signed into with XSS or CSRF or similar. It already couldn't read responses or page content from other sites; the dev tools are still subject to same-origin policy. It can send requests (potentially exposing your IP address, user-agent string, and similar), but they will be otherwise anonymous and it can't access the responses.

5
  • 3
    1) private/incognito does not make much difference for script analysis. 2) "it can't access the responses" - this is not quite correct, it can be true only for web sites that require same origin. Many web sites allow intentionally arbitrary origins. – mentallurg Dec 28 '20 at 17:11
  • 2
    @mentallurg 1) private/incognito prevents cookies and saved data change/read. 2) That's true for every website. – Ray Wu Dec 28 '20 at 19:16
  • 1
    @mentallurg ACAO:* isn't that common. It also just does not work for authenticated requests (which these of course aren't going to be if you use incognito). But yes, the script would (probably) be able to see those responses (unless using an About page as the origin means the origin is treated as null in which case even * might not match). That's almost certainly not a security threat, though; the attacker could make the same request (and get the response) from their own machine, differing only in source IP. – CBHacking Dec 28 '20 at 19:21
  • 4
    Thea ability to make requests is a powerful tool. For example, it may scan your local subnet for potentially vulnerable devices accessible over http(s) (e.g. printer, router or IoT device admin pages) and send the outputs of the scan to an attacker, thus providing them access to things that aren't accessible from public internet because the network connections are running from your workstation. It's plausible to spray default credentials at such devices (often unsecured because they are accessible only from "inside") and automatically exploit them from such javascript. – Peteris Dec 29 '20 at 8:59
  • A "throw away" profile on Firefox would be better. But a low depends on what sort of output and interaction OP expects from the script... zhe doesn't explicitly say that it requires a browser-like DOM. – Mark Morgan Lloyd Dec 29 '20 at 19:46
4

Javascript is meant to allow local execution of non controlled code (*). Said differently, either you trust your browser to contain no breach (and you are brave because I would not) or you trust the server to only contain harmless code.

In any other case, my advice would be to use a dedicated virtual machine, take a snapshot before consulting the possibly unsafe page, and restore the snapshot after. Unless you are facing an attack targetting your virtual machine engine any action caused by javascript should be rolled back by restoring the snapshot.


(*) On a strict security point of view, that means that javascript should be disabled when consulting pages for non controlled sites. Unfortunately few modern sites can be consulted that way...

2
  • I googled "non controlled code" to find out what you mean by this term, and the first result was this answer. Could you provide an alternative term, or give a definition? – Jaap Joris Vens Jan 5 at 21:01
  • 1
    What I mean here is that the Javascript code that runs inside a browser is under the exclusive control of the server and that the client has little to no control on it (at most the sandbox of the browser), while the code uses and/or accesses the client resources. – Serge Ballesta Jan 7 at 15:11
2

The simplest and cleanest approach would be to Dockerize your testing platform. The ability to quickly spin up containers with the requisite testing frameworks, libraries, utilities, and code, and then bang on the target code and applications in an isolated fashion is very powerful. And this will minimize your blast radius to unintended consequences, which is even more crucial when dealing with unsafe/untrusted code.

And if containers don't satisfy all or your needs, then VMs either locally with something VirtualBox or remotely with one of the cloud providers is always an option. With a DevOps mindset, I try to think about situations like this sort of problem in terms of clean, repeatable, safe, automated solutions. Being able to throw away things and easily recreate and tailor them as needed is a model to strive for.

-1

If you're talking about what I think you're talking about, have a look at "Workers". JavaScripts running in a Worker don't have access to the DOM and are isolated. https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers

3
  • 13
    You could improve this answer by elaborating on what "I think you're talking about" means. – DoYouEvenCodeBro Dec 28 '20 at 22:18
  • 5
    Workers srill do send HTTP cookies they are still same origin and are not "isolated", apart from running on an other thread. They still leak many fingerprint info and even have access to IndexedDB. All in all, they just prevent writing something on the page, they don't prevent doing harm. – Kaiido Dec 28 '20 at 23:49
  • 3
    Can you reveal more about "what I think you're talking about"? Please respond by editing your question, not here in comments (without "Edit:", "Update:", or similar). – Peter Mortensen Dec 29 '20 at 16:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.