MCederholm

Content Security Policy and the ArcGIS API for JavaScript

Blog Post created by MCederholm on Sep 5, 2019

Does the ArcGIS API for JavaScript work with Content Security Policy?  The short answer is yes, but which version you're using (4.x vs. 3.x) determines the approach to take.  Dojo allows you to configure support CSP support:

 

// mapconfig.js
window.dojoConfig = {
     async: true,
     has: {"csp-restrictions": true}
}

 

So the following example works [note that blob support must be enabled]:

 

<!DOCTYPE html>
<html>
<head>
     <meta charset="utf-8" />
     <meta http-equiv="content-security-policy"
               content="script-src 'self' https://js.arcgis.com blob:; object-src 'self'" />

     <title>Using ArcGIS API for JavaScript with CSP</title>
     <script src="./mapconfig.js"></script>
     <link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/css/main.css">
     <script src="https://js.arcgis.com/4.12/"></script>
     <style>
          html, body, #map {
               padding: 0;
               margin: 0;
               height: 100%;
               width: 100%
          }
     </style>

</head>
<body>
     <div id="map"></div>
     <script src="./mapinit412.js"></script>
</body>
</html>
//mapinit412.js
require([
     "esri/Map",
     "esri/views/MapView"
], function (Map, MapView) {

     var map = new Map({
          basemap: "topo-vector"
     });

     var view = new MapView({
          container: "map",
          map: map,
          center: [-118.71511, 34.09042],
          zoom: 11
     });
});

 

Note that CSP doesn't allow any inline JavaScript, so even the simplest blocks of code need to be in a separate file.

 

What about 3.x?  Aye, there's the rub.  Although Dojo supports CSP, the ArcGIS API 3.x does not: it contains code that CSP will reject.  Here's an example from VectorTileLayerImpl.js:

 

l = Function("return this")();

 

The only way to get 3.x to work with CSP is to include the dreaded 'unsafe-eval' in the policy string.  With that, the following example will work:

 

<!DOCTYPE html>
<html>
<head>
     <meta charset="utf-8" />
     <meta http-equiv="content-security-policy"
               content="script-src 'self' 'unsafe-eval' https://js.arcgis.com; object-src 'self'" />

     <title>Using ArcGIS API for JavaScript with CSP</title>
     <script src="./mapconfig.js"></script>
     <link rel="stylesheet" href="https://js.arcgis.com/3.29/esri/css/esri.css">
     <script src="https://js.arcgis.com/3.29/"></script>
     <style>
          html, body, #map {
               padding: 0;
               margin: 0;
               height: 100%;
               width: 100%
          }
     </style>

</head>
<body>
     <div id="map"></div>
     <script src="./mapinit329.js"></script>
</body>
</html>
// mapinit329.js
require(["esri/map"], function (Map) {
     var map = new Map("map", {
          center: [-118, 34.5],
          zoom: 8,
          basemap: "topo"
     });
});

Outcomes