Repository: plotly/dash

Issue:
Remove CSRF protection
Besides the `GET` of `index.html`, Dash only supports POST requests with `application/json`. These are actually unsusceptible to CSRF attacks according to https://security.stackexchange.com/questions/23371/csrf-protection-with-custom-headers-and-without-validating-token/58308#58308. Based off of this, I believe that we should be able to remove CSRF protection and therefore will not require users to create a `app.server.config.SECRET_KEY`. 


Discussion:
I don't know enough about CSRF to comment on whether that makes sense, but if that's the case, then yeah I definitely reckon it should go. It caused me a lot of hassles working out that I needed to set the secret key, and it's something I've seen coming up a fair bit as an issue for people on the community forums. Would save a bit of headache potentially. 

Resolving patch:
diff --git a/dash/dash.py b/dash/dash.py
--- a/dash/dash.py
+++ b/dash/dash.py
@@ -1,14 +1,12 @@
-import flask
-import json
-import plotly
 from flask import Flask, Response
 from flask_compress import Compress
-from flask_seasurf import SeaSurf
-import os
+import collections
+import flask
 import importlib
+import json
 import pkgutil
-import collections
-import re
+import plotly
+import warnings
 
 import dash_renderer
 
@@ -26,8 +24,17 @@ def __init__(
         server=None,
         static_folder=None,
         url_base_pathname='/',
-        csrf_protect=True
+        **kwargs
     ):
+
+        if 'csrf_protect' in kwargs:
+            warnings.warn('''
+                `csrf_protect` is no longer used,
+                CSRF protection has been removed as it is no longer
+                necessary.
+                See https://github.com/plotly/dash/issues/141 for details.
+                ''', DeprecationWarning)
+
         # allow users to supply their own flask server
         if server is not None:
             self.server = server
@@ -36,19 +43,6 @@ def __init__(
                 name = 'dash'
             self.server = Flask(name, static_folder=static_folder)
 
-        if self.server.secret_key is None:
-            # If user supplied their own server, they might've supplied a
-            # secret_key with it
-            secret_key_name = 'dash_{}_secret_key'.format(
-                # replace any invalid characters
-                re.sub('[\W_]+', '_', name)
-            )
-            secret_key = os.environ.get(
-                secret_key_name, SeaSurf()._generate_token()
-            )
-            os.environ[secret_key_name] = secret_key
-            self.server.secret_key = secret_key
-
         self.url_base_pathname = url_base_pathname
         self.config = _AttributeDict({
             'suppress_callback_exceptions': False,
@@ -62,10 +56,6 @@ def __init__(
         # gzip
         Compress(self.server)
 
-        # csrf protect
-        if csrf_protect:
-            self._csrf = SeaSurf(self.server)
-
         # static files from the packages
         self.css = Css()
         self.scripts = Scripts()
diff --git a/dash/version.py b/dash/version.py
--- a/dash/version.py
+++ b/dash/version.py
@@ -1 +1 @@
-__version__ = '0.18.3'
+__version__ = '0.19.0'
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -16,7 +16,6 @@
     install_requires=[
         'Flask>=0.12',
         'flask-compress',
-        'flask-seasurf',
         'plotly'
     ],
     url='https://plot.ly/dash',


Test patch: