Protect against write/read an external save file

Is there any way to protect from write and read an external save file generated by the game? I mean a json file and a text file can be edited easily, so it’s not possible protect scores or locked content in a game if the data to save that information can be edited easily.

What I do in my saves when is an external file is do some hash with javascript
First hash the data then I name the file with a custom extension like savegame.apixeladventure
When I have to retrieve I do an unhash formula then load the file.

I don’t have the knowledge to do something like that and I consider that gdevelop should have this essential feature.

Internal storage is safe for these purposes but it has the problem that in case of delete/update the game the current progress in the game is lost.

To clarify: Most engines do not have this built-in, and do not natively encrypt save files. It is up to the developers to decide how/if they will, or to add their own extensions for doing so.

There’s some simple options encoding options available (there’s a rotate13 extension available in the extension list), but considering the number of save editors out there, unless you completely build your own save structure via text with your own custom encoding, people are going to be able to edit said files if they want to.

I did some checking, and this is true even for stuff like Unreal Engine 4, Defold, and Unity. With Unity you have to buy a separate extension for encoding the save files or build your own method. UE4 doesn’t have any extensions for it at all and you have to do it youself, same for Defold.

>_> Unhashing is not a thing, that defeats the whole purpose of hashing. When you hash something, you get a unique output for an input, but the input cannot be found using the hash. That is why it is used to store passwords, that way, if the database with the hashes is leaked, you cannot just unhash the passwords to get them, you have to bruteforce them (hash a random string, check if the hashes are the same, if they are congrats else try again).

Updating the game shouldn’t clear the internal storage. You may think it is safe but it is trivial to modify to an experienced person. Whatever you do, it will always be possible to modify save files. Whatever security measures you have, the file has to be in clear text at some point on the players machine, and if your software can convert it to clear text players can make software that can as well. What you are asking for is security through obscurity, which isn’t secure at all, it only gives an illusion of security.

What you can do to actually improve security is to “fact check” the save and not store unnecessary stuff in it.
For example, storing the player speed in your save file is unnecessary and dangerous, letting the player cheat. If at some points of the game you want the player to be faster, check the other variables for game progression and apply the appropriate speed if necessary, to only give the speed at the moment you are supposed to be given speed to.
Another example, if the save says you haven’t unlocked say level 2 but have an object available only in level 4, you can detect that a cheat has been attempted and either refuse to load or straight up delete the save.

When I mean unhashing is to perform any kind of formula you want to retrieve the data. For instance in PHP
to hash a password
$passwd = hash(‘sha512’, $password)
store this $passwd into your db.

Then to check and compare to database use
hash(‘512’, $recieved_pass == $hased_pass_on_db)

But anyway is only to clarify.

In PHP I think that you would actually use

$inputted_password = "HELLO"
$hashed_pass = password_hash($inputted_password)
if(password_verify($inputted_password, $hashed_pass)) {
   echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}

I’m going to pile on here as well with some advice.
Don’t even attempt to implement client side protection for game data… if it’s on the player’s system it’s under their control.
If you want to be in control of the data then store it server side using your own service where you can validate and ensure the integrity.

That being said, if you just want the client side data to be “tamper-evident” then the technology you are looking for is called “signing”. There is a JS library to help with this:
https://jose.readthedocs.io/en/latest/
But even then you’d want to put the signing service in the cloud, otherwise you’d ship your game with the signing key… which could definitely be compromised.

Again though, I personally think it’s not worth the effort… if I user wants to cheat the data that’s their business.

Nice I didn’t know that Framework.

Well, putting files on the servers isn’t more secure than on the client. The player can easily redirect traffic from the server to the local machine, and make it return their tampered file.

Like with hashing, it doesn’t change anything. The game needs to be able to sign saves, and if the game can, the player can as well. If it is on a server, you can just send our tampered file and make it sign it. If it is on the client, the private key would be in the game files and trivial to extract to sign yourself.

Again, just verifying the data and not giving access to unnecessary variables should be enough to prevent breaking the game, and if you just don’t want it to be evident to tamper with the save, just do a rot13 like silver said to not make it directly readable.

The only way to truly prevent the user from changing his save is hosting the game on your server, and streaming the image from the server to the client and the input from the client to the server, and let your trusted server take care of everything, and that is not doable with GDevelop.

If someone really wants to tamper with your data file, they will find a way. But considering the games most of us make and our audience, is it really that important to make it unbreakable?

If you really are after scrambling the data so it’s not understandable, look at encrypting it. Even a simple encryption method, like XORing a character with the previous one or using a passphrase, will throw most wannabe crackers off.