CSRF vulnerabilities occur when attackers can trick a user to perform sensitive authenticated operations on a web application without his consent.
<body onload="document.forms[0].submit()">
<form>
<form action="http://mybank.com/account/transfer_money" method="POST">
<input type="hidden" name="accountNo" value="attacker_account_123456"/>
<input type="hidden" name="amount" value="10000"/>
<input type="submit" value="Steal money"/>
</form>
If an user visits the attacker's website which contains the above malicious code, his bank account will be debited without his consent and notice.
There is a risk if you answered yes to any of those questions.
GET which are designed to be
used only for information retrieval. For a Django application, the code is sensitive when,
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',
] # Sensitive: django.middleware.csrf.CsrfViewMiddleware is missing
@csrf_exempt # Sensitive
def example(request):
return HttpResponse("default")
For a Flask application, the code is sensitive when,
WTF_CSRF_ENABLED setting is set to false: app = Flask(__name__) app.config['WTF_CSRF_ENABLED'] = False # Sensitive
CSRFProtect module:
app = Flask(__name__) # Sensitive: CSRFProtect is missing
@app.route('/')
def hello_world():
return 'Hello, World!'
app = Flask(__name__)
csrf = CSRFProtect()
csrf.init_app(app)
@app.route('/example/', methods=['POST'])
@csrf.exempt # Sensitive
def example():
return 'example '
class unprotectedForm(FlaskForm):
class Meta:
csrf = False # Sensitive
name = TextField('name')
submit = SubmitField('submit')
For a Django application,
django.middleware.csrf.CsrfViewMiddleware:
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',
]
def example(request): # Compliant
return HttpResponse("default")
For a Flask application,
CSRFProtect module should be used (and not disabled further with WTF_CSRF_ENABLED set to false):
app = Flask(__name__) csrf = CSRFProtect() csrf.init_app(app) # Compliant
@app.route('/example/', methods=['POST']) # Compliant
def example():
return 'example '
class unprotectedForm(FlaskForm):
class Meta:
csrf = True # Compliant
name = TextField('name')
submit = SubmitField('submit')