#224: CSRF protection framework
This PLIP contains two parts: infrastructure to Plone to manage site-wide secrets that can be used for various purposes and adding a system to authenticate form posts, prevent abuse from attackers.
- Proposed by
- Wichert Akkerman
- Proposal type
- User interface, Architecture
- Assigned to release
A common problem with web application is Cross Site Request Forgery (CSRF). This is an attack method where an attacker tricks a victims web browser into submitting a HTTP request, controller by the attacker, to another site. If the victim has an open session on that site attackers can use this to make arbitrary changes on that site. Common attacks involve changing a users email address or using admin privileges to make other security-sensitive changes.
This PLIP describes new infrastructure for Plone which provides a simple method to protect against CSRF attacks.
We assume that Plone is free from other cross-site scripting (XSS) problems and attackers are not able to see network traffic from the victim to the Plone site. If either of those is not true an attacker will be able to grab a valid authenticator from Plone and use that in an attack.
Since both XSS problems and raw network access also provide other, possibly more serious, attack vectors this is considered to be an acceptable assumption.
CSRF attacks rely on three factors:
- if a victim has a valid login session based on cookies on a website any requests being triggered by an attacker will be able to use that session. Cookies are the standard mechanism to manage login sessions: without them every request would need to perform special session handling in its URL or use HTTP POST requests.
- an attacker has to know the exact HTTP request that needs to be used in advance.
The first two are facts of life and can not be changed. Luckily there are ways to protect sites against the last factor: by embedding an authenticator in requests which an attacker can not predict we can verify if the request is valid.
This PLIP contains two parts: a keyring/secret manager, and a framework to add authenticators to forms which can be used to protect against CSRF attacks.
The framework consists of two parts:
- This provides a persistent utility which manages one or more keyrings with secrets. These secrets can be used to generate things such as authenticators or session identifiers. plone.session uses a similar system to manage the secrets it needs for session identifiers, and its implementation can be reused for plone.keyring.
This package uses the secrets managed by plone.keyring to generate authenticators for forms and provides a few simple methods developers can use to authenticate a request.
This package is intended to be a central location for various security mechanisms, hence its generic name.
The authenticators used by plone.app.protect will be based on two items: the current secret from the system keyring as stored in plone.keyring and the userid of the current user (which will be the string 'Anonymous User' for anonymous users). Since an attacker can not known the secret and can only guess at the userid this produces an authenticator that is secure. For extra security the keyring can be rotated periodically, invalidating older authenticators.
There are no known risks. There is very little migration needed: two new packages need to be added to the Plone instance and the persistent utility from plone.keyring needs to be instantiated.
All existing forms will continue to work. In order to use the newly available protection they can be modified by a single line of TAL in the template and a single line of python in the backend code.
The implementation of plone.keyring is complete.
plone.app.protect is fully functioning and has tests and documentation. A user interface to manage keyrings as well as a system to automatically rotate keyrings is highly desirable.