An edit token (also known as a csrf token) is a random string that is passed between a client and the MediaWiki server when performing actions that change pages. It is used to check that the user really intended to make the change, rather than being tricked into requesting the change on the wiki while visiting an external site (i.e. cross-site request forgery).
Why it is necessary
Edit tokens are used as an additional security measure when performing changes. If the user identity were checked using cookies only, an external site could use a link like the following one to have visitors perform changes to the wiki. https://en.wikipedia.org/w/index.php?title=Image:Abcd.jpg&action=delete&oldimage=324242234 Following such a link would lead an administrator to unknowingly request deletion of an image. If the administrator is still logged in, the server would check the cookies and grant the request.
For this reason, actions that perform changes require an additional piece of data that is passed as an HTTP parameter, the edit token. An edit token is embedded into web pages from which the user can request a change; this includes the edit form (where one can change a page by pressing "Publish changes") but also the image description pages (where an administrator can request deletion of an old version of an image), contributor histories (where administrators can rollback), etc.
When the user actually requests the change to be done (by pressing a button or following a link), the edit token is sent back to the server. This proves to the server that the user has requested the change directly from the site and not from an external site, as external sites do not have access to the edit tokens of the user.
How it works
An edit token is a random string stored in the PHP session, which is an associative array that is stored in the server and maintained across sessions because of a cookie (e.g.,
enwiki_session on the English Wikipedia). The edit token is in particular contained in the
wsEditToken element of the PHP session.
Edit tokens are embedded into web pages from where the user can request a change. When such a page is to be generated, the edit token is retrieved from the
wsEditToken element of the PHP session, if such an element exists; otherwise, a random string is generated and stored in that element.
What is actually embedded into the web page is not the
wsEditToken element itself. Rather, this element is concatenated to the salt, which is a string that depends on the particular action and page; the resulting string is then MD5-hashed; this is what is embedded in the web page. When the user actually requests the action, this string is sent back to the server via an HTTP parameter. The server can then check the correctness of this parameter: it repeats the procedure used to generate it from the PHP session and checks if the result is equal to the parameter.
The edit token returned by the server can be reused multiple times for different edit operations. The token is only valid for a specific period of time. API call with a stale token will return a badtoken error. In this case it is necessary to get a new edit token from the server before retrying the operation.
Edit tokens are mainly dealt with in the User.php source file, and in particular by the following methods.
- returns the MD5 hash of the concatenation of the
wpEditTokenelement of the PHP session with the salt. If such an element does not exist in the PHP session, a random one is generated. See getEditToken function in repository.
- matchEditToken(token, salt)
- checks whether its first argument is a valid edit token with respect to the salt; this is done by repeating the procedure of generation and then comparing the result with the first argument; in particular, this function calls
editToken(salt)and then compares the result with the first argument;
The default salt is the empty string; most actions use this default value. As a result, an edit token string received from a server to perform an initial action on a page can also be used to perform additional actions on other pages. However, since an edit token is stored in the PHP session, it can be used only as long as the session is kept in the server and the client has the corresponding session token cookie (e.g., the enwiki_session cookie).
An edit-token-hash generated using a salt can be used for performing additional actions only if the salt used by both server and client is the same. Therefore it follows that if the salt is only embedded in the page where the initial action is performed, then that same edit-token-hash cannot be used to enable actions on additional pages.
- Actions not using the default empty salt are:
- the salt is the title of the article (including the namespace prefix) concatenated with the name of the user whose edits are to be reverted;
- delete the old version of an image
- the salt is the
oldimageparameter (when deleting all version this parameter is the empty string, which is also the default salt);
- the salt is the username of the user whose properties are to be changed;
- the salt is the string 'clearwatchlist'
The edit token suffix
Edit tokens end with
+\ to prevent broken proxies from editing: proxies that cannot correctly handle the backslash or plus sign typically also mess up the wiki markup code.
In 1.18 and higher, you do not need to retrieve the edit token using AJAX. It's available as
mw.user.tokens.get( 'csrfToken' ). Note that you need to have defined mediawiki.user as a ResourceLoader dependency for your module. It is recommended that you use the
mw.api.postWithToken() helper method, which automatically takes care of retries if the token has expired since the web page was loaded.