diff --git a/frontend/src/download.js b/frontend/src/download.js
index 00208085..f16adf40 100644
--- a/frontend/src/download.js
+++ b/frontend/src/download.js
@@ -9,7 +9,8 @@ $(document).ready(function() {
   $('#send-file').click(() => {
     window.location.replace(`${window.location.origin}`);
   });
-  const download = () => {
+  $('#download-btn').click(download);
+  function download() {
     const fileReceiver = new FileReceiver();
     const name = document.createElement('p');
     const $btn = $('#download-btn');
@@ -37,20 +38,20 @@ $(document).ready(function() {
     fileReceiver.on('decrypting', isStillDecrypting => {
       // The file is being decrypted
       if (isStillDecrypting) {
-        console.log('Decrypting')
+        console.log('Decrypting');
       } else {
-        console.log('Done decrypting')
+        console.log('Done decrypting');
       }
-    })
+    });
 
     fileReceiver.on('hashing', isStillHashing => {
       // The file is being hashed to make sure a malicious user hasn't tampered with it
       if (isStillHashing) {
-        console.log('Checking file integrity')
+        console.log('Checking file integrity');
       } else {
-        console.log('Integrity check done')
+        console.log('Integrity check done');
       }
-    })
+    });
 
     fileReceiver
       .download()
@@ -84,7 +85,5 @@ $(document).ready(function() {
         Raven.captureException(err);
         return Promise.reject(err);
       });
-  };
-
-  window.download = download;
+  }
 });
diff --git a/frontend/src/fileReceiver.js b/frontend/src/fileReceiver.js
index 0404bda8..17b5393f 100644
--- a/frontend/src/fileReceiver.js
+++ b/frontend/src/fileReceiver.js
@@ -61,52 +61,60 @@ class FileReceiver extends EventEmitter {
         true,
         ['encrypt', 'decrypt']
       )
-    ]).then(([fdata, key]) => {
-      this.emit('decrypting', true);
-      return Promise.all([
-        window.crypto.subtle.decrypt(
-          {
-            name: 'AES-GCM',
-            iv: hexToArray(fdata.iv),
-            additionalData: hexToArray(fdata.aad)
-          },
-          key,
-          fdata.data
-        ).then(decrypted => {
-          this.emit('decrypting', false);
-          return new Promise((resolve, reject) => {
-            resolve(decrypted);
-          })
-        }),
-        new Promise((resolve, reject) => {
-          resolve(fdata.filename);
-        }),
-        new Promise((resolve, reject) => {
-          resolve(hexToArray(fdata.aad));
-        })
-      ]);
-    }).then(([decrypted, fname, proposedHash]) => {
-      this.emit('hashing', true);
-      return window.crypto.subtle.digest('SHA-256', decrypted).then(calculatedHash => {
-        this.emit('hashing', false);
-        const integrity = new Uint8Array(calculatedHash).toString() === proposedHash.toString();
-        if (!integrity) {
-          return new Promise((resolve, reject) => {
-            console.log('This file has been tampered with.')
-            reject();
-          })
-        }
-        
+    ])
+      .then(([fdata, key]) => {
+        this.emit('decrypting', true);
         return Promise.all([
+          window.crypto.subtle
+            .decrypt(
+              {
+                name: 'AES-GCM',
+                iv: hexToArray(fdata.iv),
+                additionalData: hexToArray(fdata.aad)
+              },
+              key,
+              fdata.data
+            )
+            .then(decrypted => {
+              this.emit('decrypting', false);
+              return new Promise((resolve, reject) => {
+                resolve(decrypted);
+              });
+            }),
           new Promise((resolve, reject) => {
-            resolve(decrypted);
+            resolve(fdata.filename);
           }),
           new Promise((resolve, reject) => {
-            resolve(fname);
+            resolve(hexToArray(fdata.aad));
           })
         ]);
       })
-    })
+      .then(([decrypted, fname, proposedHash]) => {
+        this.emit('hashing', true);
+        return window.crypto.subtle
+          .digest('SHA-256', decrypted)
+          .then(calculatedHash => {
+            this.emit('hashing', false);
+            const integrity =
+              new Uint8Array(calculatedHash).toString() ===
+              proposedHash.toString();
+            if (!integrity) {
+              return new Promise((resolve, reject) => {
+                console.log('This file has been tampered with.');
+                reject();
+              });
+            }
+
+            return Promise.all([
+              new Promise((resolve, reject) => {
+                resolve(decrypted);
+              }),
+              new Promise((resolve, reject) => {
+                resolve(fname);
+              })
+            ]);
+          });
+      });
   }
 }
 
diff --git a/frontend/src/fileSender.js b/frontend/src/fileSender.js
index 1fdf149c..888e1de4 100644
--- a/frontend/src/fileSender.js
+++ b/frontend/src/fileSender.js
@@ -61,8 +61,8 @@ class FileSender extends EventEmitter {
           window.crypto.subtle.digest('SHA-256', plaintext).then(hash => {
             self.emit('hashing', false);
             self.emit('encrypting', true);
-            resolve({plaintext: plaintext, hash: new Uint8Array(hash)});
-          })
+            resolve({ plaintext: plaintext, hash: new Uint8Array(hash) });
+          });
         };
         reader.onerror = function(err) {
           reject(err);
@@ -81,14 +81,17 @@ class FileSender extends EventEmitter {
               },
               secretKey,
               file.plaintext
-            ).then(encrypted => {
+            )
+            .then(encrypted => {
               self.emit('encrypting', false);
               return new Promise((resolve, reject) => {
                 resolve(encrypted);
-              })
+              });
             }),
           window.crypto.subtle.exportKey('jwk', secretKey),
-          new Promise((resolve, reject) => { resolve(file.hash) })
+          new Promise((resolve, reject) => {
+            resolve(file.hash);
+          })
         ]);
       })
       .then(([encrypted, keydata, hash]) => {
diff --git a/frontend/src/upload.js b/frontend/src/upload.js
index f91c09b6..69935376 100644
--- a/frontend/src/upload.js
+++ b/frontend/src/upload.js
@@ -8,8 +8,10 @@ $(document).ready(function() {
   gcmCompliant().catch(err => {
     $('#page-one').hide();
     $('#compliance-error').show();
-  })
+  });
 
+  $('#file-upload').change(onUpload);
+  $('#page-one').on('dragover', allowDrop).on('drop', onUpload);
   // reset copy button
   const $copyBtn = $('#copy-btn');
   $copyBtn.attr('disabled', false);
@@ -61,11 +63,11 @@ $(document).ready(function() {
   });
 
   // on file upload by browse or drag & drop
-  window.onUpload = event => {
+  function onUpload(event) {
     event.preventDefault();
     let file = '';
     if (event.type === 'drop') {
-      file = event.dataTransfer.files[0];
+      file = event.originalEvent.dataTransfer.files[0];
     } else {
       file = event.target.files[0];
     }
@@ -88,29 +90,29 @@ $(document).ready(function() {
     fileSender.on('loading', isStillLoading => {
       // The file is loading into Firefox at this stage
       if (isStillLoading) {
-        console.log('Processing')
+        console.log('Processing');
       } else {
-        console.log('Finished processing')
+        console.log('Finished processing');
       }
-    })
+    });
 
     fileSender.on('hashing', isStillHashing => {
       // The file is being hashed
       if (isStillHashing) {
         console.log('Hashing');
       } else {
-        console.log('Finished hashing')
+        console.log('Finished hashing');
       }
-    })
+    });
 
     fileSender.on('encrypting', isStillEncrypting => {
       // The file is being encrypted
       if (isStillEncrypting) {
         console.log('Encrypting');
       } else {
-        console.log('Finished encrypting')
+        console.log('Finished encrypting');
       }
-    })
+    });
 
     fileSender
       .upload()
@@ -143,11 +145,11 @@ $(document).ready(function() {
         $('#page-one').hide();
         $('#upload-error').show();
       });
-  };
+  }
 
-  window.allowDrop = function(ev) {
+  function allowDrop(ev) {
     ev.preventDefault();
-  };
+  }
 
   function checkExistence(id, populate) {
     const xhr = new XMLHttpRequest();
diff --git a/frontend/src/utils.js b/frontend/src/utils.js
index af0c9c99..e1e7531d 100644
--- a/frontend/src/utils.js
+++ b/frontend/src/utils.js
@@ -34,34 +34,38 @@ function notify(str) {
 
 function gcmCompliant() {
   try {
-    return window.crypto.subtle.generateKey(
-      {
-        name: 'AES-GCM',
-        length: 128
-      },
-      true,
-      ['encrypt', 'decrypt']
-    ).then(key => {
-      return window.crypto.subtle.encrypt(
+    return window.crypto.subtle
+      .generateKey(
         {
           name: 'AES-GCM',
-          iv: window.crypto.getRandomValues(new Uint8Array(12)),
-          additionalData: window.crypto.getRandomValues(new Uint8Array(6)),
-          tagLength: 128
+          length: 128
         },
-        key,
-        new ArrayBuffer(8)
+        true,
+        ['encrypt', 'decrypt']
       )
-      .then(() => {
-        return Promise.resolve()
+      .then(key => {
+        return window.crypto.subtle
+          .encrypt(
+            {
+              name: 'AES-GCM',
+              iv: window.crypto.getRandomValues(new Uint8Array(12)),
+              additionalData: window.crypto.getRandomValues(new Uint8Array(6)),
+              tagLength: 128
+            },
+            key,
+            new ArrayBuffer(8)
+          )
+          .then(() => {
+            return Promise.resolve();
+          })
+          .catch(err => {
+            return Promise.reject();
+          });
       })
       .catch(err => {
-        return Promise.reject()
-      })
-    }).catch(err => {
-      return Promise.reject();
-    })
-  } catch(err) {
+        return Promise.reject();
+      });
+  } catch (err) {
     return Promise.reject();
   }
 }
diff --git a/server/server.js b/server/server.js
index 50696275..e3c838a0 100644
--- a/server/server.js
+++ b/server/server.js
@@ -32,6 +32,30 @@ app.engine(
 app.set('view engine', 'handlebars');
 
 app.use(helmet());
+app.use(
+  helmet.contentSecurityPolicy({
+    directives: {
+      defaultSrc: ['\'self\''],
+      connectSrc: [
+        '\'self\'',
+        'https://sentry.prod.mozaws.net',
+        'https://www.google-analytics.com',
+        'https://ssl.google-analytics.com'
+      ],
+      imgSrc: [
+        '\'self\'',
+        'https://www.google-analytics.com',
+        'https://ssl.google-analytics.com'
+      ],
+      scriptSrc: ['\'self\'', 'https://ssl.google-analytics.com'],
+      styleSrc: ['\'self\'', 'https://code.cdn.mozilla.net'],
+      fontSrc: ['\'self\'', 'https://code.cdn.mozilla.net'],
+      formAction: ['\'none\''],
+      frameAncestors: ['\'none\''],
+      objectSrc: ['\'none\'']
+    }
+  })
+);
 app.use(busboy());
 app.use(bodyParser.json());
 app.use(express.static(STATIC_PATH));
@@ -92,33 +116,35 @@ app.get('/assets/download/:id', (req, res) => {
   storage
     .metadata(id)
     .then(meta => {
-      storage.length(id).then(contentLength => {
-        res.writeHead(200, {
-          'Content-Disposition': 'attachment; filename=' + meta.filename,
-          'Content-Type': 'application/octet-stream',
-          'Content-Length': contentLength,
-          'X-File-Metadata': JSON.stringify(meta)
-        });
-        const file_stream = storage.get(id);
+      storage
+        .length(id)
+        .then(contentLength => {
+          res.writeHead(200, {
+            'Content-Disposition': 'attachment; filename=' + meta.filename,
+            'Content-Type': 'application/octet-stream',
+            'Content-Length': contentLength,
+            'X-File-Metadata': JSON.stringify(meta)
+          });
+          const file_stream = storage.get(id);
 
-        file_stream.on('end', () => {
-          storage
-            .forceDelete(id)
-            .then(err => {
-              if (!err) {
-                log.info('Deleted:', id);
-              }
-            })
-            .catch(err => {
-              log.info('DeleteError:', id);
-            });
-        });
+          file_stream.on('end', () => {
+            storage
+              .forceDelete(id)
+              .then(err => {
+                if (!err) {
+                  log.info('Deleted:', id);
+                }
+              })
+              .catch(err => {
+                log.info('DeleteError:', id);
+              });
+          });
 
-        file_stream.pipe(res);
-      })
-      .catch(err => {
-        res.sendStatus(404);
-      });
+          file_stream.pipe(res);
+        })
+        .catch(err => {
+          res.sendStatus(404);
+        });
     })
     .catch(err => {
       res.sendStatus(404);
@@ -157,15 +183,17 @@ app.post('/upload', (req, res, next) => {
 
   try {
     meta = JSON.parse(req.header('X-File-Metadata'));
-  } catch(err) {
+  } catch (err) {
     res.sendStatus(400);
     return;
   }
 
-  if (!validateIV(meta.id) ||
-      !meta.hasOwnProperty('aad') ||
-      !meta.hasOwnProperty('id') ||
-      !meta.hasOwnProperty('filename')) {
+  if (
+    !validateIV(meta.id) ||
+    !meta.hasOwnProperty('aad') ||
+    !meta.hasOwnProperty('id') ||
+    !meta.hasOwnProperty('filename')
+  ) {
     res.sendStatus(404);
     return;
   }
@@ -216,4 +244,4 @@ const validateIV = route_id => {
 module.exports = {
   server: server,
   storage: storage
-}
+};
diff --git a/server/storage.js b/server/storage.js
index b03cbbaf..5d48b490 100644
--- a/server/storage.js
+++ b/server/storage.js
@@ -129,7 +129,9 @@ function localGet(id) {
 
 function localSet(newId, file, filename, meta) {
   return new Promise((resolve, reject) => {
-    const fstream = fs.createWriteStream(path.join(__dirname, '../static', newId));
+    const fstream = fs.createWriteStream(
+      path.join(__dirname, '../static', newId)
+    );
     file.pipe(fstream);
     fstream.on('close', () => {
       redis_client.hmset(newId, meta);
diff --git a/views/download.handlebars b/views/download.handlebars
index ba6cf5c5..50cc365a 100644
--- a/views/download.handlebars
+++ b/views/download.handlebars
@@ -23,7 +23,7 @@
       </div>
       <div id="download-page-one">
         <div>
-          <button id="download-btn" onclick="download()">Download File</button>
+          <button id="download-btn">Download File</button>
         </div>
         <div id='expired-img'>
           <img src='/resources/link_expired.png' />
diff --git a/views/index.handlebars b/views/index.handlebars
index 8be8f2d5..b34a9e80 100644
--- a/views/index.handlebars
+++ b/views/index.handlebars
@@ -19,7 +19,7 @@
       <div class="title">
         Share your files quickly, privately and securely.
       </div>
-      <div class="upload-window" ondrop="onUpload(event)" ondragover="allowDrop(event)">
+      <div class="upload-window">
         <div id="upload-img"><img src="/resources/upload.svg" alt="Upload"/></div>
         <div>
           DRAG &amp; DROP
@@ -31,7 +31,7 @@
           <div id="browse">
             <form method="post" action="upload" enctype="multipart/form-data">
               <label for="file-upload" class="file-upload">browse</label>
-              <input id="file-upload" type="file" onchange="onUpload(event)" name="fileUploaded" />
+              <input id="file-upload" type="file" name="fileUploaded" />
             </form>
           </div>
         </div>