You may have noticed that large pieces of the Internet were down on Tuesday. It was a problem at Cloudflare, and for once, it wasn’t DNS. This time it was database management, combined with a safety limit that failed unsafe when exceeded.
Cloudflare’s blog post on the matter has the gritty details. It started with an update to how Cloudflare’s ClickHouse distributed database was responding to queries. A query of system columns was previously only returning data from the default database. As a part of related work, that system was changed so that this query now returned all the databases the given user had access to. In retrospect it seems obvious that this could cause problems, but it wasn’t predicted to cause problems. The result was that a database query to look up bot-management features returned the same features multiple times.
That featurelist is used to feed the Cloudflare bot classification system. That system uses some AI smarts, and runs in the core proxy system. There are actually two versions of the core proxy, and they behaved a bit differently when the featurelist exceeded the 200 item limit. When the older version failed, it classified all traffic as a bot. The real trouble was the newer Rust code. That version of the core proxy threw an error in response, leading to 5XX HTTP errors, and the Internet-wide fallout.
Dangling Azure
There’s a weird pitfall with cloud storage when a storage name is used and then abandoned. It’s very much like what happens when a domain name is used and then allowed to expire: Someone else can come along and register it. Microsoft Azure has its own variation on this, in the form of Azure blob storage. And the folks at Eye Security’s research team found one of these floating blobs in an unexpected place: In Microsoft’s own Update Health Service.
The 1.0 version of this tool was indeed exploitable. A simple payload hosted on one of these claimed blob endpoints could trigger an explorer.exe execution with an arbitrary parameter, meaning trivial code execution. The 1.1 version of the Update Health Service isn’t vulnerable by default, requiring a registry change before reaching out to the vulnerable blob locations. That said, there are thousands of machines looking to these endpoints that would be vulnerable to takeover. After the problem was reported, Microsoft took over the blob names to prevent any future misuse.
BADAUDIO
There’s a new malware strain from APT24, going by the name BADAUDIO. Though “new” is a bit of a misnomer here, as the first signs of this particular malware were seen back in 2022. What is new is that Google Threat Intelligence reporting on it. The campaign uses multiple techniques, like compromising existing websites to serve the malware in “watering hole” attacks, to spam and spearphishing.
Notable here is how obfuscated the BADAUDIO malware loader is, using control flow flattening to resist analysis. First consider how good code uses functions to group code into logical blocks. This technique does the opposite, putting code into blocks randomly. The primary mechanism for execution is DLL sideloading, where a legitimate application is run with a malicious DLL in its search path, again primarily to avoid detection. It’s an extraordinarily sneaky bit of malware.
Don’t Leave The Defaults
There’s an RCE (Remote Code Execution) in the W3 Total Cache WordPress plugin. The vulnerability is an eval() that can be reached by putting code in a page to be cached. So if a WordPress site allows untrusted comments, and has caching enabled, there’s just one more hurdle to clear. And that is the W3TC_DYNAMIC_SECURITY value, which seems to be intended to stave off exactly this sort of weakness. So here’s the lesson, don’t leave this sort of security feature default.
Not a Vulnerability
We have a trio of stories that aren’t technically vulnerabilities. The first two are in the mPDF library, that takes HTML code and generates PDFs — great for packaging documentation. The first item of interest in mPDF is the handling of @import css rules. Interestingly, these statements seem to be evaluated even outside of valid CSS, and are handled by passing the URL off to curl to actually fetch the remote content. Those URLs must end in .css, but there’s no checking whether that is in a parameter or not. So evil.org/?.css is totally valid. The use of curl is interesting for another reason, that the Gopher protocol allows for essentially unrestricted TCP connections.
The next quirk in mPDF is in how .svg files are handled. Specifically, how an image xlink inside an svg behaves, when it uses the phar:// or php:// prefixes. These are PHP Archive links, or a raw php link, and the mPDF codebase already guards against such shenanigans, matching links starting with either prefix. The problem here is that there’s path mangling that happens after that guard code. To skip straight to the punchline, :/phar:// and :/php:// will bypass that filter, and potentially run code or leak information.
Now the big question: Why are neither of those vulnerabilities? Even when one is a bypass for a CVE fix from 2019? Because mPDF is only to be used with sanitized input, and does not do that sanitization as part of its processing. And that does check out. It’s probably the majority of tools and libraries that will do something malicious if fed malicious input.
There’s one more “vulnerable” library, esbuild, that has an XSS (Cross Site Scripting) potential. It comes down to the use of escapeForHTML(), and the fact that function doesn’t sanitize quotation marks. Feed that malicious text, and the unescaped quotation mark allows for plenty of havoc. So why isn’t this one a vulnerability? Because the text strings getting parsed are folder names. And if you can upload an arbitrary folder to the server where esbuild runs, you already have plenty of other ways to run code.
Bits and Bytes
There’s another Fortinet bug being exploited in the wild, though this one was patched with FortiWeb 8.0.2. This one gets the WatchTowr treatment. It’s a path traversal that bypasses any real authentication. There are a couple of validation checks that are straightforward to meet, and then the cgi_process() API can be manipulated as any user without authentication. Ouch.
The Lite XL text editor seems pretty nifty, running on Windows, Linux, and macOS, and supporting lua plugins for extensibility. That Lua code support was quite a problem, as opening a project would automatically run the .lua configuration files, allowing direct use of os.execute(). Open a malicious project, run malicious code.
And finally, sometimes it’s the easy approach that works the best. [Eaton] discovered A Cracker Barrel administrative panel built in React JS, and all it took to bypass authentication was to set isAuthenticated = true in the local browser. [Eaton] started a disclosure process, and noticed the bug had already been fixed, apparently discovered independently.
Dogfooding is usually a good thing: That’s when a company uses their own code internally. It’s not so great when it’s a cloud company, and that code has problems. Oracle had this exact problem, running the Oracle Identity Governance Suite. It had a few authentication bypasses, like the presence of ?WSDL or ;.wadl at the end of a URL. Ah, Java is magical.

Please be kind and respectful to help make the comments section excellent. (Comment Policy)