include::../description.adoc[]

include::../ask-yourself.adoc[]

include::../recommended.adoc[]

== Sensitive Code Example

For a https://docs.djangoproject.com/fr/3.0/ref/csrf/[Django] application, the code is sensitive when,

* ``++django.middleware.csrf.CsrfViewMiddleware++`` is not used in the https://docs.djangoproject.com/en/3.0/topics/settings/[Django settings]: 

----
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
] # Sensitive: django.middleware.csrf.CsrfViewMiddleware is missing
----

* the CSRF protection is disabled on a view:

----
@csrf_exempt # Sensitive
def example(request):
    return HttpResponse("default")
----


For a https://flask-wtf.readthedocs.io/en/latest/csrf.html[Flask] application, the code is sensitive when,

* the ``++WTF_CSRF_ENABLED++`` setting is set to ``++false++``:

----
app = Flask(__name__)
app.config['WTF_CSRF_ENABLED'] = False # Sensitive
----

* the  application doesn't use the ``++CSRFProtect++`` module:

----
app = Flask(__name__) # Sensitive: CSRFProtect is missing

@app.route('/')
def hello_world():
    return 'Hello, World!'
----

* the CSRF protection is disabled on a view:

----
app = Flask(__name__)
csrf = CSRFProtect()
csrf.init_app(app) 

@app.route('/example/', methods=['POST'])
@csrf.exempt # Sensitive
def example():
    return 'example '
----

* the CSRF protection is disabled on a form:

----
class unprotectedForm(FlaskForm):
    class Meta:
        csrf = False # Sensitive

    name = TextField('name')
    submit = SubmitField('submit')
----

== Compliant Solution

For a https://docs.djangoproject.com/fr/3.0/ref/csrf/[Django] application,

* it is recommended to protect all the views with ``++django.middleware.csrf.CsrfViewMiddleware++``:

[source,python]
----
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware', # Compliant
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
] 
----

* and to not disable the CSRF protection on specific views:

[source,python]
----
def example(request): # Compliant
    return HttpResponse("default")
----


For a https://flask-wtf.readthedocs.io/en/latest/csrf.html[Flask] application, 

* the ``++CSRFProtect++`` module should be used (and not disabled further with ``++WTF_CSRF_ENABLED++`` set to ``++false++``):

[source,python]
----
app = Flask(__name__)
csrf = CSRFProtect()
csrf.init_app(app) # Compliant
----

* and it is recommended to not disable the CSRF protection on specific views or forms:

[source,python]
----
@app.route('/example/', methods=['POST']) # Compliant
def example():
    return 'example '

class unprotectedForm(FlaskForm):
    class Meta:
        csrf = True # Compliant

    name = TextField('name')
    submit = SubmitField('submit')
----

include::../see.adoc[]

ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

include::../message.adoc[]

'''
== Comments And Links
(visible only on this page)

include::../comments-and-links.adoc[]

endif::env-github,rspecator-view[]
