The problem: I have a jQuery heavy page that has a built in admin interface. The admin functions only trigger when an admin variable is set. These functions require a second library to work properly and the second file is only included if the user is an admin when the page is first created. The functions will never trigger for normal users and normal users do not get the include for the second library.
Is it bad to reference a function does not exist in the files currently included even if that function can never be called? (does that make sense :)
Pseudocode:
header: (notice that admin.js is not included)
<script type="text/javascript" src="script.js"></script>
<script type="text/javascript" src="user.js"></script>
script.js: (admin functions referenced but can't be executed)
admin = false; // Assume this
$(".something").dblclick(function(){
if(admin)
adminstuff(); // Implemented in admin.js (not included)
else
userstuff();
});
Ideas:
I suppose two separate files for users and admins could be used but I feel that would be an overly complicated solution (don't want to maintain two large files with only a few lines of difference). The only reason I include a reference to the admin function in this file is I need to attach it to page elements that get refreshed as a part of the script. When jQuery refreshes the page I need to reattach function to interactive elements.
The Question:
I want to keep things very simple and not have to include file I don't have to if they will not be used by the user. Is this a good way to do this or should I be going another route?
The code should operate without error, since the admin functions without implementation will not be called. The only thing that is really being wasted is bandwidth to transmit the admin code that is not used.
However, let me caution against security through obscurity. If the user were to view this code and see that there are admin functions that they cannot access, they might get curious and try to download the "admin.js" file and see what these functions do. If your only block to keeping admin functions from being performed is to stop including the file, then some crafty user will probably quickly find a way to call the admin functions when they should not be able to.
If you already do server side authentication/permissions checking for the admin function calls just ignore my previous paragraph :-)
Personally, I would bind (or re-bind) the event in admin.js:
$(function() {
$(".something").dblclick(function(){
adminstuff();
});
});
function adminstuff()
{
// ...
}
That way, the adminstuff() call and the function will not be visible to "normal" users.
Good question. It shouldn't cause any JavaScript problems.
Other things to consider: you are potentially exposing your admin capabilities to the world when you do this, which might be useful to hackers. That's probably not much of a concern, but it is something to be aware of.
See also:
Why can I use a function before it’s defined in Javascript?
I don't think it matters. If it makes you feel better, you can make an empty stub function.
I don't think there's a dogmatic answer to this in my opinion. What you're doing is...creative. If you're not comfortable with it, that could be a sign to consider other options. But if you're even less comfortable with those then that could be a sign this is the right thing (or maybe the least wrong thing) to do. Ultimately you could mitigate the confusion by commenting the heck out of that line. I wouldn't let yourself get religious over best practices. Just be willing to stand by your choice. You've justified it to me, anyway.
Javascript is dynamic - it shouldn't care if the functions aren't defined.
If you put your admin functions in a namespace object (probably a good practice anyway), you have a couple of options.
Check for the existence of the function in the admin object
Check for the existence of the admin object (possibly replacing your flag)
Have an operations object instead, where the admin file replaces select functions when it loads. (Even better, use prototypical inheritance to hide them.)
I think you should be wary that you are setting yourself up for massive security issues. It is pretty trivial in firebug to change a variable such as admin to "true", and seeing as admin.js is publically accessible, its not enough to simple not include it on the page, as it is also simple to add another script tag to the page with firebug. A moderately knowledgeable user could easily give themselves admin rights in this scenario. I don't think you should ever rely on a purely client side security model.
Related
I'm just in the process of studying jquery. And I have the following question. I have a page that relies on js for ajax and reporting to user.
So basically I have created a file with $(function() {}) construct. Inside of that construct I'm using standard jquery functionality to work with my modal windows, smth. like
$('.text-danger').hide();
$(".btnajax").click(function() {})
But now I want to work with another modal window at the same page, not at the same time. What would be a better way:
Continue inside the same anonymous function construct and keep working with IDs and Classes when referencing the specific buttons and form actions?
OR
Create new anonymous function construct? OR
Create named functions and call them when needed?
I would like to build correctly from the scratch, so I don't have to redo everything later when I'm better with JS.
Thank you in advance.
Continue inside the same anonymous function construct and keep working
with IDs and Classes when referencing the specific buttons and form
actions?
This is not a good idea as every time you would do something with the buttons or the form it would access the DOM which is unnecessarily expensive.
Create new anonymous function construct?
Actually, anonymous functions are rarely a good idea as they make your code hard to read. Imagine there are no named functions and everything is anonymous. That would require the reader to always get the context in order to quickly understand what the function is doing
Create named functions and call them when needed?
Especially when reusing that functionality, it's a good idea. But also in terms of readability it is good because the name of the function describes what is happening so when someone (you) read the code again after some time, will know hat is happening without studying the body of the functions.
Apart from that:
I would like to build correctly from the scratch, so I don't have to redo everything later when I'm better with JS.
I can tell you: you will not avoid rewriting parts of your code once the requirements change. That is just what coding is about. You can not foresee every required change to your application. If you try to then you end up having an over engineered code. Instead, you should follow YAGNI.
Generally speaking, for everything that's more than just 5 buttons and a form, a JS file with jQuery is not the way to go. Those times are over. Switch to something that gives you a separation of concerns between model, (model)view and controller.
Good day all.
I would like to count the js functions present on a given page, and then send this number via ajax (the ajax part is the simple part) do you think is it possible to achieve that in javascript? what should be the best way to do it?
thanks in advance.
explanation:
I'm trying to figure out how to counter measure some fraud attempts on some subscription pages, I suspect that some javascript is injected on the page before the user click, so having the number of functions present at the load event, and then the number of those present on the submit event, should lead me in the right direction.
Well, if someone is injecting code to your site, they could just as easily use that code to turn off your code counting functions. You can never trust anything that happens on the client side and must validate everything on the server.
As for the technical side, you'd use a tool like acorn to traverse the syntax tree and find all FunctionDeclaration and FunctionExpressions (and arrows, concise method definitions and methods). That would not find all functions, but it would find all statically created ones.
Once the code started executing it's impossible since it's easily reducable to the halting problem. You don't know if a code will create a function at some point in the future.
I'm working within a Javascript + BackboneJS (an MVC framework) + RequireJS framework, but this question is somewhat OO generic.
Let me start by explaining that in Backbone, your Views are a mix of traditional Views and Controllers, and your HTML Templates are the traditional MVC Views
Been racking my head about this for a while and I'm not sure what the right/pragmatic approach should be.
I have a User object that contains user preferences (like unit system, language selection, anything else) that a lot of code depends on.
Some of my Views do most of the work without the use of templates (by using 3rd party libs, like Mapping and Graphing libs), and as such they have a dependency on the User object to take care of unit conversion, for example. I'm currently using RequireJS to manage that dependency without breaking encapsulation too much.
Some of my Views do very little work themselves, and only pass on Model data to my templating engine / templates, which do the work and DO have a dependency on the User object, again, for things like units conversion. The only way to pass this dependency into the template is by injecting it into the Model, and passing the model into the template engine.
My question is, how to best handle such a widely needed dependency?
- Create an App-wide reference/global object that is accessible everywhere? (YUK)
- Use RequireJS managed dependencies, even though it's generally only recommended to use managed dependency loading for class/object definitions rather than concrete objects.
- Or, only ever use dependency injection, and manually pass that dependency into everything that needs it?
From a purely technical point of view, I would argue that commutable globals (globals that may change), especially in javascript, are dangerous and wrong. Especially since javascript is full of parts of code that get executed asynchronously. Consider the following code:
window.loggedinuser = Users.get("Paul");
addSomeStuffToLoggedinUser();
window.loggedinuser = Users.get("Sam");
doSomeOtherStuffToLoggedinUser();
Now if addSomeStuffToLoggedinUser() executes asynchronously somewhere (e.g. it does an ajax call, and then another ajax call when the first one finishes), it may very well be adding stuff to the new loggedinuser ("Sam"), by the time it gets to the second ajax call. Clearly not what you want.
Having said that, I'm even less of a supporter of having some user object that we hand around all the time from function to function, ad infinitum.
Personally, having to choose between these two evils, I would choose a global scope for things that "very rarely change" --- unless perhaps I was building a nuclear powerstation or something. So, I tend to make the logged in user available globally in my app, taking the risk that if somehow for some reason some call runs very late, and I have a situation where one user logs out and directly the other one logs in, something strange may happen. (then again, if a meteor crashes into the datacenter that hosts my app, something strange may happen as well... I'm not protecting against that either). Actually a possible solution would be to reload the whole app as soon as someone logs out.
So, I guess it all depends on your app. One thing that makes it better (and makes you feel like you're still getting some OO karma points) is to hide your data in some namespaced singleton:
var myuser = MyApp.domain.LoggedinDomain.getLoggedinUser();
doSomethingCoolWith(myuser);
in stead of
doSomethingCoolWith(window.loggedinuser);
although it's pretty much the same thing in the end...
I think you already answered your own question, you just want someone else to say it for you : ) Use DI, but you aren't really "manually" passing that dependency into everything since you need to reference it to use it anyways.
Considering the TDD approach, how would you test this? DI is best for a new project, but JS gives you flexible options to deal with concrete global dependencies when testing, ie: context construction. Going way back, Yahoo laid out a module pattern where all modules were loosely coupled and not dependent on each other, but that it was ok to have global context. That global context can make your app construction more pragmatic for things that are constantly reused. Its just that you need to apply that judiciously/sparingly and there need be very strong cases for those things being dynamic.
I am trying to figure out any and all ways to prevent CSS modification and DOM modification of specific elements. I understand this might not be completely possible or that a talented developer could get around it, however, I am not so concerned about people potentially getting around it, I just want to stop newbies. In particular those using jQuery. An example would be to delete certain properties on prototype objects etc..
But why you need/want this? If you want to "protect" your code, you can use some JavaScript minifier as Google Closure Compiler or YUI compressor. They will rewrite your script and it will be difficult to read by a human. Nowadays, with tools like Firebug and Grease Monkey it's almost impossible to do what you want.
Don't use CSS or JavaScript :p Depend completely on server side checks etc.
You cannot stop anyone from messing with your javascript or your objects in the page. The way the browser is designed, your code and objects in your page are simply not protected. Everything from bookmarklets to javascript entered at a console to browser plug-ins can mess with your page and code and variables. That is the architecture of a browser.
What you can do is make things a little more difficult such that a little more work is required for some things. Here are a couple of things you could do:
Obfuscating/compressing/minimizing your code will do things like remove comments, remove whitespace, remove some linebreaks, shorten variable names, etc... That does not prevent anyone from modifying things, but does make it more work to understand and figure out.
Putting variables inside closures and not using globals. This makes it harder to directly modify variables from outside of your scripts.
Keep all important data and secrets on your server. Use ajax calls to ask the server to carry out operations using that data or secrets such that the important information is never available in the browser client.
You cannot keep anyone from modifying the DOM. There simply are no protections against that. Your code can check the DOM and refuse to operate if the DOM has been messed with in non-standard ways. But, of course, the code would then be modified to remove that check too.
If you are looking for a jquery specific solution a crude approach will involve altering the jQuery ($) function and replacing it with a custom one that delegates to the original function only if the provided selector does not match the element you want to secure.
(function(){
jQueryOrig = jQuery;
window.jQuery = window.$ = function(){
if (jQueryOrig("#secure").is(arguments[0])) {
throw new Error("Security breach");
} else return jQueryOrig.apply(this, arguments);
}
}());
Of course people using direct DOM manipulation would not be affected.
Also, if you are actually including arbitrary third party code in your production code, you should take a look at Caja ( http://code.google.com/p/google-caja/ ), which limits users to a subset of javascript capabilities. There is a good explanation regarding Caja here : http://due-diligence.typepad.com/blog/2008/04/web-20-investor.html .
This is possible but requires that the JS file to always be loaded from your server. Using observers you can lock CSS properties and using the on DOM remove/add listeners you can lock it to a parent. This will be enough to discourage most modification.
You can actually go a step further and modify core javascript functions making it nearly impossible to modify the DOM without loading the JS file locally or through a proxy. Further security can be added by doing additional domain checks to make sure the JS file is loaded from where it is supposed to be loaded from.
You can make everything in Flash. In Chrome, there's even a bug that prevents users from opening a console if the flash element has focus (not sure how exactly this works, but you can see an example at http://www.twist-cube.com or http://www.gotmilk.com). Even if users do manage to get a console open (which isn't that hard...), still about all you can do is change the shape of the element.
I am in the middle of a project which basically allows other users to install "add-ons" for my script. In general it will be something like the following:
function widget () {
this.addControl = function (type,control) {
control.call({ Object With Some Un-thoughtout Vars });
}
}
Very basic example with pretty much everything removed
The users who will be using this trust myself fully. Now I want to make sure any scripts other people make will be ran with limited permissions. So they can't hijack sessions or redirect the user or upright steal their passwords/keystrokes.
I looked at a few results on Google and they basically suggest that you shouldn't really do this as its more trouble than its worth. But in my opinion I'd much rather limiting it than someone installing a widget that takes their information (which they more than likely will). So does anyone know of a way of breaking down the callback function into individual lines of code so I can check everything's fine before allowing it to run?
Or will I have to go down some horrid string then eval method?