Would it be possible to sandbox user-submitted Javascript by overriding various functions such as alert, window.location, and eval?
I'm not looking for a perfect solution. I'm sure some people would still find a way to rearrange divs to spell out swear words or something malicious, but if I could disable page redirects 100% reliably I would be mostly happy.
I tried in Chrome, and doing something like
context={}; //use this to prevent `this` from being `window`
context.f=function(){
var window=null,location=null,eval=function(){};
console.log(window); //also the other two
};
context.f();
seems promising. If I replace the console line with user-submitted code (checking for paren balancing), would that be an absurdly bad idea or a mildly bad idea? On Chrome I can still break things by going through this to Function and redefining things, but that would be acceptable to me.
You can use Microsoft Web Sandbox or Google Caja.
Here are two more possible solutions (disclaimer: I just started looking for this myself, so I am not an expert).
This is very interesting, uses web workers to sandbox untrusted code:
https://github.com/eligrey/jsandbox
even though, I wonder if that is maintaned anymore, or if the following html5 "sandbox" iframe attribute supersedes it:
http://www.w3schools.com/html5/att_iframe_sandbox.asp
vm.js is a javascript virtual machine implemented in pure coffeescript(should run in relatively old browsers) and can be used as a lightweight in-process sandbox. It can break infinite loops and shields global objects from modifications.
Depending on what this needs to do, you could always run the javascript in a document-context-free environment, like through Rhino, and then grab the results server-side and clean/insert those.
You could also try Douglas Crockford's AdSafe, though it does limit the possibilities of JavaScript.
Masking the globals with local variables is not secure actually. Preprocessing the untrusted code with tools like Google Caja may help, but it's not necessary:
For a web-browser simply running a code in a Worker is enough - it seems to be pretty restricted nowadays. See update below
For Node.js you may fork() in a sandboxed process and execute the code there (using the child_process module).
There are also some libraries for simplifying the sandboxing, one of those created by myself is Jailed (there's also a demo with JS-Console which executes user-submitted code in a sandbox).
Update: obviously I was wrong, the worker is not secure by itself, as it can access some of same-origin stuff, like IndexedDB for instance. I have submitted a related question. The solution is to additionally put the worker into a sasndboxed iframe, which is also implemented in my Jailed library.
Use HTML5 "sandbox" iframe attribute.
I made a javascript function for this.
function evalUnsafe(userCode) {
var vars = [];
var legal = {console: 'console', alert: 'alert'};
for(var b in this) {
if (!(b in legal)) {
vars.push(b);
}
}
var funcs = vars.join(",");
var code = "(function sandbox(" + funcs + ") {function runthis() {eval(" + JSON.stringify(userCode) + ");};var a = new runthis();})();";
eval(code);
}
And then you can do this
Example 1:
evalUnsafe("alert(window);");
Example 2 (from a php file):
evalUnsafe(<?php echo json_encode(file_get_contents("example.js"));?>);
You can download it from here:
https://github.com/oyvindrestad/javascriptsandbox
Related
I know that I can type into Chrome or FF the following command:
Object.keys(window);
but this displays DHTMLX stuff and also function names in which I'm not interested in. And it doesn't display variables in functions that have not been executed yet. We have more than 20,000 lines of JavaScript codebase, so I would prefer static code analyis. I found JavsScript Lint. It is a great tool but I don't know how to use it for displaying global vars.
So I'm searching for memory leaks, forgotten var keywords, and so on...
To do [only] what you're asking, I think you're looking for this:
for each (obj in window) {
if (window.hasOwnProperty(obj)) {
console.log(obj);
}
}
I haven't linted that code, which is unlike me, but you get the idea. Try setting something first (var spam = "spam";) and you'll see it reported on your console, and not the cruft you asked about avoiding.
That said, JLRishe is right; JSLint executes JavaScript in your browser without "phoning home", so feel free to run it. There are also many offline tools for JSLinting your code. I use a plugin for Sublime Text, for instance.
If you'd like some simplest-case html/JavaScript code to "wrap" JSLint, I've got an example here. Just download the latest jslint.js file from Crockford's repository into the same directory, and poof, you're linting with a local copy of JSLint.js. Edit: Added code in a new answer here.
Though understand that you're linting locally with that wrapper or when you visit JSLint.com. Honestly, I can say with some confidence, Crockford would rather not see our code. ;^) You download JSLint.js (actually webjslint, a minified compilation of a few files) from JSLint.com, but you execute in the browser.
(Admittedly, you're technically right -- you never know when that site could be compromised, and to be completely on the up and up, you sh/c/ould vet jslint.js each time you grab a fresh copy. It is safer to run locally, but as of this writing, you appear safe to use JSLint.com. Just eyeball your favorite browser's Net tab while running some test, non-proprietary code, and see if any phoning happens. Or unplug your box's network cable!)
Rick's answer to use "use strict"; is another great suggestion.
A great way to catch undeclared variables is to add 'use strict' to your code.
The errors will appear in the console, or you could display them in a try ... catch block:
'use strict';
try {
var i= 15;
u= 25;
} catch(ee) {
alert(ee.message);
}
I found a very good solution to list all the global variables with the jsl command line tool:
Here is the documentation
I just have to put /*jsl:option explicit*/ into each file that I want to check. Then it is enough to run ./jsl -process <someFile> | grep 'undeclared identifier'
It is also possible to use referenceFile that contains some intentional global variables /*jsl:import <referenceFile>*/ so these variables will not be listed.
So, here is the issue.
I have something like:
// Dangerous __hostObject that makes requests bypassing
// the same-origin policy exposed from other code.
(function(){
var danger = __hostObject;
})();
delete __hostOBject;
Am I perfectly safe knowing no script can tamper or access __hostObject?
( If they can, I have an CSRF vulnerability or worse. )
Note 1: This is for a browser extension. I have better hooks than other scripts running on the page. I execute before them and I'm done before they've even loaded.
Note 2: I know this has been asked multiple times for scripts in general. I'm wondering if it's possible if I know I load before any other scripts.
Provided that the __hostObject is deletable, the code in your question is safe.
However, I assume that your real code is slightly more complicated. In that case, very careful coding is required, because the page can change built-in methods (e.g. Function.prototype.call) to get into your closure and do whatever evil things they want. I had successfully abused functionality of extension frameworks such as Kango and Crossrider via this method when I performed such a test.
Won't simply adding a breakpoint and reloading the script expose your __hostObject
Original Question
This maybe a stupid question but is there a way in VS 2013 to unminify JavaScript?
Just making sure we are all on the same page here.
Minify:
var flashVer=-1;if(navigator.plugins!=null&&navigator.plugins.length>0){if(navigator.plugins["Shockwave Flash 2.0"]||navigator.plugins["Shockwave Flash"]){var swVer2=navigator.plugins["Shockwave Flash 2.0"]?"
That's just an example to make sure we all know what I'm on about. As far as I can tell there is no way to be able to do this. I have only been using VS 2013 for around 3 weeks so there is probably still stuff that is hidden to me.
If there is no way to do this within the program what is the next best thing for this?
I did see on another similar post that recommends the site http://jsbeautifier.org/ , so may have to give that ago but would make life easier if it was built into VS 2013
Thanks in advance as I know someone will be able to help me out here.
Update:
I have looked around VS 2013 and found nothing that can help me with this problem, like I said before they maybe some things I have missed (certain settings) so I guess if it cannot be done in VS what's the next best thing for the job? I seem to run into a fair amount of JS that is minifed and would like the quickest and best way to get the job done. I couple sites I have tried seem to have problems with it, is there a program I could install that would just allow me to short cut it with a hot-key or something. That would be pretty handy.
Update 2:
So I think its safe to say this cannot be done within VS2013, or for that matter at all due to missing var names and so on. So I have seen a few links and programs that allow you to format the code. Is there a way to do with within VS2013? And again if not what is the most reliable website/program that I can use to do this. Like I said I can see there have been answers and I appreciate all of them. I will be leaving this question open for a while to get more people to look at it and possibly give a better answer. Keep it up guys!
Update 3:
If anyone has any more information on this please do share. I am still looking around now and then waiting for someone to come up with something amazing for this. One day people.... One day!
The thing is that you cannot really "unminify" your code since some data was already lost - e.g. variable names. You can reformat it to more readable form though.
According to this question, since VisualStudio 2012 you can just use Ctrl+E, D keyboard shortcut
If the above is not right, there is this extension for VS 2010: http://visualstudiogallery.msdn.microsoft.com/41a0cc2f-eefd-4342-9fa9-3626855ca22a but I am not sure if it works with VS 2013
There is an extension to VisualStudio called ReSharper which can reformat javascript in a few different manners.
Also there are online formatters already mentioned in other answers (if your code is confidential, I would advise some paranoia manifested by downloading sources and using them locally).
Also you may always try to find unminified version of desired library on the interwebs
Also, there is the WebStorm IDE from JetBrains that is able to reformat JS - you may download a trial for the sole purpose of reformatting your minified scripts :)
If that's just to make debugging easier, you may want to use source maps
Also, here is a bunch of related questions:
How to automatically indent source code? <-- this is for VS2010, but it looks promising, maybe it will help you if it supports JavaScript (and it does since VS2012 according to MS support):
Ctrl+E, D - Format whole doc
Ctrl+K, Ctrl+F - Format selection
reindent(reformat) minimized jquery/javascript file in visual studio
Visual Studio 2010 can't format complex JavaScript documents
Visual Studio code formatter
how to make visual studio javascript formatting work?
I am not sure if they figured out a working way to reformat JS, but I've seen a few answers which might be helpful - I am just pasting this in here just FYI.
Added 03.06.2014:
http://www.jsnice.org/
This tool could be useful too, it even tries to infer minified names. As stated on their website:
We will rename variables and parameters to names that we learn from thousands of open source projects.
Personally I can't think of a reason to ever unminify code^:
If you're using a compiled js file (a-la google closure) and want more readable code to debug, use source maps available for well-supported libraries (speaking of jQuery, if it is served from a google CDN it already maps to the correct source)
If you're using a whitespace-only minified js file and want more readable code to debug, you could just toggle pretty print in-browser. This seems to best fit your question.
If you're using either of the above and want to modify the source code for a third-party js file, don't. Any future release will cancel out your change - instead consider one of the many patterns to extend a framework (or, perhaps, do some duck punching depending on the exact scenario.)
The other answers seem to cover the "unminification" process (maxification?) well, but it's worth making sure it's a necessary step first.
^ - Except when version control falls over, there are no backups and the only version of the file left is a minified copy in browser cache. Don't ask.
Its just a one way transformation .... sorry in normal cases you will not get something understandable back from minified JavaScript !
Make just a quick look at JQuery source for a second:
(function( window, undefined ) {
// Can't do this because several apps including ASP.NET trace
// the stack via arguments.caller.callee and Firefox dies if
// you try to trace through "use strict" call chains. (#13335)
// Support: Firefox 18+
//"use strict";
var
// The deferred used on DOM ready
readyList,
// A central reference to the root jQuery(document)
rootjQuery,
// Support: IE<10
// For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
core_strundefined = typeof undefined,
// Use the correct document accordingly with window argument (sandbox)
location = window.location,
document = window.document,
docElem = document.documentElement,
// Map over jQuery in case of overwrite
_jQuery = window.jQuery,
// Map over the $ in case of overwrite
_$ = window.$,
// [[Class]] -> type pairs
class2type = {},
// List of deleted data cache ids, so we can reuse them
core_deletedIds = [],
core_version = "1.10.2",
------
And now at the minify source:
(function(e,t){var n,r,i=typeof t,o=e.location,a=e.document,s=a.documentElement,
l=e.jQuery,u=e.$,c={},p=[],f="1.10.2", ....
I think now you see it =>
window => e
undefined => t
readyList => n
rootjQuery => r
core_strundefined => i
location => o
document => a
So its mapped somehow to make it more shorter look here to minify something
People normally use this so there is no way back
you can just format it look here
If the code has only been minified then the best you can do automatically is reformat to make it more readable. One way of doing this is using an online formatter/beautifier. E.g. Copy and paste the line of code you posted into http://jsbeautifier.org/ or http://www.jspretty.com/ and it'll produce something like this:
var flashVer = -1;
if (navigator.plugins != null && navigator.plugins.length > 0) {
if (navigator.plugins["Shockwave Flash 2.0"]
|| navigator.plugins["Shockwave Flash"]) {
var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? ""
But of course what these don't do is put any comments that have been removed by the minifier back in. And if the code has also been obfuscated then it will be a lot less readable since the variable names will have changed (e.g. var a instead of var flashVer). See here for further details.
As you can see from the other answers, there is no way to reconstitute minified Javascript back into its original form, it is a lossy compression. The best you can do is make it readable by reformatting it.
If the code is open source, then it is likely that the code will exists in a raw state on some form of version control site or as a zip. Why not just download the raw version if available?
There is an online tool to unminify Javascripts
http://jsbeautifier.org/
And also for CSS
http://mrcoles.com/blog/css-unminify/
Both firebug and the built in console in webkit browsers make it possible to set breakpoints in running Javascript code, so you can debug it as you would with any other language.
What I'm wondering is if there is any way that I can instruct firebug or webkit that I'd like to set a breakpoint on line X in file Y at runtime, and to be able to examine variables in the specific scope that I have paused in.
I need something that can work in both Chrome (or any other webkit browser) and Firefox. For the latter Firebug is an acceptable dependency. Supporting IE is not a requirement.
I've been building an in-browser IDE ( quick video for the interested: http://www.youtube.com/watch?v=c5lGwqi8L_g ) and want to give it a bit more meat.
One thing I did try was just adding debugger; as an extra line where users set them, but this isn't really an ideal solution.
I'd say you can definitely do this for webkit browsers using the remote debugging protocol. This is based on a websocket connection and a json message protocol that goes back and forth.
You can read the announcement and the whole protocol schema.
Chrome also offers more information about this inside its remote developer-tools docs.
For the debugger domain, for instance, you can see how you can use Debugger.setBreakpoint, Debugger.setBreakpointByUrl and Debugger.setBreakpointsActive to work with breakpoints.
On the other hand, Mozilla also seems to be working on this as you can see in https://developer.mozilla.org/en-US/docs/Tools/Debugger-API and https://wiki.mozilla.org/Remote_Debugging_Protocol though I don't know the completion status of it.
In this case, you can work with breakpoints using the Debugger.Script APIs setBreakPoint, getBreakPoint, getBreakpoints, clearBreakpoints and clearAllBreakpoints
I hope this helps you move forward.
There isn't such a thing, at least not using the public, scriptable side of JavaScript. It would be possible if you have a privileged browser extension that could do that for you. For example, Firebug has a debug method which you can call from its command line, but not from scripts inside a page.
So, you have two solutions:
Implement your own JavaScript interpreter, which you can control as you wish. Might be a bit too ambitious, though...
Rely on a browser extension that can set breakpoints anywhere in the code, expose some API to public code, and interact with it from your JavaScript. But that means that users will have to install some extra piece of software before they can use your "Web IDE".
Use _defineSetter__ to watch variables, and combine it with a call to debugger when an assignment happens.
__defineSetter__("name", function() { debugger; });
or defineProperty:
function setter () { debugger; }
Object.defineProperty(Math, 'name', { set: setter });
References
MDN: Object.defineProperty
A List Apart: Advanced Debugging With JavaScript
JavaScript Getters and Setters
Where I work, all our JavaScript is run through a compiler before it's deployed for production release. One of the things this JavaScript compiler does (beside do things like minify), is look for lines of code that appear like this, and strip them out of the release versions of our JavaScript:
//#debug
alert("this line of code will not make it into the release build")
//#/debug
I haven't look around much but I have yet to see this //#debug directive used in any of our JavaScript.
What is it's possible usefulness? I fail to see why this could ever be a good idea and think #debug directives (whether in a language like C# or JavaScript) are generally a sign of bad programming.
Was that just a waste of time adding the functionality for //#debug or what?
If you were using a big JavaScript library like YUI that has a logger in it, it could only log debug messages when in debug mode, for performance.
Since it is a proprietary solution, we can only guess the reasons. A lot of browsers provide a console object to log various types of messages such as debug, error, etc.
You could write a custom console object is always disabled in production mode. However, the log statements will still be present, but just in a disabled state.
By having the source go though a compiler such as yours, these statements can be stripped out which will reduce the byte size of the final output.
Think of it as being equivalent to something like this:
// in a header somewhere...
// debug is off by default unless turned on at compile time
#ifndef DEBUG
#define DEBUG 0
#endif
// in your code...
var response = getSomeData({foo:1, bar:2});
#if DEBUG
console.log(response);
#endif
doStuffWith(response);
This kind of thing is perfectly acceptable in compiled languages, so why not in (preprocessed) javascript?
I think it was useful (perhaps extremely useful) back a few years, and was probably the easiest way for a majority of developers to know what was going on in their JavaScript. That was because IDE's and other tools either weren't mature enough or as widespread in their use.
I work primarily in the Microsoft stack (so I am not as familiar with other environments), but with tools like VS2008/VS2010, Fiddler and IE8's (ugh! - years behind FF) dev tools and FF tools like firebug/hammerhead/yslow/etc., peppering alerts in your JavaScript isn't really necessary anymore for debugging. (There's probably a few instances where it's useful - but not nearly as much now.) Able to step through JavaScript, inspect requests/responses, and modify on the fly really makes debugging alert statements almost obsolete.
So, the //#debug was useful - probably not so much now.
I've used following self-made stuf:
// Uncomment to enable debug messages
// var debug = true;
function ShowDebugMessage(message) {
if (debug) {
alert(message);
}
}
So when you've declared variable debug which is set to true - all ShowDebugMessage() calls would call alert() as well. So just use it in a code and forget about in place conditions like ifdef or manual commenting of the debug output lines.
For custom projects without any specific overridden console.
I would recommend using: https://github.com/sunnykgupta/jsLogger , it is authored by me.
Features:
It safely overrides the console.log. Takes care if the console is not available (oh yes, you need to factor that too.)
Stores all logs (even if they are suppressed) for later retrieval.
Handles major console functions like log, warn, error, info.
Is open for modifications and will be updated whenever new suggestions come up.