147 lines
3.5 KiB
Plaintext
147 lines
3.5 KiB
Plaintext
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[]
|