Update: Fixed! Duo WordPress Plugin 2.2 Now Available
Duo/WordPress admins/users are advised to download the most recent plugin version 2.2 that fixes the multisite bypass issue.
For a full explanation of our fix, check out our blog, Duo Security's WordPress Plugin Updated to Address Multisite Vulnerability!
We recently discovered a vulnerability in our duo_wordpress plugin, employed by users to protect their WordPress blogs and sites with our two-factor authentication service. The vulnerability only affects a subset of WordPress deployment models, namely, "Multisite" deployments where the plugin is enabled on an individual per-site basis. The impact of the vulnerability may allow a user of one site of a multisite WordPress deployment to bypass the second factor of authentication of another site.
Clarifying the Impact
As part of our security response program, we notified our customers this morning of the vulnerability. The full advisory sent to customers can be found here.
Throughout the afternoon, we observed some reactions on social media sites to our notification. There were several instances of misinformation being spread (eg. that normal non-Multisite deployments were affected, that people should completely disable the duo_wordpress plugin, etc), so we thought it was prudent to write this post to clarify the scope of the issue and prevent any further misinformation.
To reiterate the impact of the vulnerability:
Only WordPress "Multisite" deployments that have chosen to deploy the plugin on an individual site basis are affected.
Normal WordPress deployments or Multisite deployments with the plugin enabled globally are NOT affected.
The user must still present correct primary authentication (eg. username and password); only the second factor is bypassed.
The Broader Impact
As it turns out, the vulnerability discovered by our engineers is not unique to the duo_wordpress plugin. We've determined that authentication plugins from other two-factor vendors are similarly affected by this vulnerability. We're no stranger to helping our competitors discover and fix vulnerabilities in their integrations, so we've reached out to the affected vendors to share our findings.
If you're using a WordPress two-factor plugin other than duo_wordpress, you should check with the upstream vendor to see if your plugin is affected. Also, if you're not yet using duo_wordpress, you should check it out! :-)
Towards a Fix
We're continuing to work internally to devise a permanent fix to the discovered issue and are engaging with WordPress, as core modifications to the WordPress plugin architecture may be necessary to properly fix the issue. We will be providing additional information to our customers as it becomes available.
In the meantime, as the advisory states, we have recommended a workaround for WordPress Multisite deployments: enable duo_wordpress globally, and disable it for specific user roles.
If you're interested in the technical details of the issue, read on!
Appendix: Technical Details
WordPress' plugin architecture is designed such that our plugin is called after primary authentication has succeeded, but only for the blog/site the user is authenticating against. Since other WordPress sites in the same multisite network can authenticate each others' users, a user of one blog can provide their primary credentials to another (non-2FA-enabled) blog in that network. Assuming primary authentication succeeds, the user will be redirected back to blog they're a member of, fully authenticated without ever hitting a two-factor prompt.
Perhaps this is best explained with a fancy flowchart. Consider two users, Alice and Bob, who are members of the WordPress blog "Site1", part of a multisite network which includes the "Site2" blog. Site1 has duo_wordpress enabled, and all user roles are subject to two-factor authentication. Site2, however, has duo_wordpress disabled. If Alice browses to Site1 like normal, she will need to provide both primary credentials as well as pass second factor authentication in order to log in. However, Bob browses to the login page for Site2, where he provides his Site1 credentials. Once he passes primary auth, he is redirected straight to Site1.