PDA

View Full Version : Making Read-only property in a user-defined JS object



codeexploiter
03-12-2009, 04:36 AM
Hi All,

Is it possible to make read-only property in a JS user defined object. I am looking for a cross-browser based solution.

jscheuer1
03-12-2009, 01:35 PM
Depends upon what you mean by user defined. Also this is a bit of a contradiction, if the user defines it, they just wrote it - definitely not readonly. But say you let the user define the object and that once it is created you want it to be readonly in the HTML sense of the word. If the object is an element supports that attribute:


obj.readonly = true;

will do the trick.

However, virtually all element objects are accessible using the DOM, so a sophisticated user may just type in commands to the address bar to change the values of their properties.

On the other hand, a normal user won't be doing this, so you can always just create the element, or even a non-element object for them and give them no other (besides the address bar method - which cannot be blocked) means to write to it.

The very facts of the matter at hand here are why javascript used with forms is insecure if it performs any security validation or price computations not also rechecked on the server side. And are why javascript in general is not secure - the user may always alter it.

Now, you can create objects in a scope that the user cannot access. But these will be of limited utility because they cannot be a part of the DOM, and the user may not interact with them at all. Even with that, if a person copies your page and the relevant script code, they will be able to spoof your private object back to your host in most, probably all cases.

codeexploiter
03-12-2009, 01:45 PM
hi john,

What I am trying to achieve is say there is a JS object


var foo = {
id: "myid"
};

In the above object a developer who accesses the object foo can read or update the element id's value. I am looking for something to prevent the changes.

jscheuer1
03-12-2009, 02:14 PM
As I said, you may create it in a scope that the user has no access to:


function myFunc(){
var foo = {
id: "myid"
}
};

myFunc();

It will only be accessible within that scope. But a developer can still access it if they copy your page and script code, it simply is no longer accessible via the address bar, possibly via a debug function in an advanced debugger program though, and definitely if they make a copy of your work as mentioned in my previous post.

You may even make it in the scope of an anonymous function:


(function(){
var foo = {
id: "myid"
}
})();

These are both examples of private variables. They may be used within the scope where they are created. You may carry out complex operations, even entire scripts within the scope of either of these two function types if you like, and the user will only be able to access the variables within them by making a copy of your work and somehow fooling the server into thinking that the copy is your page - not hard to do, but a bit of work.

However, if you access the global scope from within one of these functions, by accessing the DOM or any of the global properties of window, document, etc., anything you do there is open to change from the address bar, except for events which have passed and which cannot be repeated. The only one of those I can think of at the moment is the onload event. But anything it does in the global scope can be accessed and changed. And it may even be able to be invoked from the address bar:


javascript:void(window.onload())

Bottom line, like I said - javascript is insecure.

Twey
03-12-2009, 02:20 PM
Effectively, no. You can use getters and setters, of course, as John implied:
var foo = function() {
var id = "myid";

return {
getId: function() { return id; }
};
}();... although the getter can always be overwritten when done like that. Problems arise, however, if the object needs to be constructed more than once, since you'd have to create all those functions anew for each instance — which, generally speaking, isn't worth the effort.

In Mozilla's JavaScript and some other implementations, there are specialised getters and setters, which overcome this problem:

var foo = {
get id() {
return "myid";
}
};... but this won't work in IE's JScript.

jscheuer1
03-12-2009, 02:40 PM
There is also the constant keyword in javascript, but support for that is terrible. If it worked, you could:


const foo = {
id: 'myid'
};

And it shouldn't be able to be changed, but it can in most if not all browsers.

jscheuer1
03-12-2009, 03:47 PM
I did a little more research, and the above (const) will work for strings and numbers in current Opera and Mozilla. But if you define an object with it, its properties can still be changed. In IE, const simply isn't supported, you will get an error.

Also there are ways, like the define function:

http://www.devpro.it/code/171.html

that have been developed to deal with this. But once again only for strings and numbers as far as I know, and the function itself and/or the objects it creates to work its magic could be redefined or changed, so it could be gotten around, just a bit more difficult - sort of like those no right click scripts.