diff --git a/bigbluebutton-html5/.meteor/packages b/bigbluebutton-html5/.meteor/packages
index 21cb9e5c425261f1820700399850f0761b71141e..4efa37a6ad4dc93c2ff2c3353e3597cc50a0dfae 100644
--- a/bigbluebutton-html5/.meteor/packages
+++ b/bigbluebutton-html5/.meteor/packages
@@ -28,4 +28,3 @@ cfs:power-queue
 cfs:micro-queue
 cfs:reactive-list
 stevezhu:lodash
-nitrolabs:cdn
diff --git a/bigbluebutton-html5/.meteor/versions b/bigbluebutton-html5/.meteor/versions
index afd639ce9ba48701cdaf0b47ceba522e696ee267..6a0728f210d663752b520be3e981edd13a8457cc 100644
--- a/bigbluebutton-html5/.meteor/versions
+++ b/bigbluebutton-html5/.meteor/versions
@@ -4,7 +4,6 @@ babel-compiler@7.2.4
 babel-runtime@1.3.0
 base64@1.0.11
 binary-heap@1.0.11
-blaze@2.1.9
 blaze-tools@1.0.10
 boilerplate-generator@1.6.0
 caching-compiler@1.2.1
@@ -55,9 +54,7 @@ mongo-decimal@0.1.0
 mongo-dev-server@1.1.0
 mongo-id@1.0.7
 nathantreid:css-modules@3.1.4
-nitrolabs:cdn@1.3.0
 npm-mongo@3.1.1
-observe-sequence@1.0.16
 ordered-dict@1.1.0
 promise@0.11.2
 random@1.1.0
@@ -71,15 +68,11 @@ routepolicy@1.1.0
 session@1.2.0
 shell-server@0.4.0
 socket-stream-client@0.2.2
-spacebars@1.0.13
 spacebars-compiler@1.1.3
 standard-minifier-css@1.5.2
 standard-minifier-js@2.4.0
 static-html@1.2.2
 stevezhu:lodash@4.17.2
-templating@1.2.15
-templating-compiler@1.2.15
-templating-runtime@1.2.15
 templating-tools@1.1.2
 tmeasday:check-npm-versions@0.3.2
 tracker@1.2.0
diff --git a/bigbluebutton-html5/imports/startup/server/index.js b/bigbluebutton-html5/imports/startup/server/index.js
index f5e606973a987a38455ac01b5cf73fa458422108..c91934b8d8381bd1becd59b7773b3f8fee07f252 100755
--- a/bigbluebutton-html5/imports/startup/server/index.js
+++ b/bigbluebutton-html5/imports/startup/server/index.js
@@ -1,4 +1,5 @@
 import { Meteor } from 'meteor/meteor';
+import { WebAppInternals } from 'meteor/webapp';
 import Langmap from 'langmap';
 import Users from '/imports/api/users';
 import fs from 'fs';
@@ -9,14 +10,37 @@ import Redis from './redis';
 var parse = Npm.require('url').parse;
 
 const AVAILABLE_LOCALES = fs.readdirSync('assets/app/locales');
-const CDN_URL = process.env.CDN_URL || '';
 
 Meteor.startup(() => {
   const APP_CONFIG = Meteor.settings.public.app;
   const env = Meteor.isDevelopment ? 'development' : 'production';
-
-  // Add CDN
-  WebAppInternals.setBundledJsCssPrefix(CDN_URL);
+  const CDN_URL = APP_CONFIG.cdn;
+
+  if (CDN_URL) {
+    // Add CDN
+    BrowserPolicy.framing.disallow();
+    BrowserPolicy.content.disallowEval();
+    BrowserPolicy.content.allowInlineScripts();
+    BrowserPolicy.content.allowInlineStyles();
+    BrowserPolicy.content.allowImageDataUrl(CDN_URL);
+    BrowserPolicy.content.allowImageOrigin(CDN_URL);
+    BrowserPolicy.content.allowFontDataUrl(CDN_URL);
+    BrowserPolicy.content.allowFontOrigin(CDN_URL);
+    BrowserPolicy.content.allowOriginForAll(CDN_URL);
+    WebAppInternals.setBundledJsCssPrefix(CDN_URL + APP_CONFIG.basename);
+
+    var fontRegExp = /\.(eot|ttf|otf|woff|woff2)$/;
+
+    WebApp.rawConnectHandlers.use('/', function(req, res, next) {
+      if (fontRegExp.test(req._parsedUrl.pathname)) {
+        res.setHeader('Access-Control-Allow-Origin', '*');
+        res.setHeader('Vary', 'Origin');
+        res.setHeader('Pragma', 'public');
+        res.setHeader('Cache-Control', '"public"');
+      }
+      return next();
+    });
+  }
 
   Logger.warn(`SERVER STARTED.\nENV=${env},\nnodejs version=${process.version}\nCDN=${CDN_URL}\n`, APP_CONFIG);
 });
diff --git a/bigbluebutton-html5/imports/ui/components/activity-check/component.jsx b/bigbluebutton-html5/imports/ui/components/activity-check/component.jsx
index d04f447731d30671f38bd53f02e47afe40a6bbcf..628a2e717a6b35050ce5bbddefac51d1ebd94748 100644
--- a/bigbluebutton-html5/imports/ui/components/activity-check/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/activity-check/component.jsx
@@ -75,7 +75,7 @@ class ActivityCheck extends Component {
   }
 
   playAudioAlert() {
-    this.alert = new Audio(`${Meteor.settings.public.app.cdn || Meteor.settings.public.app.basename}/resources/sounds/notify.mp3`);
+    this.alert = new Audio(`${Meteor.settings.public.app.cdn + Meteor.settings.public.app.basename}/resources/sounds/notify.mp3`);
     this.alert.play();
   }
 
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-test/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-test/container.jsx
index 3f0fd323b1c52fe799c1f72ab8d8e75607a7d60a..39864218dbbebe412ef7fff144971b70be6b1811 100644
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-test/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-test/container.jsx
@@ -8,7 +8,7 @@ const AudioTestContainer = props => <AudioTest {...props} />;
 export default withTracker(() => ({
   outputDeviceId: Service.outputDeviceId(),
   handlePlayAudioSample: (deviceId) => {
-    const sound = new Audio((Meteor.settings.public.app.cdn || Meteor.settings.public.app.basename) + 'resources/sounds/audioSample.mp3');
+    const sound = new Audio((Meteor.settings.public.app.cdn + Meteor.settings.public.app.basename) + 'resources/sounds/audioSample.mp3');
     if (deviceId && sound.setSinkId) sound.setSinkId(deviceId);
     sound.play();
   },
diff --git a/bigbluebutton-html5/imports/ui/components/chat/alert/audio-alert/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/alert/audio-alert/component.jsx
index 1f81fc473df2c0db6531d95feb4708b1006bfcfd..d59fbff723761a41318280f34f81dcc9bd21b540 100644
--- a/bigbluebutton-html5/imports/ui/components/chat/alert/audio-alert/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/chat/alert/audio-alert/component.jsx
@@ -8,7 +8,7 @@ const propTypes = {
 class ChatAudioAlert extends React.Component {
   constructor(props) {
     super(props);
-    this.audio = new Audio(`${Meteor.settings.public.app.cdn || Meteor.settings.public.app.basename}/resources/sounds/notify.mp3`);
+    this.audio = new Audio(`${Meteor.settings.public.app.cdn + Meteor.settings.public.app.basename}/resources/sounds/notify.mp3`);
     this.handleAudioLoaded = this.handleAudioLoaded.bind(this);
     this.playAudio = this.playAudio.bind(this);
   }
diff --git a/bigbluebutton-html5/imports/ui/components/polling/component.jsx b/bigbluebutton-html5/imports/ui/components/polling/component.jsx
index 1dac1f24f555335220766dedc5b4dbcf7085affd..9ee34e6a9d1a114e1de461186a3ff221af36ba65 100644
--- a/bigbluebutton-html5/imports/ui/components/polling/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/polling/component.jsx
@@ -30,7 +30,7 @@ class Polling extends Component {
   }
 
   play() {
-    this.alert = new Audio(`${Meteor.settings.public.app.cdn || Meteor.settings.public.app.basename}/resources/sounds/Poll.mp3`);
+    this.alert = new Audio(`${Meteor.settings.public.app.cdn + Meteor.settings.public.app.basename}/resources/sounds/Poll.mp3`);
     this.alert.play();
   }
 
diff --git a/bigbluebutton-html5/imports/ui/components/video-provider/video-button/service.js b/bigbluebutton-html5/imports/ui/components/video-provider/video-button/service.js
index cde154dfe2b7f8396d344420e4c954eb3aa9ff01..99ad79e5ab71615007d695505bb50eeeb67918c5 100755
--- a/bigbluebutton-html5/imports/ui/components/video-provider/video-button/service.js
+++ b/bigbluebutton-html5/imports/ui/components/video-provider/video-button/service.js
@@ -4,7 +4,7 @@ import Auth from '/imports/ui/services/auth';
 import Users from '/imports/api/users/';
 import VideoService from '../service';
 
-const baseName = Meteor.settings.public.app.cdn || Meteor.settings.public.app.basename;
+const baseName = Meteor.settings.public.app.cdn + Meteor.settings.public.app.basename;
 
 const isSharingVideo = () => {
   const userId = Auth.userID;
diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/pencil-draw-listener/component.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/pencil-draw-listener/component.jsx
index 2d4c18c57f86ef822fcf5c550e02019f6121c57d..79134436ea66eaed56f238038cbc64ce405c5a31 100755
--- a/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/pencil-draw-listener/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/pencil-draw-listener/component.jsx
@@ -224,7 +224,7 @@ export default class PencilDrawListener extends Component {
   }
 
   render() {
-    const baseName = Meteor.settings.public.app.cdn || Meteor.settings.public.app.basename;
+    const baseName = Meteor.settings.public.app.cdn + Meteor.settings.public.app.basename;
     const pencilDrawStyle = {
       width: '100%',
       height: '100%',
diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/text-draw-listener/component.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/text-draw-listener/component.jsx
index cf5f92d4140f6b549a95145a185536bded226397..57a279d264c057fa086f2450d8705b6e0797606e 100755
--- a/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/text-draw-listener/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-overlay/text-draw-listener/component.jsx
@@ -387,7 +387,7 @@ export default class TextDrawListener extends Component {
   }
 
   render() {
-    const baseName = Meteor.settings.public.app.cdn || Meteor.settings.public.app.basename;
+    const baseName = Meteor.settings.public.app.cdn + Meteor.settings.public.app.basename;
     const textDrawStyle = {
       width: '100%',
       height: '100%',