Open source programming language R patches gnarly arbitrary code exec flaw
An ACE in the hole for miscreants
Updated The open source R programming language – popular among statisticians and data scientists for performing visualization, machine learning, and suchlike – has patched an arbitrary code execution hole that scored a preliminary CVSS severity rating of 8.8 out of 10.
The vulnerability, tagged CVE-2024-27322, can be exploited by tricking someone into loading a maliciously crafted RDS (R Data Serialization) file into an R-based project, or by fooling them into integrating a poisoned R package into a code base. Doing so will trigger the execution of a code payload within the file or package, which could leak the user's files to another source, delete data, or perform other devilish activities.
The hole was closed in version 4.4.0 of R Core, which was released earlier this month – upgrading ASAP is strongly advised.
The flaw lies in how R deserializes data. R's built-in deserialization feature, which loads information from files to unpack into data structures in memory, is insecure and can be exploited to execute arbitrary code on a victim's machine.
The good news is that it is somewhat complicated to exploit, according to this analysis by Kasimir Schulz and Kieran Evans at AI security shop HiddenLayer. For the nitty-gritty, see their write-up which, as they put it, "involves the use of promise objects and lazy evaluation in R."
The biz offers some proof-of-concept code to exploit this security oversight, which prints out some text when a malicious file is deserialized by R. This code can be swapped out for something far more malicious.
Attacks could target supply chains or even specific individuals
HiddenLayer warns attackers could use the oversight to compromise the software supply chain.
The Comprehensive R Archive Network (CRAN) hosts and distributes over 20,000 R packages, and anyone could upload one – including one that has malicious code secretly embedded into it. At the time the HiddenLayer advisory was written, CRAN's automatic scans didn't check packages for a CVE-2024-27322 exploit.
What's especially concerning is that merely loading a package can trigger the hidden payload. HiddenLayer demonstrated that even opening the R Console could activate arbitrary code execution.
- Flaws in Chinese keyboard apps leave 750 million users open to snooping, researchers claim
- Rust rustles up fix for 10/10 critical command injection bug on Windows in std lib
- Apple, AMD, Qualcomm GPU security hole lets miscreants snoop on AI training and chats
- Cisco's critical zero-day bug gets even worse – 'thousands' of IOS XE devices pwned
"Like Python's pickle module, the exploitation of this vulnerability depends a lot on the environment of the targeted user but opens a lot of potential attack vectors," HiddenLayer's principal security researcher Kasimir Schulz told The Register.
"These could include social engineering a user to download a malicious file, allowing a file write attack to become a code execution attack, or even allowing a remote attack if a service allows for untrusted RDS formatted data to be uploaded.
"As an example for the targeted approach, a threat actor could craft such a file and sneak into researcher communities under the guise of a researcher seeking help.
"They could then send their code and a 'dataset' in the RDS format to other researchers who have offered to help them, with any who load the RDS file having their entire system compromised."
We've asked CRAN for comment. In the meantime, don't forget to patch. ®
Updated to add
"The ability to write malicious code in R does not imply that the language itself is insecure. The base R language is maintained by a select group of high-trust individuals in The R Core Development Team, most of whom have been working on the language for decades," a CRAN spokesperson told The Register after publication.
"Like any open source project, we rely on our wide user base to identify bugs in the source code. We welcome all bug reports, including those with security implications. The bug report by HiddenLayer is one such example. Briefly, promises are language objects used to implement lazy evaluation. Promises constructed in R are always bound to an environment, but HiddenLayer found a way to make an unbound promise by deserializing a hacked file. This bug has been fixed in R 4.4.0 and any attack vector associated with it has been removed.
"We reject the idea that there are wider security implications associated with promises or serialization, both of which are core features of the language."