0

I have a web application that allows user view our data that front-end in JavaScript fetches the data via a Restful request to back-end, then render it in the application. The size of each data can range from few KB to 500MB where most of them are around 100MB.

According to the requirement, this data is for viewing only therefore should not be downloaded by user.

From what I researched there is no ultimate way to prevent a user from getting the data but to increase the difficulty. So the idea is to make it harder for a user to download the data, at least not easily via developer consoles.

I'm thinking applying a symmetric encryption on the file, AES-128 seems a good choice but that means a key needs to be hid in JavaScript which can easily be found by users.

This comes to the question, for my problem, is symmetric encryption useful? what are other drawbacks or security vulnerabilities it would introduce?

In general, what is a proper way to prevent or make it difficult for users from downloading restful resources?


Edit: reworded title

The application is for really small groups of clients that i'm pretty sure there won't be info change on using the software. I know it's an optimistic believe but If the goal is really to just increase the difficulty a bit so that users won't directly use resources they downloaded from developer consoles, what would be a possible way?

  • 3
    If you remove "restful" from the question, the question is not materially different. As long as the user controls the devices used to view, they can always download the data you sent to them. – Lie Ryan Jan 15 at 1:35
  • I agree. That's the reason I tried to increase the difficulty a bit by applying encryption. In this case they cant use or view the data without figuring out how to decrypt it – eth4io Jan 15 at 2:00
  • While I understand you are trying to take a reasonable measure to make the data more difficult to misuse, you have to realize in today's world it just takes one person to figure out how to bypass your clever solution and upload a hack or add-in. Once the cat is out of the bag, everyone can use it. YouTube doesn't want me to download their videos (without paying for Red) but there's a dozen addins available that do exactly that, and you are not as well-resourced as YouTube. I suggest you focus your efforts on creating value so that users won't want to download the data,. – John Wu Jan 15 at 2:36
  • Thanks John. Totally understand and I love the "idea of it just takes one person to hack it". Nonetheless the application is for really small groups of clients that i'm pretty sure there won't be info change on using the software. I know it's a optimistic believe but If the goal is really to just increase the difficulty a bit so that users won't directly use resources they downloaded from developer consoles, what would be a possible way? (i'll append this info in the question) – eth4io Jan 15 at 3:21
  • 1
    The internet is a device designed to easily copy data. You would be better off allowing the users to access low-res models, that you don't care if they copy. Hi-res models must be paid for in advance, or they must pay for a high-res render (obtained by setting up the low-res scene and requesting a thumbnail/full render from your server). Alternately just give the high-res models over in plain text, and pay for a legal department to hunt down and enforce licensing. Maybe a mix of both. – Kain0_0 Jan 15 at 5:31
4

is symmetric encryption useful? what are other drawbacks or security vulnerabilities it would introduce?

No. The user can just intercept the data after your app has decrypted it.

In general, what is a proper way to prevent or make it difficult for users from downloading restful resources?

The proper way is to not worry about it. The user can always take screenshot or snap a photo of the screen, there's nothing you can do about that. To limit exposure, don't send your entire database to the client. Instead just sent to the client what it needs to generate the screen. There's no reason to send 500MB of data to display data when there user can only ever see one screen's worth of data at a time.

| improve this answer | |
  • I agree that I shouldn't expect a way to prevent them from intercepting it. The difference I tried to make was whether or not every user can easily get the raw data via developer consoles. My hypothesis was by encrypting data, resources show in developer consoles would not be directly usable therefore it became more difficult for some users. – eth4io Jan 15 at 2:10
  • Regarding sending 500MB data, the reason why each file is that big is it contains geometries for 3D models – eth4io Jan 15 at 2:18
  • 2
    @eth4io: if the user can use a developer console, it'll be minimal additional difficulty to just call the decryption function. If its 3D models, you'd want to avoid client side rendering, you'd be looking into technologies similar to Google Stadia or GeForce Now to avoid client side rendering, i.e. you'd just stream video rendered on the server you control. – Lie Ryan Jan 15 at 3:43
3

According to the requirement, this data is for viewing only therefore should not be downloaded by user.

As you know, viewing something (henceforth called “document”) from internet requires downloading it. You could add extra steps… However, you also need to provide the client the code to do those extra steps… Then the user can take the document after your code has processed it.

About cryptography, consider:

  • It makes showing the document slower. That is, getting a document in the clear (not encrypted) takes resources.
  • It can obfuscate contents.

Using cryptography does not prevent the user from getting the document in the clear, it just means that the user has to get it from the part of your code where cryptography is already done.


About symmetric vs asymmetric cryptography, any user that can view the document would have a valid key to decipher it. Assuming you already has a good access control solution (authentication and authorization), and the connection is on a secure connection (HTTPS). Additional asymmetric cryptography to view the content adds no security.

To make sure, analyze the properties of information:

  • Integrity. The secure connection ensure this.
  • Availability. Asymmetric cryptography does not change this.
  • Confidentiality. The secure connection and your access control solution ensures this.

Plus, HTTPS authenticates the server. That is, it guarantees to the user that the server is the server it claims to be (and not some phishing site). Therefore, using asymmetric cryptography to guarantee the identity of the server via digital signature is also redundant. In fact, HTTPS already uses asymmetric cryptography.


In general, what is a proper way to prevent or make it difficult for users from downloading restful resources?

We can make it harder to create a solution that grants access to the document in the clear. Know that once such solution has been created, it can be reused. In fact, it can be shared with virtually every user out there… meaning the effort to create such solution only has to be done once. And thus, the marginal cost of downloading a document in clear – regardless of how hard we manage to make the initial effort – goes to zero. Thus, you can only consider these measures as a deterrent for somebody doing it in the first place… and even then, you can never be fully confident that nobody will do it… thus, this could all be wasted effort.

You must consider not caring if people download the document in clear. Is the cost of people downloading the documents in clear worth the effort (and side effects)? You say the user base is small, arguably the impact of them downloading the document in clear is small too.

Is the effort really justified even if it cannot guarantee nobody will download documents in clear?

How much time and resources are you willing to expend on this?

Consider also the side of the user trying to get the document in clear… one possibility is that you intent to sell the documents. In which case, you want to make the effort of downloading them without paying hard enough that paying seems a good value proposition. Said in other terms, you want to sell the document cheap enough that paying seems a better idea than figuring out how to download without paying. Other possibility is that you do not intent to sell the documents… if we conceptualize this as a price tag of infinity… yeah, figuring out how to download without pay sounds viable. In practice, the user will be comparing against opportunity cost. Can they get a cheap alternative from another site? How does the effort of figuring out how to download the document in clear comparing against them figuring out how to create their own (of similar quality)? Do they really, really, really want that document? (hey, maybe if the documents are trash nobody will want to figure out how to download them without pay).


Alright, let us talk mitigation...

First thing that comes to mind is single use tokens. It does not prevent downloading by any means. It just means that if the user got the request code to download, it won’t work again because it has a token that has already been used. It complicates the download in that you do it in two phases: 1) first the client request access to a file, gets the token. 2) the client downloads with the token.

The server could reject creating tokens if the client is making them too fast (such as a script downloading documents). You may also add a third party captcha solution each time a token request is sent, meaning that whatever solution cannot be completely automated (easily). Yes, that means that viewing a document requires a captcha.

I am aware that single use token do not prevent grabbing the already downloaded version from the browser. We will mitigate that too. In fact, with each additional mitigation single use tokens will make more sense, I promise.

Second, you want good encapsulation. If I can reach the variable that holds the data (in the clear), or I can call a method that returns it, I can dump it easily. Thus, encapsulate it to make it hard.

Third, you want code obfuscation. If I cannot find something that gives me the data directly, I will rather try to read your code to create a function (that I can run in console) that mimics what it does, except it gives the data to me (note: if you are using the single use token, this also includes figuring out how to get a new token, thus a single use token makes this hard already). You want to make this task harder. Use obfuscation for that.

Remember that cryptography obfuscate contents, you can use it for that goal. In fact, you can use it on script code for extra kicks (decipher code + eval).

The property of cryptography being slow could also serve as a deterrent. In fact, the marginal cost will never be zero, it will be at least the time and computing resources needed for this. Which could be an argument to use slower cryptography.

If you are suing cryptography you can add one more hurdle in not using the same key for every file. Meaning that the solution product used to download documents in clear cannot rely on a single hard coded key… which makes it harder to create.

Furthermore, you could not only use a different key per file. You would cipher the file again for each request. Remember that single use token? Replace that with a single use key. When the token is requested, you actually cipher the document and return the key. Then the client downloads the document and decipher with the key. Now, not only is your client slower. Your server is slower.

Note: Solutions that mean a worse user experience (slowness or captcha), could translate to less user retention. In fact, if you over do it, people could be interested downloading the documents in clear, so they can have access to them without that darn slow application of yours. Note that if nobody uses your application, nobody downloads the document in clear from your application.


By the way, are you confident you do not have cross site scripting or cross site request forgery vulnerabilities? I hope you do not have those.


Once the document is on the client machine, it is under the power of the user. We can find inspiration on how to avoid sending the document to the client from stores where people can buy the documents in clear. Sites like that will often use lower quality versions for preview. They could be versions with less detail, versions with water marks (or similar solutions), partial versions, reproductions in a less useful format.

Regarding sending 500MB data, the reason why each file is that big is it contains geometries for 3D models

  • Versions with less detail: low-poly.
  • Versions with water marks: add geometry, add noise (move each vertex some random amount).
  • Partial version: just show a part of the model as preview.
  • Reproductions: Pre-render.

Maybe if the documents are trash nobody will want to figure out how to download them without pay

These are real solutions. Showing these instead of the real document to a user that should not download means that the user has nowhere from where to get the document in clear. You would protect the real download by good old access control.


Finally, if what you are thinking is that your users will download your models, use them to make a video game, gain profit from it, and not pay you any loyalties… use legal protections instead.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.