At HackDefense, we were evaluating various calendaring solutions, and during installation and configuration of DAViCal we discovered three (severe) vulnerabilities. We reported these vulnerabilities to the vendor. Unfortunately, the DAViCal project itself was not able to fix these vulnerabilities. As DAViCal is an open source project we decided to contribute patches for these vulnerabilities ourselves. DAViCal has accepted our patches in the 184.108.40.206 release. If you use DAViCal as a calendaring server, we recommend upgrading to version 220.127.116.11 immediately to remediate the issues we’ve discovered.
All three vulnerabilities exist in the web-based management pages that come with DAViCal. We have written three separate advisories to describe the vulnerabilities:
DAViCal is a server for calendar sharing. It is an implementation of the CalDAV protocol which is designed for storing calendaring resources on a remote shared server. It can be used by various e‑mail and calendaring clients to centrally store and share calendars.
It includes a web-based management application. It was in these pages that we discovered this vulnerability.
DAViCal CalDAV Server 1.1.8 and prior
The application has no protection against CSRF attacks. If an authenticated user visits an attacker-controlled webpage (for example, in another browser tab), the attacker can send arbitrary requests in the name of the user to the application, including requests that result in a state change.
For example, if an attacker includes the following HTML code on his/her site and an authenticated DAViCal administrator visits, a new administrative account “hacker” (password also “hacker”) will automatically be created in the background, giving the attacker full access to the calendaring application:
In a successful CSRF attack, the attacker can change the e‑mail address and password on a victim’s account, which results in a full account takeover. If the compromised user has a privileged (administrator) role within the application, then the attacker is also able to add a new administrator user.
Update to version 18.104.22.168
Technical solution details
The most robust way to defend against CSRF attacks is to include a CSRF token within relevant requests. The idea is that you assign a unique token to a user’s session, this token can be regenerated whenever but this usually happens when a new session is created (e.g.when the user logs out and logs back in). This token is then required to be sent along with the rest of the data you want to submit. Prior to performing the action the called route is supposed to perform(let’s say you want to update your user information) the application will check if a CSRF token is present and whether it’s the right one. Once those two checks pass the application will continue executing.
So the first task was to write a library that would generate a CSRF token and attach it to the session. That’s all pretty basic, the only thing I had to take into account is that the current requirement for DAViCal is PHP 5.6.0 and up so I had to keep backwards compatibility in mind. The token is generated by a random number generator (which one is decided by the current PHP version) and then assigned to the user. Once that was done the only thing left is to make sure every information altering request verifies the CSRF token.
The modern way most web frameworks will handle this is by using middleware. Let’s say you map a route to a function in your code,you can then put a CSRF middleware in the middle of that ‘mapping’. So let’s say you’ve got the following mapping:
You’d then tell your framework to use a CSRF middleware which would change the flow to:
‘/user/information/update’> checkCSRF(); > updateUserInformation();
DAViCal however is quite an old project (the copyright states 2006 as starting year) and we don’t have the luxury of a framework handling these things for us. The easiest solution is to find every place a
POSTrequest is made and manually verifying the token at those places. But I was keen to find out if there was a more central place I could put the CSRF verifying function. As every developer will know, getting to know and understand someone else’s code can be quite a tough one. I found myself using
xdebugquite a lot to figure out the flow of the application until something quite obvious became apparent. There is a PHP file in the project called ‘always.php’ which always runs. This file can be used to launch a function on every page load. This is where I added a function to check the CSRF token on POST requests (which are used in DAViCal to alter information).
The final act was adding the CSRF tokens to all the forms in DAViCal which could be easily found by searching for
</form>. Which concluded the fix for the CSRF vulnerability in DAViCal.
Responsible Disclosure timeline
Reported to the DAViCal CalDAV Server project (no response)
Reported to the DAViCal CalDAV Server project again
Asked for an update regarding these vulnerabilities
The DAViCal project responded that they did not have resources to implement a fix for these vulnerabilities
Partnered up with Niels van Gijzen to contribute a patch
CVE-2019-18345, CVE-2019-18346 and CVE-2019-18347 were assigned to these vulnerabilities
Released a patch that fixes these vulnerabilities
DAViCal verified the patch
DAViCal released version 22.214.171.124 including our patch
DAViCal released version 126.96.36.199 correcting a small oversight