[Question] How to defeat Javascript hacking in Unity WebGL builds

I’ve just finished the Block Breaker section of the Unity2D course, and I’ve got a game that seems to work reasonably well. There are still a few things I’d like to add in the future. In particular, I think a high score table would be a useful addition.

But there’s a bit of a problem with that. Since Unity makes all the game’s public methods accessible from Javascript, it would be very easy for someone to create a fake high score without even playing the game.

For example, suppose you want to start the game with a million points. Just go to Level 1, pop open a Javascript console, and type in the following:

unityInstance.SendMessage("GameSession","AddPointsToScore",1000000);

Are there any simple techniques that can prevent users from fiddling with game objects in this way?

Hi,

First of all, good job on completing your game so far. I tested it, and it is running smoothly. :slight_smile:

Regarding your question about the accessibility via Javascript, it’s not possible to protect or hide anything. The Javascript code is always accessible, and it’s just a matter of how experienced the person is who is looking at the code.

You could try to write a pure C# Score class meaning a class that does not inherit from any Unity classes. In that class, you could have a property which can be read but one cannot override it from outside. The class could have a GetScore() and a AddToScore (int score) method.

Maybe that will make the score less obvious in the Javascript code.

Another way could be to open the Javascript project in Visual Studio or something like that. I never did that, so I don’t know how well this would work. Then you could install some package that encrypts the parameters in your code. This way, the code will become less readable. However, it’ll not override any strings, so this will probably work better with your own classes. If it works.

Please feel free to ask our helpful community of students for advice in our official Discord chat.

Thanks Nina. Perhaps I was unclear; my project is written entirely in C#. The issue is that Unity builds all WebGL projects with a Javascript interface that exposes all the public C# methods. So if I create a Score class in C# with a public AddToScore() method, it will still be possible to call this method from the browser’s Javascript console in exactly the way I described.

But on reflection, this is probably the sort of problem that affects all client-side code. I don’t think obfuscating the names of classes and methods would help — I haven’t tried decompressing a unityweb file, but I imagine it would contain all the object and method names in plain view.

Is there perhaps some way the Score class could disclose a randomly generated secret token to the objects that call it (without using a public method)?

It’s not because you are using Unity which was written in C++. Your scripts are only a part of your project.

I don’t think obfuscating the names of classes and methods would help

As aforementioned, the code will always be exposed. What I described could prevent a “hacker” from understanding your code at the first glance. “AddPointsToScore” can be understood even by a beginner while some cryptic name like “Blasjfjkdhgtdk” is meaningless without any context.

Or can you tell how lines like these would affect a game if you saw hundreds of them? You would probably have to use the trial and error approach to understand what’s going on there. That’ll take time, and maybe it is not worth it for the “hacker”.

unityInstance.SendMessage("dfsk","fdjgl",1000000);
unityInstance.SendMessage("glkjglsdgf","gfsdogtorgteroph",434);

Many programmers use encrypting scripts to prevent beginners from stealing their code. Depending on the complexity of their projects, an experienced programmer will need days to decrypt the scripts, and it might be that they give up early because developing their own solution is faster than grasping your code. That’s the idea behind the concept and a workaround for the insoluble problem.

Is there perhaps some way the Score class could disclose a randomly generated secret token to the objects that call it (without using a public method)?

There are no secrets but you could certainly write an algorithm that passes on some token which can be verified by the receiving method before the points get added to the score. That algorithm will be exposed, too, though, so an experienced programmer who really wants to cheat, will be able to generate his own valid token.

You also could evaluate the current project state. Did the ball hit a block in that moment when the AddPointsToScore was called?

In a multiplayer game, you could other players evaluate the situation as well because if the cheater was able to pass on a different value to the AddPointsToScore method than the other players, there must be something wrong with the method call.

That will definitely have a negative impact on the performance of your project, and the question remains: Is it worth it?

Well, obviously not for this particular project! :grin:

The thing is, I’ve studied cybersecurity in the past, and was told repeatedly that security measures are usually ineffective when added as an afterthought. They have to be built into the fabric of a system if they’re going to work properly. So if I’m ever going to apply these principles to Unity projects, I may as well start here.

A bit of obfuscation would definitely help, but renaming the Score class wouldn’t be of much use unless all the other classes are given random names. Requiring a secret token as a call parameter would definitely help. I’m just wondering if it’s possible to go one step further and have this token generated randomly instead of being hard-wired into the source code or available from a public method.

Anyway, I’m going to flag this as solved, but I’ll keep tinkering away to see if I can come up with something more robust.

Thanks for your help :smiley:

I’m no expert in cybersecurity. In fact, I have almost no knowledge about this. As a frontend developer, I just know that there is no way to secure the code because it is executed in the browser and accessible. Modern browsers do not allow you to manipulate them.

You could try to outsource parts of your project to a server. Then you’ll theoretically be able to execute secret programs.

https://forum.unity.com/threads/javascript-secure.455111/#post-2950075

This thread might also be interesting:

1 Like

Thanks for the links. I’ve since discovered that the Javascript SendMessage() interface only accepts one parameter, so if the public C# methods to update the score take two or more parameters then they won’t be callable from the Javascript console in any case.

For what it’s worth, I’ve made a ScoreKeeper.cs script that generates a random 64-bit token and distributes it to a predefined list of game objects. If it receives any calls without the correct token, it shuts down altogether:

But just using public methods with two parameters would probably be enough to deter all but the most determined hacking attempts.

Good job! :slight_smile:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.