24 Feb 2017

Securing your Forge Viewer token behind a proxy

Default blog image

This post illustrates how to strengthen security of your Forge Viewing Application by using a proxy to avoid passing a token to the client JavaScript code.

The issue 

In order for the viewer to get access to the viewable resources on the Autodesk Cloud and load the models on the client page, it needs to add a bearer token to the requests headers.

To make this possible, the basic approach is to expose a route on your server that returns the token, your client code will then use that route to request a token whenever the viewer needs it. Those steps are described in the basic viewer step-by-step tutorial.

The minimal scope that is required at the moment is "data:read", however this scope also allows to perform GET requests on OSS buckets and objects. It would be relatively trivial for an attacker to analyze the source code of your page or monitor the http traffic, intercept the token and the URN of the model and by base-64-decoding it, he can harvest the seed files stored on that bucket, i.e downloading original CAD files.

 

The workarounds

There are two efficient ways to prevent this from happening:

1/ A Forge Platform solution:

There are internal discussions going on the moment in order to secure that workflow. One possibility would be to provide a "token:read" scope that only allows the viewer to download viewable resources but prevents accessing seed files on OSS. There are other possibilities being evaluated by the development team, but it is too early to share those topics publicly

 

2/ A third party solution: 

Using a proxy on the server application that will securely append the token to the viewer requests, hence protecting it from being exposed to the client at all. This is a solution that third-party applications can implement straight away without waiting implementation on the Forge Platform, so I will expose it today in that post.

The impact on your existing server/client code should be minimal, here is how to proceed:

 

Server Side

I am today exposing the Node.js code to achieve that, later we will show you how to implement that in an ASP.Net application, but the principle remains the same.

Add an additional route to your app that will handle all viewer GET requests:

import LMVProxy from './api/endpoints/lmv-proxy' 
 
var app = express() 
 
app.get('/lmv-proxy/*', LMVProxy.get) 
 
// ... initialize other routes ... 

The code for the proxy route is exposed below:

 

Client Side

A new API has been added in the viewer version 2.13 and will slightly change in version 2.14. Basically you can remove the getAccessToken field in the Initializer options and specify the proxy route the viewer has to use for its GET requests:

const options = { 
  env: 'AutodeskProduction' 
  //getAccessToken: ... //not needed, token provided by proxy on server-side 
) 
 
Autodesk.Viewing.Initializer (options, () => { 
   
  //2.13 
  Autodesk.Viewing.setApiEndpoint( 
    window.location.origin + '/lmv-proxy') 
 
  //2.14 - not yet avail in PROD 
  //Autodesk.Viewing.setEndpointAndApi( 
  //  window.location.origin + '/lmv-proxy', 'modelDerivativeV2') 
 
  // instantiate viewer and load model as before ... 
})

Et voilà, you can now enjoy secure viewing! Complete examples using that approach are available at forge-react-boiler.nodejs and forge-rcdb.nodejs

Related Article