Two Factor Authentication Cross Site Request Forgery (CSRF) vulnerability (CVE-2018-20231)
At BitnessWise we recently did a review of a few Two Factor Authentication (2FA) plugins for WordPress. First we selected some candidates based on usability and free-version features and after that performed a technical review of the plugin. This revealed a vulnerability we’d like to discuss in this post for future reference and to better understand the issue.
Many people think the security of WordPress is bad to begin with and they might also think that adding 2FA is not going to improve it much. The security of WordPress is not something we want to go into detail to in this post however. The simple fact remains that a lot of people use it and making their choice more secure is always a good thing. This is also why we found it important to look at the free-version features too: not because we think security should be free, but because we wanted to select one for a broad audience – also those who don’t have the means to pay for a plugin.
The plugin
The Two Factor Authentication plugin seemed like a good choice and functionally we found it working nicely as well. It worked intuitively and the setup was very easy.
Code review
We have a policy that we never add plugins we don’t review first. A plugin might simply be written badly, but there’s also a few rotten apples out there that are written with malicious intent. Even if the plugin has many installations and especially if it’s meant to enhance the security.
Overall this plugin made a good impression, but nevertheless we were able to find one hole in the security: the functionality to enable or disable 2FA for the current account was not protected against Cross Site Request Forgery (CSRF). This means that a successful CSRF attack would succeed in disabling the second factor step for the login, thereby stripping that line of defense completely. The only thing needed for such an attack would be to trick the victim into clicking on a link while being logged in – as we will demonstrate below in a POC that we wrote.
This type of attack is easier to carry out as you might think at first: consider for example the scenario where the attacker writes a comment (including a malicious link) to a post from an author he already has the credentials of (through phishing/leaked database/etc). The author logs in to review new comments, clicks on the link in the comment and without knowing it disables his/her 2FA.
Proof of Concept
We created a POC that can be used to test if your version of the Two Factor Authentication plugin is vulnerable. Of course you can also determine this by simply looking at the version (all versions below 1.3.13 are vulnerable), but some people might still want to test it for various reasons. And as stated, this post is mainly to help understand the vulnerability which is why we’re including this POC.
By clicking on this link you can review the POC and if you like, save it to your local file-system. It is written in HTML/Javascript so it doesn’t depend on a backend language like PHP.
To mimic a real-world-scenario of an exploit, the actual disabling happens invisible in the background after you click on the button. Of course, an attacker would never ask you to enter the url to your website and click on a button – this would be hard-coded (and invisible) in the source – but that is to make the POC work for anyone that wants to test his/her version. In a true real-world-scenario you would simply see a normal web page that expects you are coming and already knows your website. You wouldn’t notice anything out of the ordinary and no further interaction would be needed.
Conclusion
It pays off to review plugins and open source wins again!
Naturally we followed the Responsible Disclosure principles and notified the author(s) of what we had found. They took it very seriously and released a new version within half a day after our report! Great work, that shows they care about their product.
So if you’re a WordPress user and you haven’t protected your login yet with 2FA, we can recommend installing this plugin.