Cross-site request forgery (CSRF) forces an authenticated user to perform unintended state-changing actions in a web application. This rule detects when CSRF protection is explicitly disabled or missing from an application.
When CSRF protection is disabled or bypassed, an attacker can trick a logged-in user into submitting requests the application treats as authenticated. The rule flags configurations that disable framework CSRF middleware, exempt specific routes or views, or leave unsafe HTTP methods unprotected.
An attacker can change passwords, transfer funds, modify data, or perform other privileged operations using the victim’s session.
Successful CSRF attacks can lead to full account takeover when combined with sensitive actions such as email or credential changes.
Enable django.middleware.csrf.CsrfViewMiddleware in settings and do not exempt views from CSRF protection unless strictly
necessary.
Disabling or bypassing CSRF protection allows an authenticated user’s browser to execute state-changing requests the user did not intend.
django.middleware.csrf.CsrfViewMiddleware is not used in the 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',
] # Noncompliant: django.middleware.csrf.CsrfViewMiddleware is missing
The CSRF protection is disabled on a view:
@csrf_exempt # Noncompliant
def example(request):
return HttpResponse("default")
Protect all views with django.middleware.csrf.CsrfViewMiddleware:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
Do not disable the CSRF protection on specific views:
def example(request):
return HttpResponse("default")
Use the CSRFProtect module from Flask-WTF and keep WTF_CSRF_ENABLED enabled.
Disabling or bypassing CSRF protection allows an authenticated user’s browser to execute state-changing requests the user did not intend.
The WTF_CSRF_ENABLED setting is set to false:
app = Flask(__name__) app.config['WTF_CSRF_ENABLED'] = False # Noncompliant
The application doesn’t use the CSRFProtect module:
app = Flask(__name__) # Noncompliant: CSRFProtect is missing
@app.route('/')
def hello_world():
return 'Hello, World!'
The CSRF protection is disabled on a view:
@app.route('/example/', methods=['POST'])
@csrf.exempt # Noncompliant
def example():
return 'example '
The CSRF protection is disabled on a form:
class unprotectedForm(FlaskForm):
class Meta:
csrf = False # Noncompliant
name = TextField('name')
submit = SubmitField('submit')
Use the CSRFProtect module (and do not disable it with WTF_CSRF_ENABLED set to false):
app = Flask(__name__) csrf = CSRFProtect() csrf.init_app(app)
app = Flask(__name__) csrf = CSRFProtect() csrf.init_app(app)
Do not disable the CSRF protection on specific views or forms:
@app.route('/example/', methods=['POST'])
def example():
return 'example '
class unprotectedForm(FlaskForm):
class Meta:
csrf = True
name = TextField('name')
submit = SubmitField('submit')