Andrew Nacin just spoke at Loopconf about the nature of a critical software bug.
No strict mode on WordPress databases
At a base level, the problems originated in that WordPress did not enable strict mode for MySQL. If STRICT_ALL_TABLES
has been enabled, the security vulnerability that was addressed in WordPress 4.2 would not exist.
Without strict mode, MySQL allows more flexible inputs, and doesn’t require the same level of precision in what it allows. For example, a long username would just truncate to the maximum allowed characters, versus be rejected.
Since MySQL can do strange things without strict mode enabled, there are obscure but significant ways for hackers to take advantage.
Defining the scope of a vulnerability
A vulnerability was disclosed to the WordPress security team about two years ago. At its core, the method for forcing MySQL truncation was by using four-byte characters, and then using tricks to store nefarious code in the database.
Nacin used an example of inserting two comments in the database with single quotes and attached four-byte characters. MySQL would truncate the four-byte characters on databases using UTF8 (and don’t allow four-byte characters), and a hacker could utilize the truncated comment (or any other field, really) to add a second comment to finish the exploitation.
The initial vulnerability was fixed in 3.6.1. In 2014, an new disclosure came in from Cedric Van Bochhaven to note that there was still a vulnerability under particular circumstances.
After months of work and “tens of thousands of lines of code” for rewrites and tests, the team realized that they needed to check inputs to the database at a base level of WordPress.
In WordPress 4.2, approximately 1,000 lines of code were inserted into wpdb.php under the guise of emoji support, but were really for fixing this vulnerability.
The original report identified three requirements for the site to be exposed:
- MySQL truncating everything after a four-byte character
- It’s not exposed when utf8mb4 is enabled
- It’s theme dependent
It turned out that really only part of number one needed to be true. They discovered, “this could affect any two fields that would be rendered anywhere near each other.”
Between 11 default database tables and hundreds of fields, basically all parts of WordPress were vulnerable, and core itself also “extensively” relied on non-strict mode functionality.
Furthermore, they realized that even three-byte characters could cause truncation, if they aren’t valid upon insertion.
So of the requirements from the original report, most were not actually required.
“We’re deeper and deeper and deeper into this hole, and we have no idea how to get out.”
The team went back to a discussion from the 3.6.1 vulnerability fix, that does what Nacin calls “preflight checks” that checks many layers of WordPress to ensure allowed data is being inserted.
Checking allowed character sets was not only on the database and table level, but also on columns and fields. Furthermore, the client, the connection, and the server can have their own character sets.
Nacin defines the method for checking as both using a scalpel and a sledgehammer.
We need this to work two different ways: with a scalpel via
update()
,replace()
,insert()
, anddelete()
, and with a sledgehammer via write queries viaquery()
.
Trojan emoji
The code has been in trunk since January, months before the release of 4.2. But it was there under the guise of emoji support, as “noone had any idea what it did because it was 1,000 lines of the database abstraction layer to just remove invalid characters.”
Because of how opaque the vulnerability and the corresponding fix were, the team was able to spend a very long time working on and fixing the issue, all without exposing the vulnerability to the general public.
When 23.9% of the internet uses WordPress, security becomes an even more enormous challenge than in other software. There was an easy fix for this all along: strict mode on MySQL.
However, it would’ve broken “everything.” Alternatively, exposing a vulnerability to the public without a fix that doesn’t break websites makes the vulnerability that much more powerful. It takes a ridiculous effort for the WordPress core team and security team to ensure practical solutions to keep the WordPress software secure and reliable for millions of users.
By the way, if you ever find a vulnerability in WordPress or you get really excited about problems like these, you can email [email protected] to get involved.
If the InnoDB storage engine is used, and STRICT_TRANS_TABLES is set, this problem will be eliminated.
True, however, that’s not really any different than using STRICT_ALL_TABLES.
I don’t really need emojis support in WordPress and I’ve disabled it as suggested on sites such as http://wordpress.stackexchange.com/questions/185577/disable-emojicons-introduced-with-wp-4-2. Will disabling emojis in this case expose me to the vulnerability caused by MySQL truncating everything?
No, the “pre-flight” checks still happen, so you are covered.
Glad to know that. Thanks for the speedy reply!
Very interesting and informative.
There was an easy fix for this all along: strict mode on MySQL. However, it would’ve broken “everything.””
Obvious question: could WP enable strict mode on all new installs?
I don’t think so, because of core’s reliance on non-strict mode in other code.
Do you have any indication of what strict mode would break and why?
Is this something that will *never* be possible, even for new installs?
There’s a core ticket with a giant list of things they’re working on fixing. Maybe someday, but not for a while
What amazes me is that MySQL has been my hair-tearing problem (rant here) for years, and I had no idea it actually had a “suck less” switch.
I once seriously lobbied core devs to at least include support for postgresql, if not full db wrappers for top rdbs.
But, the reply was deafening silence and looks that suggested I had just sprayed every lead developer with concentrated herpes.
The problem there, like not using Apache, is plugins that pretty much require MySQL or Apache and get very upset without them.
I suppose. But imagining the possible upside worth it at that long ago time.
So does that means any sites that haven’t upgraded to 4.2 or higher are still exposed? Which wouldn’t that mean all the sites that just have security and minor updates set to auto but haven’t upgraded to 4.2 yet be unprotected? Or have they also released this as a separate security update after 4.2.
Even if they fixed the issue if you didn’t upgrade your local version (and it’s not set to Auto), it’s still there.
Thank you very much for this article. However, it’s an insight in absolute ridiculousness. A security fix is named emoji support because “noone had any idea what it did because it was 1,000 lines of the database abstraction layer to just remove invalid characters.”
At the end: we’re facing a mindset where “features” are labeled intentionally misleading in WP – so obviously you cannot trust any more what happens in WordPress core code. This is btw. the opposite of Open Source.
I mean: noone ever wanted emojis! The “Disable Emojis” plugin has more downloads than all emoji plugins on wp.org in summary. Nobody understood why this was added to core. Even in code comments you find ironic dissociations regarding the “very important” feature of emojis. And now we hear: it’s about security! – But wait – what if even this is not true … ?
When things have wrong labels you cannot orientate any more. Such a mindset is the end of trust.
I don’t think this is a fair characterization. Emoji/utf8mb4 support was a good feature on its own, and it wasn’t included just because it was good cover. It was a convenient parallel to preventing a security vulnerability from being exposed.
The security team is forced to work in a less open environment than the rest of core development. It’s not to be closed source, but to protect 23% of the web while a vulnerability doesn’t have a proper fix in place — it’s a safety measure.
And just because more people disable it than previously used plugins to support it doesn’t make it an unworthy core feature. There are plenty of other considerations to make.
Hmm..to paraphrase Ben Franklin, “Those who sacrifice Open Source for safety deserve neither”.
I have to agree with Frank here. The fact that OPEN SOURCE stands for freedom and full disclosure and this was not made public 2 years ago or even currently when adding the EMOJI Support does not really instill trust within the community and it violates the founding principles and the philosophy that Richard Stallman and many others worked so hard to createthe GNU general public license.
I am sorry but looking at the facts here, so far we have Google Open Web Fonts super imposed on us which tracks your data and now the EMOJI thing, once has to really wonder if WordPress hasn’t sold out to the establishment because it sure is looking that way and from a security stand point, I can’t say that makes me feel to confident considering the scope of the shit going on with the Government blatantly violating peoples privacy and taking what they want whenever they want. This is a very serious concern!!
Also too, if anyone takes the time to do a (manual) fresh install of wordpress 4.2.2 on a live testing environment you can see that “none” of the tables in PHPMyAdmin are set to uft8mb4_unicode_ci! WHY IS THAT?
If this was such a pending issue then why prey tell did it take (2 years) to fix or come up with a solution? That right there is total B.S because no one takes 2 years to solve a critical security crisis. That all by itself is completely improbable as well as it being illogical to accept that as a suitable answer
> That right there is total B.S because no one takes 2 years to solve a critical security crisis
I can’t even begin to tell you how patently wrong you are. Some critical security bugs, take not only years, but in some cases decades to solve. Last November for example, Microsoft fixed a 19 years and running critical remote code execution security issue, that was present in every version of Windows since 95 (it also fixed another one that was also present since 95 but recently discovered).
I am not wrong because anyone that places security (user security) at utmost priority does not take 2 years or in Microsofts intstance 19 years to fix it.
Why did it take Micro$oft 19 years to fix their security issues? Because they are more interested in their bottom line and live by the adage that we will (sell it now) and worry about fixing it later. In regards to how little Microsoft give a flying F##ck about their users, Windows VISTA is the perfect example. Not only did they promise everything under the sun with that O.S but you also needed to spend thousands of dollars to get a computer with hardware robust enough to run it and to add insult to injury, it was a complete piece of shit and it remains that way to current date! Did they ever make good on their promise? The answer is NO they did not.
Enter Windows 7.. not only is this just a modified VISTA Kernel with a slightly different GUI but it is what VISTA should have been from the beginning!! Did Microsoft give Windows Vista a FREE upgrade to Windows 7?
The answer is NO they did not!!
Does this sound like a company that gives a fuck about your security? NO IT DOES NOT!!
It is amazing what you can accomplish when you actually give a damn. To use Microsoft as a reference to follow on security or how to gauge standards is a horrible Idea because they are a perfect example of what is wrong with present day society and the mindset that goes along with it!!!
Please be civil. He was giving you a counter example, not putting Microsoft on a pedestal.
I am not being uncivil towards the gentleman that left the comment I am emphasizing the point of how flawed the ideology of individuals and those in business is these days.
I hope that clears things up.
Cam, it’s unfair to claim “no one takes 2 years to solve a critical security crisis,” and to “imply” the WordPress core developers don’t give a damn about security. Each problem presents it’s own difficulties, one of which is the fact WordPress is used in many different server environments, even on Macs and Windows. Each problem also takes a different amount of time to resolve. Not all problems are black and white, there are often many variables to consider, which can take sometimes years to unravel and solve. Unless you were involved in the process to fix this security issue, it’s not fair for you, or anyone to judge from a distance. On another note, if you, or someone else, had offered a suitable fix sooner than 2 years, and that solution had been rejected by the security team, then you’d have a reason to complain, otherwise you’re just being unfair to the entire team, rather than being thankful they cared enough to fix the problem, and despite it taking 2 years of careful planning and research.
The security team deserves a big “THANK YOU!” THANK YOU! THANK YOU! THANK YOU!
I am not trying to discredit those involved in the core development team. However, OPEN SOURCE represents FREEDOM, full transparency and community. By not saying anything for 2 years they violated the trust of the community and that makes them no different from corporate America.
Considering that the whole point of Open Source is community involvement and community awareness and doing the exact opposite of what the evil corporate agenda does, what do we have left when the founding principles are ignored by a select few?
That is not Open Source and That is the entire problem here.
Interestingly enough, there was a brief period during the 4.1 development cycle where STRICT_ALL_TABLES was turned on: https://core.trac.wordpress.org/ticket/21212#comment:32
Got a bunch of failing unit tests when we were testing our plugins against (at the time WP 4.1 alpha) and it was due to that. I suspect they pushed it in hoping it could be an “easy fix” but realized it would potentially “break” plugins/themes.
Personally, I think it’d still be a good idea to get STRICT_ALL_TABLES turned on but just give plenty of leeway for plugin and theme devs to get their code ready.
It’s coming at some point. Core needs to get all of the issues with turning strict mode on breaking core stuff first. There’s a couple people working on that atm
I’m interested to know more about securing a website even though I’ve not started with a steady rolling my business online !