So for a long time now I have been under the assumption that, while it does performance gains, one of the primary reasons we minify javascript/css is to give a modicum of obfuscation to it so that it is harder to reverse engineer.
However a friend of mine just showed me how it is not only possible; but extremely simple to just reverse minification on minified javascript and css.
So my question is - other than performance gains, what is the point? Is there any other actual way to protect javascript from being simply stolen right from your site?
Javascript minification is done primarily to increase performance. Upon minification, it's not uncommon to see >25% reduction in script size. On top of this, some minify-ers/compilers will obfuscate your code a little as well, renaming functions and variables to less obvious names.
As you've pointed out, it can always been unminified or pretty-printed, but since Javascript is a non-compiled, client-side language there isn't a whole lot you can do to protect your javascript.
See this link on javascript obfuscation.
If you have proprietary code or code you really don't want users seeing, you'll have to keep it server side. Consider moving it to a server side language such as PHP, Python, C, etc and expose the functions via web services.
There is no way to prevent javascript from being stolen directly off your site. It is "stolen" the instant someone visits your site and loads the HTML page or file containing the javascript code. Minification will do nothing more from a security perspective than obfuscate your code from a casual browser. It's primary purpose is for performance.
Rule of thumb: If you don't want the user to have access to it, don't send it to the client/browser.
Related
What is the difference between obtrusive and unobtrusive javascript - in plain english. Brevity is appreciated. Short examples are also appreciated.
No javascript in the markup is unobtrusive:
Obtrusive:
<div onclick="alert('obstrusive')">Information</div>
Unobtrusive:
<div id="informationHeader">Information</div>
window.informationHeader.addEventListener('click', (e) => alert('unobstrusive'))
I don't endorse this anymore as it was valid in 2011 but perhaps not in 2018 and beyond.
Separation of concerns. Your HTML and CSS aren't tied into your JS code. Your JS code isn't inline to some HTML element. Your code doesn't have one big function (or non-function) for everything. You have short, succinct functions.
Modular.
This happens when you correctly separate concerns. Eg, Your awesome canvas animation doesn't need to know how vectors work in order to draw a box.
Don't kill the experience if they don't have JavaScript installed, or aren't running the most recent browsers-- do what you can to gracefully degrade experience.
Don't build mountains of useless code when you only need to do something small. People endlessly complicate their code by re-selecting DOM elements, goofing up semantic HTML and tossing numbered IDs in there, and other strange things that happen because they don't understand the document model or some other bit of technology-- so they rely on "magic" abstraction layers that slow everything down to garbage-speed and bring in mountains of overhead.
Separation of HTML and JavaScript (define your JavaScript in external JavaScript files)
Graceful degradation (important parts of the page still work with JavaScript disabled).
For a long-winded explanation, checkout the Wikipedia page on the subject.
To expand on Mike's answer: using UJS behavior is added "later".
<div id="info">Information</div>
... etc ...
// In an included JS file etc, jQueryish.
$(function() {
$("#info").click(function() { alert("unobtrusive!"); }
});
UJS may also imply gentle degradation (my favorite kind), for example, another means to get to the #info click functionality, perhaps by providing an equivalent link. In other words, what happens if there's no JavaScript, or I'm using a screen reader, etc.
unobtrusive - "not obtrusive; inconspicuous, unassertive, or reticent."
obtrusive - "having or showing a disposition to obtrude, as by imposing oneself or one's opinions on others."
obtrude - "to thrust (something) forward or upon a person, especially without warrant or invitation"
So, speaking of imposing one's opinions, in my opinion the most important part of unobtrusive JavaScript is that from the user's point of view it doesn't get in the way. That is, the site will still work if JavaScript is turned off by browser settings. With or without JavaScript turned on the site will still be accessible to people using screen readers, a keyboard and no mouse, and other accessibility tools. Maybe (probably) the site won't be as "fancy" for such users, but it will still work.
If you think in term's of "progressive enhancement" your site's core functionality will work for everybody no matter how they access it. Then for users with JavaScript and CSS enabled (most users) you enhance it with more interactive elements.
The other key "unobtrusive" factor is "separation of concerns" - something programmers care about, not users, but it can help stop the JavaScript side of things from obtruding on the users' experience. From the programmer's point of view avoiding inline script does tend to make the markup a lot prettier and easier to maintain. It's generally a lot easier to debug script that isn't scattered across a bunch of inline event handlers.
Even if you don't do ruby on rails, these first few paragraphs still offer a great explanation of the benefits of unobtrusive javascript.
Here's a summary:
Organisation: the bulk of your javascript code will be separate from your HTML and CSS, hence you know exactly where to find it
DRY/Efficiency: since javascript is stored outside of any particular page on your site, it's easy to reuse it in many pages. In other words, you don't have to copy/paste the same code into many different places (at least nowhere near as much as you would otherwise)
User Experience: since your code can is moved out into other files, those can be stored in the client side cache and only downloaded once (on the first page of your site), rather than needing to fetch javascript on every page load on your site
Ease of minimization, concatenation: since your javascript will not be scattered inside HTML, it will be very easy to make its file size smaller through tools that minimise and concatenate your javascript. Smaller javascript files means faster page loads.
Obfuscation: you may not care about this, but typically minifying and concatenating javascript will make it much more difficult to read, so if you didn't want people snooping through your javascript and figuring out what it does, and seeing the names of your functions and variables, that will help.
Serviceability: if you're using a framework, it will probably have established conventions around where to store javascript files, so if someone else works on your app, or if you work on someone else's, you'll be able to make educated guesses as to where certain javascript code is located
I am thinking about creating mini-games in JavaScript that a public social website (yourworldoftext.com) and I had a thought, I am a user of the site and would be embedding my JavaScript in a link's href that others can click on to start the game.
One way I was thinking about would be something like this
Compress/obfuscate the JavaScript as much as possible
Encrypt the JavaScript into a sctring and wrap everything with a small decryption JavaScript that will evaluate the decrypted string (the key to decrypt would be retrieved using AJAX from some other page on the same site)
Here is my motivation:
people should all be using the same version of the game and its not trivial to cheat
The source code contains hacks that might be easy for a JavaScript developer like me to write, but potentially the code could be copy pasted and misused to spam the site
The informed spammer could find any number of scripts already available for free online, I just don't want it to be free from my scripts
I want anyone to be able to run the app without any hidden secret to know (which would make having the script publicly available meaningless because then I'd just share the game those I trusted making the script itself the secret)
Don't misunderstand me, I know there is absolutely no way to ensure that the source code behind the JavaScript would not be available to the informed/intelligent user, I am merely polling to see if this is an exercise in futility and I shouldn't even bother with the extra encryption step, or if any believe that there is some merit to this technique.
I am inclined to believe that it might thwart the casual user, I'm just not sure how much knowledge would be required to break it, if maybe the casual social network user could break it.
Also, I suspect that firebug, developer tools, web inspector will just show the evaluated code anyway, but I'm not sure. If so then it wouldn't really do anything at all to protect it. Most users on the site use chrome (from what I hear because it works best on that browser). So would chrome show it easily in the web inspector?
Minification and obfuscation and encryption as you've described are all minor obstacles in the way of people mucking with your code. Each minor obstacle will discourage a small number of would-be hackers. But, none of the three will discourage the determined hacker.
All one has to do to get around the encryption is set a breakpoint in the debugger and capture the code right after it's been decrypted before it's sent to eval and then copy/paste out of the debugger. So, it barely even slows down the determined hacker. In fact, minification (replacing all meaningful variable names with meaningless short names actually creates more work for the hacker in understandong your code).
Personally, I'd avoid the encryption as it doesn't really add much and it's real easy for the determined hacker to get around.
You're right, this is futile. Don't bother with this at all. Your code, although minified and obfuscated can be lifted by users with little knowledge.
Is there any way/reason to keep your js/jQuery ouside public_html? Are there security benefits?
All javascript is readable no matter where you put it on your server. The best you can do is obfuscate it:
How can I obfuscate (protect) JavaScript?
Plus, jQuery is open source, so there is no benefit of storing it any place in particular.
JavaScript is code that is executed by your visitor's browsers so it must be public. It is good practice to compress your JavaScript code because it will require less bandwidth to transfer and it will make it harder for other to read it (i.e. figure out how to exploit it). Yahoo offers a free JavaScript compressor.
Is there any reasons to keep your JavaScript outside public_html?
It allows for a more optimized server-side and client-side caching of the resources.
It allows for a more parallelized download of the resources from the server by the client.
It makes it easier for you to separate your UI's presentational layer (your HTML code) from its controls and logic layer (your JavaScript code), which also means:
It makes it easier for you to manage.
It's easier to share across your team (you won't have designers and developers working on the same pieces of code, and you separate functionalities in smaller resources (even if you compile them together for a production server).
As a result of this, the design of your JS code will most probably be more prone to testability.
It also allows you to not load some bits and pieces you may not need all the time. It thus also facilitates code reuse for some of these bits when they're needed somewhere else, without having to duplicate them in other huge files of stuff put together.
Is there any ways to keep your JavaScript outside public_html?
Sure. Just put the code in a external JS files and inject them normally using script tags. Or inline them with your build script or template engine. Be sure to decouple your HTML from your JS (no ugly JS injected directly with on<something>=javascript:doThisOrThat() in your tags) and to use more standard and robust methods instead (use a system compliant with the W3C DOM Level 2 Event model. jQuery is very practical for this anyway, as it's designed with progressive enhancement in mind).
Are there security benefits?
Short answer: no. But you have a clear increase in code quality, which would be easily relating to your overall security. But having your JS within the same file is not a security flaw. If what you meant is that you're concerned about your JS code being visible by visitors, as other answers already mentioned: you cannot do anything it about this. You can make it harder and more painful to look at (via obfuscation), but this won't prevent someone who really wants to to dig into your code. My recommendation: don't waste your time and efforts on that.
Unless it's in a writable location (which it shouldn't be), no.
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
I understand that client side code must be readable from the browser but I wonder (since there are too many things that I ignore) if there are ways to obfuscate to code to the end user and, if not what is the best practice to "pack" the javascript code.
It is good practice to minify your JS with a tool such as YUI Compressor. I would not obfuscate it unless you have a specific need to do this. There are plenty of online obfuscators such as this one
See this article: http://developer.yahoo.net/blog/archives/2007/07/high_performanc_8.html
Check this out.
Other than min'ing it, I don't think you can really hide js. It all goes the user's browser and there are plenty of ways of seeing it once its there.
See here for a Free Javascript Obfuscator.
Given that it is in fact possible, if the reason you intend to obfuscate is to protect intellectual property, you are probably trying to derive value from your work the wrong way. It's fairly easy to reverse the obfuscation, and you would probably be wasting time maintaining your code.
Focus more on what services you intend to provide to those who visit your site as a means to differentiate your site from competitors
There are tools that could be used to compress javascript code and render it difficult for the end user to understand.
Is there a reason why this won't do the trick for you?
http://www.javascriptobfuscator.com/
Do not put any sensitive or personal information in javascript.
Spend your time on keeping your data on the server secure.
Step 1: Don't.
You would have to do a lot to achieve any meaningful level of obfuscation. Obfuscating the names alone is not enough, since all of the standard functions will still be there (although they may be buried in a layer of shorter/obfuscated aliases), and deriving the purpose of a particular function is easy once the code is formatted nicely again. Anybody who really wants to know what your JS code does can, and will, no matter what you do to it before their browser gets a copy of it.
If you truly have valuable business processes in your JavaScript, then you're Doing It Wrong(tm).
No obfuscation is going to keep your code truly secure and it might just give you the false illusion of security (cf. security by obscurity).
If you do need to keep some portion of your code secret, consider pulling the sensitive portions into a server side script and making (say) AJAX calls to the script. Especially with the advent of JSON, communicating with server-side scripts has never been easier.
It is possible to use following tools:
YUI Compressor - requires Java - very good compressor
Packer - creates the most confusing, and smallest code, but scripts don't run as fast as YUI - this can be used online though. Select 'Base62 encode' for maximum effect.
The Dojo Compressor I've never used this one, but it's on the top-list. It also requires Java.
JSMIN By Douglas Crockford, this one has a very simple algorythm, but it is still good. Meant to be used in combination with JSLint.