misc: do not enable quixote form token if there may be multiple pages (#87781)
gitea/wcs/pipeline/head This commit looks good Details

This commit is contained in:
Frédéric Péters 2024-03-05 13:15:02 +01:00
parent 658aff404e
commit bf442ecf44
2 changed files with 29 additions and 4 deletions

View File

@ -6073,3 +6073,25 @@ def test_form_submit_no_csrf(pub):
# simulate call from remote/attacker site (magictokens prevents this)
resp = app.post(formdef.get_url(), params=form_data, status=302)
assert resp.location == formdef.get_url()
def test_form_submit_no_csrf_suddenly_single_page(pub):
formdef = FormDef()
formdef.name = 'test'
formdef.fields = [
fields.PageField(id='1', label='page1'),
fields.ComputedField(id='2', label='computed', varname='plop', value_template='{{ "plop" }}'),
fields.PageField(
id='3', label='page2', condition={'type': 'django', 'value': 'form_var_plop != "plop"'}
),
]
formdef.confirmation = False
formdef.store()
formdef.data_class().wipe()
create_user(pub)
app = get_app(pub)
login(app, username='foo', password='foo')
resp = app.get(formdef.get_url())
resp = resp.form.submit('submit').follow()
assert formdef.data_class().select()[0].status == 'wf-new'

View File

@ -37,7 +37,7 @@ from quixote.util import randbytes
from wcs.carddef import CardDef
from wcs.categories import Category
from wcs.fields import MissingBlockFieldError, SetValueError
from wcs.fields import MissingBlockFieldError, PageField, SetValueError
from wcs.formdata import Evolution, FormData
from wcs.formdef import FormDef
from wcs.forms.common import FormStatusPage, FormTemplateMixin, TempfileDirectoryMixin
@ -1006,9 +1006,12 @@ class FormPage(Directory, TempfileDirectoryMixin, FormTemplateMixin):
def create_form(self, *args, **kwargs):
form = self.formdef.create_form(*args, **kwargs)
if len(self.pages) == 1 and not self.formdef.confirmation:
# if there's a form with a single page, no confirmation, add native quixote
# CSRF protection.
if (
len([x for x in self.formdef.fields if isinstance(x, PageField)]) < 2
and not self.formdef.confirmation
):
# if there's a form with a single page (at all, not as the result of conditions),
# and no confirmation page, add native quixote CSRF protection.
form.add(FormTokenWidget, form.TOKEN_NAME)
form.attrs['data-live-url'] = self.formdef.get_url(language=get_publisher().current_language) + 'live'
form.attrs['data-live-validation-url'] = (