I’m building a marketplace for 3d assets and I need to have a 3d viewer that allows the user to view the 3d models before downloading, but I need the files to still be protected to where they can’t be downloaded.
Is there a way to not allow the user to publicly download the 3d model and texture files that i'm showing?
I am glad you are asking this question, because it is certainly the up most important security question pertinent to ALL webGL (THREE.js) applications.
From what I have seen thus far almost nobody (standards, libs, frameworks) provides a solution to such problematic, because it is a complex issue that span into another category of expertise rarely found in the domain of computer graphics and which is (most of the time) done last in computer development: Security.
There is certainly multiple aproach that would solve the problem temporarely, but to do it right once and for all, it takes a strong fundation that affects everything from the ground up: processes, code, UIs, scripts, object files… You wish to protect the 3d models, but you may also want to protect your scripts, so hackers would not be able to clone your site easily or find an exploit to take control, or bypass game logic, etc…
The only long term approach to resolve this problem is to apply a series of web security best practices :
- multiple encryption levels
- server side token verification
- multiple proprietary/private steps
Note: there is a tradeoff between performance & security strength when applying multiple steps specific to each case scenario.
Yes, this solution takes a lot of man hours and another kind of expertise in order to do it right. Plus, every security solution is not 100% bulletproof neither, but the time spend to crack such approach would be so large that it makes no sense to apply energy cracking it.
If you need a solution right away and don’t want to spent time in security dev., I know one company providing such security service via a middleware: http://multivers3D.fr
Hope this info will help you move further. I know, it may not be the answer you were expecting, yet again, it is a complex problem touching everyone, thank you for asking!
That’s not possible, except for textures you could watermark, or for example merged watermark geometries. Encryption doesn’t matter, once it’s decoded you can grab the buffers.
You can only make it harder by using a custom format, and watermark things, serve lower res previews, or even just no 3D preview at all, like a 360 turntable.
I challenge anyone to get this model into its json format (even from the buffer):
Note: The model is in the main site intro
The format doesn’t matter, he wants to preview them, once you display it the buffers are exposed. One could even extract it from outside chrome, and automate this process with a tool.
@Fyrestar, let’s not change the subject, the question is “there a way to not allow the user to publicly download the 3d model and texture files”
The solution is to encrypt the object files and put a watermark on the texture files as @anon13924900 suggested.
The buffer security issue is another problem that deserves its own thread.
I am lekxi, discourse doesn’t react to github changes.
The point is, he wants to preview all of them so it is about the buffers. One tool and you could automate to download all models through WebGL. Encrypting the files only would be useful when the preview isn’t the actual real model in WebGL. Hidden watermark geometries would at least make it hard to remove them.
Here is an approach to the buffer issue:
For the merged geometry, that’s what i suggested but only for this preview scenario, it would procedurally embed watermark symbols inside the mesh so
The polycount would probably be an issue in productive usage
It would be a lot work to remove all of it
Some might not even notice it (they are scaled to precision limit)
For the indices offset or something like this i don’t think we can do this with WebGL (indices can’t get altered on the gpu), as it requires a fully decoded and exposed state.
For real world applocations i don’t see any full protection method, anyone who wants it will get it. My opinion, and a lot other you will find around this topic is: don’t waste your time with such protection things that won’t give much protection at all.
I use a custom asset format which comes fully binary in a chunked stream, requested from a repository api which requires a account, that’s protection enough for me, as it’s no open source. It’s worth making it harder and proprietary, but that’s all. In the end one could always grab it directly from the GPU.
What he want’s to do is a different case, the watermark method for both, or preview as image / turntable would be reasonable, but not in a real application. I would’nt count on anything else, as such a market place would worth the effort to develop a tool to automate the extraction. Other marketplaces also don’t show 3D previews (such as turbosquid) and there’s a good reason for it.
My suggestion, just allow the authors to preview them, choose a pose for a image, maybe generate a turntable stripe, but don’t serve 3D previews in the market. The authors probably won’t trust it, and you can ensure to serve constant traffic for the previews, some might have several textures or a large geometry.
@Fyrestar @anon13924900, who ever you are, please stop confusing everyone. If one is not able to dissociate data protection with its rendering, there can be no progress! Again, @atylerrice asked for data protection…
People looking at such post want real solutions and not personal opinion on what is “impossible” or takes too much time to implement.
This is out of context for public work, plus a stream is not protected if it is not encrypted.
If you wish to discuss, in an organised fashion, the data rastering issue, the post is created and opened for suggestions…
I’m sorry if this confuses you, he asked for a solution to ensure no one can get the assets, i just suggested a reasonable solution as there is no encryption once it’s displayed in WebGL.
Is there a way to not allow the user to publicly download the 3d model and texture files that i’m showing?
Just search the web, you’ll get the same answers.
No need to go in a wild search, if you look at this discourse, you will get a different answer. You need to secure the files by encryption from being publicly downloaded (as the title of this question specifies). Without this first action, there is no need to go further.
Then, if the person wants to protect the webGL buffers, it is another problematic. Some people are going to resolve this issue and others may want to take the risk without securing it. It will depend on their use cases.
@Fyrestar i find reasonable the answer that you have linked. @INF1N1T “No need to go in a wild search, if you look at this discourse, you will get a different answer”, isn’t a bit too pretentious? I’m sorry if I can look pedant at your eyes but I like threejs and I’m happy that finally there is a forum, and I would like that all the people that post answers and questions feels comfortable doing it, and not scared. Feel free to DM me for any clarification
First, BMP and OBJ file up to the server to access prohibited by htaccess.
-----------htaccess-------------------------- <Files ~ "\.(obj|bmp|mtl)$"> deny from all </Files> order Allow,Deny Allow from all Deny from env=shutout -------------------------------------
Next, in the program, call the php file with ‘GET’ using XMLHttpRequest.
The content of the php file should be as follows.
---------php---------------------------- $bmpfile = 'xxx.bmp'; //bmp file $uri = 'data:' . mime_content_type($bmpfile) . ';base64,'; $uri .= base64_encode(file_get_contents($bmpfile)); $arr['bmp'] = $uri; $objfile = 'xxx.obj'; //obj file $arr['obj'] = file_get_contents($objfile); echo json_encode($arr); -------------------------------------
Read BMP and OBJ file with responseText of JSON.parse.
With this, I do not link directly from the browser, so I think it is safe.
If “Publicly downloading files” means going into the developers to > finding the file > saving a local copy of it.
The first line of defence would be to encrypt the file which may come with some cost of performance.
But, if those file are already rendering on the screen, there is no ideal defence for it. The actual files can be dynamically recreated and can be downloaded.
One different solution can be : you can simply render whatever graphics you want on the server and send the image data as a png to the web page.
But again this method has it own limitations.
We figured out the way to corrupt the GLB files (Using an encryption method), Then load that file as Arraybuffer, Decode the file as text and load them in the viewer, Ultimately the loaded model would still appear corrupted to anyone who has downloaded through the inspector.
Do you have a source repo for this to share? Or would that effectively be giving the keys out to your decryption method?
We figured out the process of Encypting / Decrypting the GLB file (Not exactly an encyption more of a a corrupting the file and correct it back while loading,
You need to use a Hex editor and edit (Replace any character at the start and end of the file and note the location of the modification), Then save that as the the “Corrupted.GLB”.
In Threejs, Instead of GLB Loader, You should use the arraybuffer to read the GLB file as and replace the Corrupted places with the proper words / characters
(Eg, The GLB file always starts with GLTF (Position 0 to 3), So If I would have replaced that with something else then I should revert the characters at that positions back to “GLTF”).
And once the replace is done, Then you can directly load the array buffer and instantiate your model.
This whole method prevents anyone to open the GLB file in any 3D Modelling tools, It would just throw error messages that the model is corrupted.