Add global CSRF protection
This commit is contained in:
parent
ab09314ed3
commit
4ed522ae47
|
@ -129,6 +129,9 @@ def make_pyramid_config(settings):
|
|||
config.set_authentication_policy(SessionAuthenticationPolicy())
|
||||
config.set_authorization_policy(TailboneAuthorizationPolicy())
|
||||
|
||||
# always require CSRF token protection
|
||||
config.set_default_csrf_options(require_csrf=True, token='_csrf')
|
||||
|
||||
# Bring in some Pyramid goodies.
|
||||
config.include('pyramid_beaker')
|
||||
config.include('pyramid_mako')
|
||||
|
|
|
@ -28,7 +28,7 @@ from __future__ import unicode_literals, absolute_import
|
|||
|
||||
from formencode import Schema
|
||||
|
||||
from .core import Form, Field, FieldSet, GenericFieldSet, invalid_csrf_token
|
||||
from .core import Form, Field, FieldSet, GenericFieldSet
|
||||
from .simpleform import SimpleForm, FormRenderer
|
||||
from .alchemy import AlchemyForm
|
||||
from .fields import AssociationProxyField
|
||||
|
|
|
@ -33,7 +33,6 @@ from pyramid.renderers import render
|
|||
from webhelpers.html import HTML, tags
|
||||
|
||||
from tailbone.db import Session
|
||||
from tailbone.forms import invalid_csrf_token
|
||||
|
||||
|
||||
class TemplateEngine(fa.templates.TemplateEngine):
|
||||
|
@ -114,8 +113,5 @@ class AlchemyForm(Object):
|
|||
self.session.flush()
|
||||
|
||||
def validate(self):
|
||||
if invalid_csrf_token(self.request):
|
||||
self.request.session.flash("Invalid CSRF token", 'error')
|
||||
return False
|
||||
self.fieldset.rebind(data=self.request.params)
|
||||
return self.fieldset.validate()
|
||||
|
|
|
@ -33,17 +33,6 @@ from formalchemy.helpers import content_tag
|
|||
from pyramid.renderers import render
|
||||
|
||||
|
||||
def invalid_csrf_token(request):
|
||||
"""
|
||||
Returns boolean indicating whether the given request has an *invalid* CSRF token.
|
||||
"""
|
||||
if request.method == 'POST':
|
||||
csrf_token = request.session.get_csrf_token()
|
||||
if request.POST.get('_csrf') != csrf_token:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class Form(object):
|
||||
"""
|
||||
Base class for all forms.
|
||||
|
|
|
@ -33,7 +33,7 @@ from pyramid_simpleform import renderers
|
|||
from webhelpers.html import tags
|
||||
from webhelpers.html import HTML
|
||||
|
||||
from tailbone.forms import Form, invalid_csrf_token
|
||||
from tailbone.forms import Form
|
||||
|
||||
|
||||
class SimpleForm(Form):
|
||||
|
@ -53,9 +53,6 @@ class SimpleForm(Form):
|
|||
return super(SimpleForm, self).render(**kwargs)
|
||||
|
||||
def validate(self):
|
||||
if invalid_csrf_token(self.request):
|
||||
self.request.session.flash("Invalid CSRF token", 'error')
|
||||
return False
|
||||
return self._form.validate()
|
||||
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ from rattail.util import pretty_quantity
|
|||
from webhelpers.html import *
|
||||
from webhelpers.html.tags import *
|
||||
|
||||
from tailbone.util import pretty_datetime
|
||||
from tailbone.util import csrf_token, pretty_datetime
|
||||
|
||||
|
||||
def pretty_date(date):
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
<div class="form">
|
||||
${h.form(url('change_password'))}
|
||||
${form.csrf_token()}
|
||||
${form.referrer_field()}
|
||||
${form.field_div('current_password', form.password('current_password'))}
|
||||
${form.field_div('new_password', form.password('new_password'))}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
<div class="form">
|
||||
${form.begin()}
|
||||
${form.csrf_token()}
|
||||
${form.hidden('user', value=request.user.uuid if request.user else None)}
|
||||
|
||||
<p>
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
<br />
|
||||
|
||||
${h.form(request.current_route_url())}
|
||||
${h.csrf_token(request)}
|
||||
<div class="buttons">
|
||||
<a class="button" href="${form.cancel_url}">Whoops, nevermind...</a>
|
||||
<button type="button" id="confirm-delete">Yes, please DELETE this data forever!</button>
|
||||
|
|
|
@ -71,6 +71,7 @@ ${rows_grid|n}
|
|||
<div id="execution-options-dialog" style="display: none;">
|
||||
|
||||
${h.form(url('{}.execute'.format(route_prefix), uuid=batch.uuid), name='batch-execution')}
|
||||
${h.csrf_token(request)}
|
||||
% if master.has_execution_options:
|
||||
${rendered_execution_options|n}
|
||||
% endif
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
<div class="form">
|
||||
|
||||
${h.form(request.current_route_url())}
|
||||
${h.csrf_token(request)}
|
||||
|
||||
<div class="field-wrapper">
|
||||
<label for="batch_type">Batch Type</label>
|
||||
|
@ -54,6 +55,7 @@
|
|||
<div class="form">
|
||||
|
||||
${h.form(request.current_route_url())}
|
||||
${h.csrf_token(request)}
|
||||
|
||||
<div class="field-wrapper">
|
||||
<label for="provider">Batch Type</label>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<br />
|
||||
|
||||
${h.form(request.current_route_url())}
|
||||
${h.csrf_token(request)}
|
||||
|
||||
<div class="field-wrapper">
|
||||
<label for="department">Department</label>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<div class="timesheet-wrapper">
|
||||
|
||||
${form.begin(id='filter-form')}
|
||||
${form.csrf_token()}
|
||||
|
||||
<table class="timesheet-header">
|
||||
<tbody>
|
||||
|
|
|
@ -283,6 +283,7 @@
|
|||
|
||||
<%def name="edit_form()">
|
||||
${h.form(url('schedule.edit'), id='schedule-form')}
|
||||
${h.csrf_token(request)}
|
||||
</%def>
|
||||
|
||||
<%def name="edit_tools()">
|
||||
|
@ -299,6 +300,7 @@ ${timesheet_wrapper(edit_form=edit_form, edit_tools=edit_tools, context_menu=con
|
|||
${edit_tools()}
|
||||
|
||||
${h.form(url('schedule.edit'), id="clear-schedule-form")}
|
||||
${h.csrf_token(request)}
|
||||
${h.hidden('clear-schedule', value='clear')}
|
||||
${h.end_form()}
|
||||
|
||||
|
@ -318,6 +320,7 @@ ${h.end_form()}
|
|||
and then new shifts will be created based on the week you specify.
|
||||
</p>
|
||||
${h.form(url('schedule.edit'), id='copy-schedule-form')}
|
||||
${h.csrf_token(request)}
|
||||
<label for="copy-week">Copy from week:</label>
|
||||
${h.text('copy-week')}
|
||||
${h.end_form()}
|
||||
|
|
|
@ -31,11 +31,21 @@ import datetime
|
|||
import pytz
|
||||
import humanize
|
||||
|
||||
from webhelpers.html import HTML
|
||||
from webhelpers.html import HTML, tags
|
||||
|
||||
from rattail.time import timezone, make_utc
|
||||
|
||||
|
||||
def csrf_token(request, name='_csrf'):
|
||||
"""
|
||||
Convenience function. Returns CSRF hidden tag inside hidden DIV.
|
||||
"""
|
||||
token = request.session.get_csrf_token()
|
||||
if token is None:
|
||||
token = request.session.new_csrf_token()
|
||||
return HTML.tag("div", tags.hidden(name, value=token), style="display:none;")
|
||||
|
||||
|
||||
def pretty_datetime(config, value):
|
||||
"""
|
||||
Formats a datetime as a "pretty" human-readable string, with a tooltip
|
||||
|
|
Loading…
Reference in a new issue