Best ways to stop people leaking your game client side

nah instead make an extremely hidden script that checks if the placeid is correct, if not just kick all players

Though, if an exploiter puts alot of effort to finding the script, the best you can do is file a DMCA.

To be honest, the best best best way to stop people from leaking your game or builds is… Instancing everything in your game (too hard to do in fact). Make a server script that instances all your builds with the sizes and positions (pre-built stuff just transforming them into script form). You can’t instance local scripts but you can also instance remote events and name them. Do all this through a server script and the exploiter would have nothing but a view pieces of confusing client code.

You want to protect client code?

Check for game.creatorId in a server script, check if it’s you who did it and store all client scripts inside server storage. If you are the creator, it clones the local scripts and parents them to the required service.

Your server scripts won’t copy onto the copy of the game, so nothing will load.

It might be really hard to instance your whole game but it will leave hackers and exploiters with nothing in the end. More than this, the effective way is to file a DMCA, but I just shared this for people who want to go another mile for game safety.

This doesn’t help. When a game is stolen it’s stolen in whatever state the player is seeing it as. This would be after everything has already been instanced and things are in place. The server script wouldn’t help either because once again the local instances would be the only things present and stolen.

2 Likes

If Roblox wanted to protect our assets, they could, and it wouldn’t be that hard.

If you’ve ever used a GUI image by location and name, those images are not downloaded when a place file is downloaded.

A good reference for this if you don’t understand, download the open-source game tribe sim.

The images in the gui are referenced as /images/image name, instead of by asset ID.

So instead of an asset ID, say you had an image named “frame” uploaded locally to that place. You could put /images/frame and that would work just like having the asset ID. However, if someone steals your place, they get nothing, because there is no “frame” located in /images/ for them.

Because of this, they exist and load locally based on their name and location, never giving access to the asset ID to begin with. The thief wont know the asset ID of the item. More so, you can use an alias that wont even give them the real file name.

There used to be times when more worked this way, but now it is pushing more towards depending on asset ID.

Currently, you can protect your GUI and normal textures this way. Sadly, PBR textures do not work with this method. Something that bothers me since they moved transparency to PBR, anything like a tree that used to be protectable even with textured leaves, now no longer is protectable.

I can’t make suggestions or I would have suggested long ago they fix this so it works with more, not less.

What I would like to see is the option on everything from meshes to textures that when you upload, you can use the local path instead of the asset ID.

This would solve place theft for everything but parts and terrain really.

Fyi modulescript bytecode is never loaded to the client until a client script requires it

And why would you put sensitive information/keys on a place replicated to the client, that’a shooting yourself in the foot

Place copying is mostly ever done to reverse engineer a game with better context, not to just republish it. Having a “good enough” look at how it works is all people need to write scripts targeting the game itself.

If anyone really cared to steal it exactly as is including images with local paths, they could. Those images are still uploaded to the website and Roblox still stores their actual IDs internally.

2 Likes

Clearly you know nothing about how programs like synapse work and what their limitations are. Asset IDs are server sided associations that are associated internally and used or not. How they are referenced are exactly that. The only thing that allows place stealing as it is now is that asset IDs work essentially as a hyperlink. There is no means to force that hyperlink to exist when it does not outside of through the server.

If you wanted to steal an item this way, you “could”, but programs like synapse would have to be specifically written for that purpose. While I have no desire to put this out there, I will say that developers like those making synapse didn’t put place copying in so people could steal assets, thieves are not their demographic. They put it in there to facilitate writing hacks, which is their market. Even if they did though, it wouldn’t be easy.

If you think you know something in this field, try it. I know many who have and to be quite blunt, anyone who knows anything about how file paths are used and the limitations of programs like synapse would tell you this isn’t doable. At best, if the developers of programs like synapse re-wrote their programs in a way to facilitate this, it would just give them raw data copies of models and images. These people would have to figure out what every one is and attempt to piece it back together themselves.

This has has a few impacts that are very important.

  1. It wouldn’t work without the nature of Synapse or other programs like it being re-written.

  2. Doing so for programs like Synapse greatly complicates the scope of how the program operates and would make updating it specifically for that purpose more work than I think they would care for. Also it would make their program much easier to detect.

  3. Even if the things above both happened. The process would become difficult enough as to elininate 99.9% of the people doing it. It would turn it from something skill-less, to an actually time consuming skilled task.

This isn’t some “no big deal” issue. Switching an asset from using a universal Roblox hyperlink to using a local file path is a huge deal as far as someone outside trying to access that data. These hack tools can’t access server data. How it is loaded to the client matters because now we’re no longer talking about accessing a function within Roblox, we’re moving to things like accessing local cache and memory addresses, which is an entirely different animal.

Even with the place file uncopylocked, you cant download those files.

If you want to see this in action, make a place file in studio, link some images by their local path, and try to even download those images yourself without changing the path to an asset ID. Or just go to tribe sim and try to download that GUI from that place file.

The only way to access them would be to go into your “images”, find the file, and copy the ID. This information is not used when it’s not entered, so there’s no way to steal something that isn’t used.

For the record. Security is never about absolute protection, there’s no such thing.
It’s about making it difficult enough to deter people from it.

Nearly every game out there is possible to be exploited and have its assets stolen.
Right now, the Roblox asset ID linking system just makes it exceptionally easy.

Using local addresses comes with its own issues, but for securing assets, it’s worth it 100%
For one, you have to upload the assets by the same name to every place you intend to use them.
This means keeping a local directory structure that is a duplicate of your game’s with every raw file.
To any developer that cares about theft, this is a small cost.

But no, just because data exists on Roblox’s side doesn’t mean 3rd party programs access it.
The whole reason they “reverse engineer” games they steal is because they don’t have the server scripts or anything server-sided that isn’t copied to the client.

Currently, the asset ID or file path is copied to the client. If you don’t enter the asset ID, it’s not copied to the client, so they don’t have it. Sure, there are other ways they “could” obtain the models or images, in theory, but the odds are they won’t, and when they do it would be rare. Compare that to right now when every kid with any copy of synapse can steal your place with the click of a button vs. a solution that doesn’t yet exist that would be much more work no matter what… this is a no-brainer.

You don’t ignore security because in theory one day someone can do something to bypass it. If that was the case, the internet would have no security at all.

Edit: For the record, I’m not even saying they should switch it entirely. For many developers, this isn’t even worth the effort. I’m just saying that the option is already there. There are just changes that they have made that break a lot of them. They could just give us a button “use local path” that puts the local path in instead of the asset ID (if the file is local) or give us correct information to know the paths and make sure asset loading works with local paths for everything.

A really good way is to make all of your local script variables

local

.

And make all of your functions local too with

local function

This makes it so that exploiters can’t decode your variable name and function names.


Also make sure that you keep ModuleScripts that only the server uses in ServerStorage or ServerScriptService to prevent the client from decompiling them.


A DMCA costs no money


That’s a very bad design choice and makes your game lag a lot.

An exploit could easilly just download the relative images. Sure it needs some extra code but there are very talented exploit devs who can do that.

Besides even if they didn’t they’d still get everything else expect remotely downloaded assets.

It won’t lag if you let the server handle as many tasks as necessary, but you obviously shouldn’t literally dump everything on the server. You should never trust anything that comes from clients anyways.

Yes, they can. If information has to reach the client, the exploit can read it. There is no workaround for that. The client has to load the images, so at some point it must be told where on the site they are stored.

Also, this only applies to instance data fetched over the network, not instances themselves. This data is usually immutable, so this could never be applied to models or other constructs that can change as gameplay goes on.

Things like HTTPS (or public key/similar encryptions, which I assume you’re referring to) are proven to be physically impossible to crack using a traditional computer in a human-reasonable amount of time. This is not the case here. This is a 5 minute fix on the exploit developer’s part for the multiple hours it can take to manage assets for a large game developer.

If a player has a slow network it definetly lags.

That’s why you simulate server behavior. Your server code doesn’t have to be identical.

Thats literally the same as doing stuff locally.

Here is what each should handle



I said simulate, not run the same code. Let’s say you have an inventory system, but don’t want to make players wait for each action to replicate. You send a remote to the server to request an item move, but in the meanwhile you place the item where it should have been if the request were successful. In case of failure, the server returns false and you undo the movement.

This has hardly anything in common with the server code as it just simulates server behavior. There is a considerable amount of lag, but it’s masked by the UI.

This is absolutely false. If you list an asset as /images/imagename that IS the address it loads from. It is loading it from the local directory using a local path. Roblox isn’t taking /images/imagename and decoding that into an asset ID, then loading it from the asset ID, they are loading it directly from that image name.

Even IF you used a program that can search memory for images and downloaded all of the images related to a game, something Synapse can’t even do, you would need other programs which I don’t really feel the need to advertise here, it still would not magically generate an internal hyperlink that’s not even being used. That hyperlink (the asset ID) isn’t used AT ALL when it’s not entered that way into the image/texture/etc. So IF you scanned and got the image out of memory, you would have an image you need to identify unless Roblox uses absolutely 0 encryption at all. Then you would have to know that image is what belongs there and upload it to your local place using that same name or use your own asset ID.

Yes, the website might have that image and asset ID associated with it, but that information is in no way ever loaded onto the client, it would be completely unnecessary to do so. While yes, you can steal whatever information is loaded to the client, you can’t magically conjure information that isn’t.

Before I ever got into developing, I used to write exploits, I know how they work and they are not magic. They have limitations. The fact you think things can be done that can’t shows exactly how little understanding you have of this subject.

Your assumption was wrong, so I’m not even going to bother addressing this. You very clearly do not know what you are talking about.

There’s no amount of talent that can compensate for things that do not exist. Synapse is a script injector that uses the same structure for injecting scripts that Roblox uses in Studio, giving it the ability to modify or inject a local script or change local settings for the client. Basically, anything the client is made to be able to do, Synapse can do, including executing remote events or even downloading a local copy of everything currently loaded. That is it and its limitations are entirely defined by that. There are plugins that use data within that but those plugins still are bound to the same rules and just represent various ways of using local data.

You can’t scan memory with Synapse, that’s an entirely different kind of exploit. While those do exist, there are none I’ve seen that target Roblox. Even the most popular one I know of does not work with Roblox. Because of the way Roblox launches instances and the fact they are kind of sandboxed within Roblox, you would have to design it specifically for this purpose. No one has done it because there’s really no demand/market for it. Maybe if Roblox actually had some security, this might change, but I wouldn’t count on that.

Yes, you still would get all the stuff you normally get. Local scripts, etc. but that’s not the point. The point is that you could choose to protect more assets if this was more open. Currently, it only works on textures applied directly to the asset and GUI images.

Roblox uses asset IDs as a sort of internal hyperlink allowing the same asset to be used in multiple places. This is how you can have a GUI uploaded to one place, then copy it to 50 places and it still works. However, local addresses have access permissions. No one can just access /images or /meshes off your place file. Even if you open-source your game, people still can’t access this. So when you take an image that is loaded locally, that image can’t be accessed except as executed locally. So if I made a GUI and addressed all the images locally, I could open-source it or download a copy of its place and those images would not be there. When you uploaded it to your place, it would still say /images/imagename, but in your local image directory, no such image exists.

Yes, it’s “possible” to get those images from local memory off the client, but that’s not even accessible through scripts. We (Roblox Devs) can’t write scripts that access local memory on the player’s computer or inside the Roblox client and neither can exploiters. When you get into stuff like that, you’re talking about memory scrapers that scan targeted regions of memory for images loaded into memory. While yes, these programs exist and are used all the time, there are none that currently work with Roblox. Even if there was, these programs use local memory on the client, they do not have access to the server address of the image. They usually output to a local directory and you have to dig through them. They often don’t even have the file names (though this depends on the encryption or lack of).

This makes it a LOT of work to steal and rebuild someone’s game. Go to any site for exploiting, like the popular one everyone knows as the source for Synapse stuff. This is looked down upon even in those communities. Most exploiters are not looking to help people steal games and assets. That garbage community is looked down upon even by exploiters.

I will tell you factually, I know exactly how these things are done. There is nothing currently in Synapse or any of those programs that allows it and there are currently no programs designed for this purpose that work on Roblox. Regardless if this changes in the future or not, there’s nothing that just makes this easy. This small piece of security would be more than enough to make me happy. I know developers that use this currently for their GUIs and textures (I do this too). This is why there are so many people on Hidden Devs selling clearly stolen models with no textures.

“Filing for DMCA is not free either.”

Submitting a DMCA notice to Roblox doesn’t cost anything unless you actually end up going to court over it (you won’t). There’s really no practical way (other than maybe that memory spike method that has been mentioned) of detecting or preventing client sided exploits and theft, and when it happens, submitting a DMCA notice is the thing to do about it. Despite your darndest of attempts to convince everyone otherwise, it’s free to do. Please read section 5 of the Roblox Terms of Use for more information on how to do this.

The site you mentioned only costs $200 because youre getting them to do it for you instead of doing it yourself.

The entire basis to this post is false. There is no “local directory” at play with the client. You can pop open Fiddler or similar tools and clearly see an HTTP request be issued out from your computer to fetch the asset by its URL/ID. I also tested the case in which the client disconnects from the server, and then dynamically loads the image for the first time. As expected, it still made out a request to the proper place and loaded the image fine.

image
image
image

It’s probably the case here that on join the server sends a mapping of “paths” to “IDs” to each client so that they can load the images at their leisure. A program such as Synapse would simply have to provide a method to fetch said ID given a path, as Roblox is presumably already doing internally, locally.

Lastly, it’s not constructive to say things such as “Clearly you know nothing about how programs like synapse work” or “You very clearly do not know what you are talking about”, especially when it is quite easily verifiable that your claim is wrong.

1 Like