Your partner as an attack surface
When it comes to WordPress security, I employ numerous defense-in-depth techniques. From a WAF to locking down WordPress core and keeping up to date with patches (and others I won’t disclose), my goal is to ensure that an attacker has a difficult time penetrating the sites that I host.
Three weeks ago I suffered three site breaches in a span of a week. The culprit? A compromised agency partner whose administrator passwords for WordPress sites were exfiltrated and compromised.
The truth is that this is a difficult attack to defend against. Here’s how I have approached it.
What happened
In July, several sites run by an agency partner were attacked and compromised. I reviewed each site and determined that the same user was used to log into all three, and despite having separate passwords set, there was no credential stuffing attack. These were direct logins with a known password.
I cleaned the malware off each site and notified the agency owner that there was a compromised password. I also reset their password on the remaining shared sites that we work on together; that way, any further compromised credentials were not used.
The total time it took me was around 20 hours to clean up the sites, execute the forensic investigation, and confirm the source.
Why this is the worst thing to defend against
Despite my defense-in-depth approach, the agency that shares passwords amongst itself is still the weak link. Storing passwords in Google Docs or shared documentation is a recipe for exfiltration should one team member be compromised. With plenty of password exfiltration exploits running around package managers these days, it’s a matter of when, not if.
I saw a post on Mastodon recently decrying the rise of two-factor authentication (2FA) requirements for people who might otherwise not have smartphones or technology expertise. I can understand where they’re coming from, but the reality is that this is exactly the kind of attack that 2FA is designed to stop. Something you have + something you know is defense-in-depth for authentication. Without it, password exfiltration leads to compromise.
What I did next
Next steps for me included installing 2FA on all sites I manage, and allowing a code to be emailed to the user as a valid 2FA mechanism. On the assumption that this friction would stymie most script kiddies, this allows me to build in security without being overtly obnoxious. For the more technically-inclined I also enabled WebAuthn to ensure that Passkeys can be used. Finally, I insisted on per-user accounts, rather than shared ones. Enabling 2FA also makes password sharing more difficult and ensures people use their own accounts. This gives me a valid audit trail.
I also gave the users a grace period before 2FA becomes mandatory, and let them know that I was enabling it. My clients trust me to protect and defend their websites, and I have an obligation to do so effectively. Most appreciated the work I did on their behalf.
Still, some clients were frustrated by the 2FA requirement. I understand: it adds friction to their login process. But a hacked website causes lost trust and eroded confidence. And the type of attack that these sites suffered can also cause consequences for the visitors who fell victim to the scam.
Bottom Line
As attackers get more sophisticated in their approach, strong security matters more than ever. Methods like 2FA are essential, not optional. WordPress doesn’t yet support 2FA in core, but I hope it will soon. Until then I recommend using something like Two Factor, produced by WordPress Contributors. It’s free, maintained, and effective.