-
Notifications
You must be signed in to change notification settings - Fork 76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CVE-2024-27322 and this package #406
Comments
@schochastics @jsonbecker thoughts? |
In my opinion, I mention allow list because I think we'd want to include things like This would be a breaking change, potentially, and may warrant a major version number update if we wanted to be closer to semver. |
I just made https://github.com/hrbrmstr/rdaradar and I think doing some quarantining of R data files in the rio load process to then pick out "data frame-like objects" might be the way to go |
So in this case, we'd:
Are there any concerns about how R makes it... incredibly simple to just declare you're one class (along with others)? Put another way, should we restrict certain classes explicitly as well, regardless of whether they also declare they are a data.frame-alike? |
Thank you all for the feedback. Specifically, this is the line that makes exceptions for the serialization formats. Lines 146 to 148 in c529994
And for other formats, rio will force the output to be data.frame. SEE BELOW Lines 43 to 52 in c529994
Lines 126 to 145 in c529994
Let me give it a test. |
I was wrong. Data will be forced to data frame anyway. tmp <- tempfile(fileext = ".R")
dput(LETTERS, tmp)
rio::import(tmp)
#> NULL
#> <0 rows> (or 0-length row.names)
tmp <- tempfile(fileext = ".R")
dput(iris[1:2,], tmp)
rio::import(tmp)
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1 5.1 3.5 1.4 0.2 setosa
#> 2 4.9 3.0 1.4 0.2 setosa
tmp <- tempfile(fileext = ".dump")
dump(list = as.character(substitute(LETTERS)), file = tmp)
rio::import(tmp)
#> NULL
#> <0 rows> (or 0-length row.names) Created on 2024-05-01 with reprex v2.1.0 |
And of course, I have to pwn myself. tmp <- tempfile(fileext = ".Rdata")
delayedAssign("x", system("gnome-calculator"))
save(x, eval.promises = FALSE, file = tmp)
rio::import(tmp) |
@hrbrmstr @jsonbecker Maybe I've missed something, but it doesn't appear to be safe. tmp <- tempfile(fileext = ".Rdata")
delayedAssign("x", system("gnome-calculator"))
save(x, eval.promises = FALSE, file = tmp)
quarantine <- new.env(parent = emptyenv())
load(file = tmp, envir = quarantine) ## not pwned yet
## load(file = tmp, envir = quarantine); print(ls.str(quarantine, all.names = TRUE), max.level = 999, give.attr = TRUE) ## pwned
## load(file = tmp, envir = quarantine); inherits(quarantine[["x"]], "data.frame") ## pwned
## load(file = tmp, envir = quarantine); body(quarantine[["x"]]) ## pwned
## load(file = tmp, envir = quarantine); class(quarantine[["x"]]) ## pwned |
qsbase/qs#93 patched upstream. |
If you want to ensure that a loaded object contains no PROMSXPs I think the best way would be to recursively inspect it using the C API. There may be a pure R way to do it but using C is more straightforward. |
@traversc Yeah, I think this is probably the only viable solution. But I also think that it is not a thing this package should do. Maybe it should be the task of R itself (as I said in HenrikBengtsson/Wishlist-for-R#162) or a new package with a promise-free version of |
@chainsawriot I think that’s right. Another thought that may be “worthwhile” — maybe loading an RDS requires a new flag called something like “trust” — that defaults to FALSE and provides a message like “Deserializing RDS may lead to arbitrary code execution. You should only load RDS files you produced or trust. Set |
@jsonbecker That's a nice idea to nudge users into not using those serialization formats (even non-binary ones like Python's |
Yup, I thought about that from a semver perspective. Another two choices here are:
|
Even with this d63ccb5 one can still be pwned with tmp <- tempfile(fileext = ".Rdata")
delayedAssign("x", system("gnome-calculator"))
save(x, eval.promises = FALSE, file = tmp)
import_list(tmp, trust = FALSE) Lines 82 to 90 in ca019c9
|
CVE-2024-27322 is partially fixed in R 4.4.0. But the attack surface is still there. First, this package supports R > 3.6 therefore the partial fix in 4.4.0 is not applied in many supported versions. Second, even with 4.4.0 deserialization of
.Rdata
and.RDS
in some cases can still invoke arbitrary code execution. See this message by gws.We can't be too nanny but should we rethink the "any R object" policy of
.Rdata
rio/R/import.R
Line 31 in c529994
.RDS
rio/R/import.R
Line 32 in c529994
and
qs
rio/R/import.R
Lines 33 to 35 in c529994
There are several options:
The text was updated successfully, but these errors were encountered: