1

似乎没有办法完全隐藏源/加密某些内容以防止用户检查脚本背后的逻辑。

那么,除了查看源代码之外,是否可以在脚本运行时操纵每个变量、对象?这在某种程度上似乎是可能的:通过使用 Chrome 的开发者工具或 Firebug,您可以轻松地编辑变量,甚至在全局范围内调用函数。那么变量、实例化对象内部的函数或自调用匿名函数呢?这是一个例子:

var varInGlobal = 'On the global scope: easily editable';

function CustomConstructor()
{
    this.exposedProperty = 'Once instantiated, can be easily manipulated too.';

    this.func1 = function(){return func1InConstructor();}

    var var1InConstructor = 'Can be retrived by invoking func1 from an instantiated object';
                            // Can it be assigned a new value after this is instantiated?

    function func1InConstructor()
    {
        return var1InConstructor;
    }
}

var customObject = new CustomConstructor();

在浏览器上运行之后:

// CONSOLE WINDOW
varInGlobal = 'A piece of cake!';

customObject.exposedProperty = 'Has new value now!';
customObject.var1InConstructor; // undefined: the variable can't be access this way
customObject.func1(); // This is the correct way

在这个阶段,用户是否可以在 customObject 中编辑变量“var1InConstructor”?

这是另一个例子:

There is a RPG game built on Javascript. The hero in the game has two stats: strength and agility. the character's final damage is calculated by combining these two stats. It is clear that players can find out this logic by inspecting the source.

Let's assume the entire script is self invoked and stats/calculate functions are inside of objects' constructors so they can't be reached by normally after instantiated. My question is, can the players edit the character's str and agi while the game is running(by using Firebug or whatever) so they can steamroll everything and ruin the game?

4

6 回答 6

3

The variable var1InConstructor cannot be re-bound under normal ECMAScript rules as it is visible only within the lexical scope. However, as alex (and others) rightly say, the client should not be trusted.

Here are some ways the user can exploit the assumption that the variable is read-only:

  1. Use a JavaScript debugger (e.g. FireBug) and re-assign the variable while stopped at a breakpoint within the applicable scope.

  2. Copy and paste the original source code, but add a setter with access to the variable. The user could even copy the entire program invalidating almost every assumption about execution.

  3. Modify or inject a value at a usage site: an exploitation might be possible without ever actually updating the original variable (e.g. player.power = function () { return "godlike" }).

In the end, with a client-side program, there is no way to absolutely prevent a user from cheating without a centralized authority (read: server) auditing every action - and even then it still might be possible to cheat by reading additional game state, such as enemy positions.

JavaScript, being easy to read, edit, and execute dynamically is even easier to hack/fiddle with than a compiled application. Obfuscation is possible but, if someone wants to cheat, they will.

于 2013-03-06T00:08:38.323 回答
3

I don't think this constitutes an answer, it could be seen as anecdotal, but it's a bit long for a comment.

Everything you do when it comes to the integrity of your coding on this issue has to revolve around needing to verify that the data hasn't changed outside of the logic of your game.

My experience with game development (via flash, primarily...but could be compared to javascript) is that you need to think about everything being a handshake where possible. When you are expecting data to come to the server from the client you want to make sure that you have some form of passage of communication that lessens the chance of someone simply sending false data. Store data on the server side as much as possible and use the client side code to call for it when it's needed, and refresh this data store often.

You'll find that HTML games tend to do a lot of abstraction of the logic to the server side, even for menial tasks. Attacking an enemy, picking up an item, these are calls to functions within server-side code, and is why the game animation could carry on in some of these games while the connection times out in the background, causing error messages to pop up and refresh the interface to the server's last known valid state.

Flash was easier in this regard as you didn't have any access to alter any data or corrupt it unless it left the flash environment

于 2013-03-06T00:09:43.330 回答
2

Yes, anything ran on the client should be untrusted if you're using the data from it to update a server side state.

于 2013-03-06T00:01:42.790 回答
0

As you suggested, you can't hide the logic/client-side code. You can make it "harder" for people to read the source by obfuscating it, but it's very trivial to undo.

Assuming you're making a game from your example, the first rule of networked games is "never trust the client". You need to either run all the game logic on a server, or you need to validate all the input on a server. Never update the game state based on input from a client without validating it first.

于 2013-03-06T00:06:00.193 回答
0

You can't hide any variable. Also, if the user is so good in javascript, he can easily edit your script, without editing the variables value through the console.

于 2013-03-06T00:09:17.810 回答
0

JS code that is injected into an HTML using Ajax is pretty darn difficult to get your hands on, but it also has it's limitations. Most notably, you can't use JS includes in injected HTML . . . only inline JS.

I've been working with some of that recently actually and it's a real pain to debug. You can't see it, step into it, or add breakpoints to it in any way that I can figure out . . . in Firebug or Chrome's built-in tool.

But, as others have said . . . I still wouldn't consider it trusted.

于 2013-03-06T00:15:09.593 回答