Security and JavaScript files containing a site's logic - javascript

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

Related

Is JavaScript source encryption useful for obfuscation?

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 it possible to hack with javascript? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I'm familiar with the term hacking. Although i never will become one of those hackers who scam people or make trouble, i believe it's an essential aspect any person who calls themselves a programmer must be able to do, as it is mainly about problem solving. But how does it work? When those people hack games or websites or the guy who hacked sony, do they use a programming langauge like ANSI C or c++ or assembly. Assuming they use a programming language, would it be possible to use javascript to hack in the same way you'd use any other language to hack. Furthermore, what do you have to do to be able to hack too. I just wanna know how it works, and the theory behind it all.
Hacking is unique every time. Exploiting some types of vulnerability doesn't require any particular language at all. Sometimes you hack whatever's there, in whatever language or form you find it. Sometimes it's necessary to automate part of the process, for example password cracking, for which you can use any language you like.
Cracking a commercial game commonly involves studying its disassembled machine code, figuring out which part does the CD or license check, and surgically replacing a few bytes of the code such that the check is skipped.
Hacking a website commonly involves discovery of some small clumsiness on the part of its developers, which allows viewing of should-be private data, or permits execution of custom code if it does not sanitize data properly. SQL injection is a common flaw when values sent to a database are not properly protected within quotes ("...") and so you can give values which break out of the quotes to execute your own commands. Cross-site scripting is a type of hack that uses JavaScript: If a website blindly takes parameters from the URL or submitted form data and displays them on the page without safely encoding them as text (worryingly common), you can provide a <script> tag for execution on that page. Causing someone to visit such a URL allows execution of scripted actions on their behalf. Code injection is also possible on the server side with PHP (or Perl, or similar), if sloppy code gives access to an eval-like function, or if server misconfiguration allows user-uploaded files to be interpreted by the server as scripts.
Hacking into an operating system or server program remotely may exploit bugs in its handling of network commands. Improper handling of malformed network commands can cause it to bungle user authentication checks or even to directly execute code provided in the network packet, such as via a buffer overflow.
Bugs in web browsers, plugins, and document viewers are similar. What should be safe types of file can be crafted with non-standard or broken values. If the programmer forgot to handle these cases safely they can often be used to escape the normal limits of the file type.
Viruses can also be slipped onto a machine via physical exchange of USB stick or CD or convincing someone to install virus-laden software. Such viruses are often written anew for each purpose (to avoid anti-virus software), but there are some common ones available.
Weak or badly implemented encryption can permit brute-force decoding of encrypted data or passwords. Non-existent encryption can permit wiretapping of data directly. A lack of encryption can also permit unauthenticated commands to be sent to a user or server.
Very obvious passwords, or unchanged default passwords, may allow simple guesswork to get into a system. Some people use the same password everywhere. This give websites the power to simply walk in to a user's email account and then take control of everything associated with it. It also means a password leak on one insecure website may be used to access accounts on many other websites.
And sometimes, "hacking" is social engineering. For example, imagine phoning up a junior employee and pretending to be someone in charge, to trick them into revealing internal information or reset a password. Phishing emails are a common, semi-automated form of social engineering.
Breaking into a system is rarely just one of these steps. It's often a long process of analyzing the system, identifying minor flaws and leveraging them to see if a useful attack vector is exposed, then branching out from that to gain more access.
I've never done it, of course.
There is a sort of "hacking" possible with javascript. You can run javascript from the adressbar. Try typing javascript: alert("hello"); in your address bar while on this website.
This way it it possible to hijack local variables, cookies for instance.
But since javascript runs on the client-side. People would have to use your workstation in order to gain access to your cookies. It is a technique that can be used to alter login data and pretend to be somebody else (if the site had been badly built).
If you really want to learn more about this there are some 'javascript hacking lessons' that can be found here: http://www.hackthissite.org/pages/index/index.php
Side note, there is a difference between hacking and cracking. Reference: http://en.wikipedia.org/wiki/Hacker_(programmer_subculture)
There are many exploits that can use javascript, probably the most well-known is going to be cross-site scripting (XSS).
http://en.wikipedia.org/wiki/Cross-site_scripting
To follow up on Michael's answer, it is good to know the vulnerabilities in software and how people exploit those vulnerabilities in order to protect against them, however hacking is not something you want to be known for.
For a start, you are actually referring to what is known as Cracking, not hacking. This question will surely be closed, however some brief observations ^_^
Cracking comes from a base level understanding of how computer systems are built, hence you don't learn how to crack/hack, you learn about computer engineering in order to reverse-engineer.
A popular platform for hacking is Linux; over windows for example as its open source so experienced programmers can write their own programs. Although experienced hackers can accomplish their goal on any platform.
There are many levels of hacking however, simple website security is worlds apart from hacking in to Sony and facing jail ^_^
You may have some fun on http://www.hackthis.co.uk though
It depends on many things, for example: how the html code is structured, for example, I don't know if you could hack an iframe, but a normal web-page would be relative easy to hack. Another security pitfall programmers usually do is passing sensitive information via url query-string, then you could get those pieces of data and submitting them wherever they are used in the html code.
There could be another details, but I don't figure them out right now.

JavaScript encryption (or obfuscation) of client-side data structures

Is there a way to 'hide' structure and content of javascript objects?
I have fairly extensive JavaScript objects on my client side holding information about the users UI (and other things). It holds a lot of information about the resources that the user will be operating on. As it is, someone with Firebug can just open the console and see the structure of all that data. I'm not crazy about that for security reasons.
Are there any ways I can protect this data?
Thanks,
No, you cannot protect that data. Anything that can be seen and used by the browser can also be seen and used by a person inspecting what the browser has.
You really need to think about why is this a problem for you? If you're concerned about a man-in-the-middle snoop who might intercept that data, then you should run your connections over https.
If you're concerned about the end-user themselves seeing this data, I'd ask why are you concerned about that? It's the user's own state. There should be no secrets in there.
If you're concerned that the user might manipulate things to do things on your server that they shouldn't be allowed to do, then you need to implement protection on your server for things the user shouldn't be allowed to do. Clients cannot implement such protection because clients are, by definition, not secure in this regard.
If there is actually secure data on the client that the end-user themselves shouldn't have access to, then you need to rethink how your app works and keep that data only on the server. The client should only have data that is absolutely required to be on the client. It's possible to implement a UI with very little actual data in the client except specific fields that are being edited if you generate most of the UI server-side.
So ... in summary. Don't put data in the client that the end-user shouldn't have access to. Rethink how your app works if that's a problem. If the end-user can have access to it, then don't work. If nobody else should have access to it, then run your pages over https.
As for obfuscation, it's barely worth any effort. Obfuscation does not provide any true security as it can always be defeated. At best, it provides a level of annoyance to someone trying to look at your code. A determined hacker will be able to get through the obfuscation by just spending a little more time on it and running it through some tools. Certainly there is no harm in minifying your javascript code as that makes it smaller and makes it less readable by humans, but do not count it as any form of real security.
No, there is not.
However, you have some options:
You can obfuscate your javascript -- this will help slightly as it makes it harder to read and understand your code. There are plenty of good obfuscators out there. I advice against this!
You can minify your javascript -- this might look like an obfuscation method, but is not. It can easily be reverted back to readable javascript and is mainly intended for limiting bandwidth. I encourage this, but advice against it for this reason!
You can try to put as much of your sensitive data and code on your server. This might make sense, or it might not.
You can encrypt your data and decrypt it on-the-fly via your own javascript decryption library. Not a good idea, as it is fairly easy to by-pass this security and it is resource intensive. However it will slightly discourage "theft" of your data. I strongly advice against this!
If you can accept to only target Google Chrome (for now) or Chromium, you can implement your code and data in Native Client, which basically is compiled C code running in a sandbox in your browser (Chromium/Chrome). The only way to get access to your code is decompilation. If you are really paranoid over data theft, you can obfuscate your C code before compiling, to try to kill debuggers from snatching your data, and possibly fetch all your data over SSL from your server in real time rather than having it in your binary.
Though, remember, even with option 5 there are ways to claim your data, though it will be very few who both have the will, time and know-how to get it.
And also remember, if you are looking for a way to conceal sensitive data on the web, it is highly likely you have thought out your solution wrongly. Never ever put sensitive data on the client or use client side verification as your only verification. Perhaps the web is not the platform you are looking for? Perhaps you're looking for a distributed solution?
If it's a security concern, don't send it to the client. Even if you obfuscate it, you're not making it more secure.
Obfuscation can only get you so far, because the nature of Javascript is that it is downloaded to the user's system so that their browser (and user) can read it. Making something harder to read is not hiding it completely. You cannot encrypt it without giving your users some way to decrypt it, thus defeating the purpose. What you're looking for is a server-side language that's compiled before the user sees it, such as PHP, Python, Java, etc.
No, not really. You can obfuscate, pack and do all kinds of stuff to make the source code harder to read. Hell, you can even give your objects really weird and indescript properties. But that's it really, you only make it harder to read. The data is there, and a determined attacker can find out what he wants if sensitive data is sent to the client.
So don't store sensitive data client side. Anyway, what's so horribly secret about UI state? If a user wants to break his state, let him?
I would not suggest to try to obfuscate the javascript logic. But you can minify it (i.e. uglifying it). at least you would make it more difficult to read.
If you are concerned about the security of your client side code, then there is no way but to use server side code. Perhaps making more code available through services and then calling your services through $.ajax or someting similar.

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.

Javascript Ajax Graceful-degradation, with Different Pages?

I'm starting to give a little more attention to making my javascript and ajax degrade gracefully. Which is more recommended:
working on incorporating the graceful degradation into your existing code (can be tricky)
or
developing a different sets of pages for the non-js users.
I'm leaning towards the different sets of pages, because I feel it's easier and I get to deliver the best possible results for each user type (js-enabled or js-disabled). Do you agree with me, and if not, why do you disagree?
I'm also worrying about hacking attempts. For example hacker gets to the js-enabled version, then disables his js. Any thoughts on this point? I don't know much about hacking, but can this be a security concern if I go with the separate versions?
Thanks in advance
Though it doesn't work well for existing sites, often it's more useful to use the Progressive Enhancement paradigm: build the site so it works with no special add-ons, then start layering your awesomeness on top of that.
This way you can be sure it works from the ground up and everyone (including those who use screen readers, those who turn off images or stylesheets, and those who don't use javascript) can all access your site.
For an existing site, however, it will depend on what functionality the ajax is delivering. In general you should strive to mirror all the ajax functionality with js disabled. If you have security holes in your js version, than you probably will in your non-js version too. AJAX can't get to anything that can't be accessed via ordinary URL.
Developing two separate sets of pages, one for JS enabled and one for non-JS, is obviously a lot of work, not only initially, but also as your application keeps evolving. If that doesn't bother you too much, I think that's the way to go. I think you are right about same-page graceful degradation being very tricky sometimes. Sometimes this is just because of the layout: With JS enabled, you can simply hide and show elements, where as without JS: where to put everything? Separate sets of pages can help keep page structure cleaner.
About hacking attempts: You can never, never, never rely on client-side JavaScript validation. Everything has to be checked (or re-checked) server-side, and your server-side code may make no assumptions whatsoever on the user input. Therefore, I think the scenario of someone de-activating JS while using the application is irrelevant. Try to keep the expected user input uniform for the non-JS and the JS versions, validate it properly, and you're good.
You'll probably want to check out jQuery Ajaxy. It lets you gracefully upgrade your website into a full featured ajax one without any server side modifications, so everything still works for javascript disabled users and search engines. It also supports hashes so your back and forward buttons still work.
It's been implemented on these two sites (which I know of) http://wbhomes.com.au and http://www.balupton.com

Categories

Resources