This Week in Security: Cloudflare Wasnβt DNS, BADAUDIO, and Not a Vuln

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.