News in Nette Forms 3.1

5 months ago by David Grudl     edit

Protection against CSRF using cookies

The vulnerability of a CSRF is based on the trick that the form is spoofed by an attacker and sent from his site, ie from another domain, against which Nette has always had protection, which is turned on by the method addProtection(). This protection is gradually being replaced by a new and fully automatic cookie protection with the SameSite flag. Forms in Nette Application have been protected this way since version 3.0, and now standalone forms come into play.

The method addProtection () is still important, even though browsers that do not support SameSite are slowly disappearing. The problem could occur when someone takes over a subdomain such as foo.example.com and creates a cookie there. This is because it has the same “site” as the subdomain www.example.com, and a cookie would be sent to the request on www.example.com.

The standalone form sends the cookie automatically. It is assumed that you are creating a form when the headers have not yet been submitted, because usually the form is successfully processed and redirected to another page, which is done with the header. If for some reason you encounter a problem that the header can no longer be sent, you can do it earlier using Nette\Forms\Form::initialize().

If you want to disable this protection and thus allow the form to be submitted from another domain, use $form->allowCrossOrigin(). This also applies to forms from the Nette Application.

Safer behavior onSuccess, onClick and getValues()

Method setValidationScope() is used to limit the elements to be validated when sending form by a certain button. Only those elements that are validated are now listed in variable $values passed to event handlers onSuccess and onClick. In $values there will be no invalid data.

The same change applies to method $form->getValues(), which now also returns only validated elements. In addition, if you call getValues() before validation, Nette will alert you with a warning.

If for some reason you need to get the values ​​of all elements independently of the validation, as it did getValues() in previous versions, use the new method $form->getUnsafeValues()

By the way, if you do not need a form object but only values ​​in the handler for onSuccess or onClick, you can omit the parameter $form ($values must have a typehint):

public function formSucceeded(array $values): void
{
	...
}

Clarity

For the sake of clarity, the method Checkbox::getSeparatorPrototype() has been renamed to getContainerPrototype() and Form::addImage() to addImageButton(). Of course, the original names still work as aliases.

Others

Rule Form::URL now fills in the missing protocol https instead of http, so if the user enters nette.org, the resulting value will be https://nette.org.

Method $vals = $form->getValues(FormData::class) returns values ​​mapped to an object of a given class. Hydration can now be used with $vals = $form->getValues(new FormData).

Forms no longer create template variables $_form that are deprecated since Nette 2.4.

The minimum required version of PHP is 7.2.

Further reading