avoid Javascript variable modification from browse

2019-09-17 16:57发布

问题:

I have a problem. I have defined some global variables and namespaced it into an object called "app". Example:

window.app : {
    foo : null,
    bar : null,
}

Well, the idea is that I want to be able to modify those variables from any module by calling app.foo = "baz" or app.bar = "baz", but I don't want the user to be able to modify those variables from the browser console (element inspector).

Is it possible?

PD: Well, I have a Backbone.js collection which is sinchronized with the server. I don't want the user to be able to modify that collection with the console

回答1:

No. The browser is the user's domain. They have the possibility to modify your scripts and inject their own functionality in various ways (through the console or browser plug-ins). That's one of the reasons why you should never blindly trust user input on the server side.

They could even manually forge a complete request, tricking your server into thinking that your javascript code that made some request.

If you want these values to be secure, you need to keep them on the server. You can send them to the client, of course, as long as you keep a possibility to validate the values agains those on the server.



回答2:

The only way to make the variables not (easily) modifiable by a user is to remove them from global scope - something like

!function() {
  foo = null;
  bar = null;
}()

You'll need to redesign the way your modules interact with each other to accomplish this. An MVC Framework like Angular.js will help.

You should never rely on this as a security mechanism, though - the browser is fully in the user's control.



回答3:

A possible way to avoid to (easily) modify javascript variables from the browser console is to either use the get operator (ECMAScript 5) or a getter-function.

To make it possible to define "private" variables, an anonymous function defines the variables in the local scope, so that it is not globally available. (as mentioned in joews' answer)

As mentioned before, this does not make it impossible to manipulate the variables.

Via get operator:

window.app = (function () {
    var _foo = 123; // private variable
    return {
        get foo () { return _foo; }
    };
}());

// --- accessing app from the console ---
// app.foo is readable from console, but not modifiable
console.log(app.foo);
app.foo = 234;
console.log(app.foo); // 123
// However, app.foo can still be modified via Object.defineProperty or
// removed with the delete operator

Via getter-function (older browsers, e.g IE < 9):

window.app = (function () {
    var _foo = 123; // private variable
    return {
        foo: function() { return _foo; }
    };
}());

// --- accessing app from the console ---
console.log(app.foo()); // 123
// However, the foo function can still be overwritten.
// But at least, the internal _foo variable is unaffected.
app.foo = function () { return 234; }