-
Notifications
You must be signed in to change notification settings - Fork 367
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
RUSTSEC-2020-0011 is not a security vulnerability. #275
Comments
It’s definitely an interesting and unusual case. It might make sense to create a new class of informational advisories for cases like this, as those are the existing mechanism for publishing advisories which aren’t specifically an advisory of a security vulnerability (presently they are used exclusively for tracking unmaintained crates). Informational advisories are surfaced as warnings instead of vulnerabilities. |
I see it was filed as a regular security advisory rather than a special "informational" advisory type we use for e.g. unmaintained crates (example). @najamelan how do you feel about downgrading the advisory to a warning? This will still allow using it in |
The crate isn't unmaintained, though. By all appearances it implements its intended functionality perfectly, the only problem is that some people don't like that functionality. |
Co-signed. As written, the crate is a modification to the visual representation of Rust source code; it does not represent or use a vulnerability in either the compiler’s intake parser or output generator. The only change it makes is in the reader-facing representation of a narrow part of syntax.
|
this is code that let's you write memory unsafe code without the |
No, it is not unsoundness. Unsoundness is specifically a term for the emission of a class of incorrect executable instructions, or a class of semantic input that causes the compiler to construct an incorrect view of the abstract program. It does not apply to the dialect of syntax that viewers observe. |
Informational advisories are modeled as an enum: https://github.com/RustSec/rustsec-crate/blob/ee8b2e5/src/advisory/informational.rs#L10-L21 pub enum Informational {
/// Security notices for a crate which are published on <https://rustsec.org>
/// but don't represent a vulnerability in a crate itself.
Notice,
/// Crate is unmaintained / abandoned
Unmaintained,
/// Other types of informational advisories: left open-ended to add
/// more of them in the future.
Other(String),
} I think we could probably use the catch-all "notice" category for this purpose. This surfaces as a warning in |
FWIW, my vote is that some sort of notification is correct here. To draw a comparison: if a crate bundled and made use of a shared object that contained a vulnerability, I would want to know about that, even if all the Rust code in the crate was safe/sound since the expected behavior ("this crate is safe and behaves as expected") is violated. Similarly, |
I'm fine with this being a warning. I just feel this should never slip unnoticed into a dependency graph, and the crate was deliberately designed to exploit a limitation of It is further problematic as grepping for the string I can only conclude that the intend and purpose of this crate is to make reviewing for memory safety harder, which is not something I think should be on crates. If people want to write unsafe code without using the keyword at home, I couldn't care less, but this invites anyone not wanting hassle for using unsafe to just add it as a dep in Cargo.toml and I'd rather we don't make that easier and less transparent. |
If we're going to debate the virtue of a source file, then I'd like to respectfully rejoin that, for example, I am the author of a crate with a ridiculously high This crate provides an opportunity to decrease the background-noise present and increase the signaling capacity of the |
@myrrlyn I'm sorry we disagree, but as a reviewer "these uses of unsafe don't merit review" is one of the assumptions you definitely want to double check, so you want to find all occurrences and not only the ones the author thought were maybe dangerous. |
I don't think "this circumvents I don't quite agree with @myrrlyn -- I don't think one should use this crate in production code -- however, his underlying point about degrees of unsafe is one I strongly agree with. cargo-geiger does nothing to help there. Perhaps that's not the point of the tool, but it's just one of the problems with treating the count of And this advisory database is about security. |
The thing is, security advisories are not about what you think should be on crates.io. There is no security issue here. There should not be a security advisory, informational or otherwise. It devalues the meaning of this database. Let's be clear: we're talking about a crate with 0 reverse dependencies and (as of this writing) 102 downloads by anyone, ever. The only reason there's an "advisory" is because someone saw it mentioned on Reddit and decided they didn't like it. |
+1 on this and the rest of Manish's comment as well. I think this particular sentence should be the main focus of this issue. The security advisory should be removed and a check for this should be added to cargo-geiger if that is deemed necessary. |
Would putting this crate in the advisory database prevent someone from forking and renaming it and then using that fork? If not it seems like this must be fixed in |
If Or what about It's not a security db's job to pass judgement on whether a library is "good." Both You can argue that maybe they shouldn't have been published on crates. But that's not the security advisory db's point to argue. It's also worth mentioning that this advisory won't help prevent any malicious actors from using this technique. It's trivial to reimplement an If anything, this advisory makes it easier to find out about this trick, and accomplishes the exact opposite of its intent of avoiding hiding of |
It seems we're pretty polarized on this issue. I see both sides of it as well: it's definitely true this is not a vulnerability in and of itself, however it'd be nice if, somewhere, there existed a list of crates which circumvent static analysis around safety. There's a case to be made that RustSec isn't the place for it, however in developing the informational advisory feature originally to handle unmaintained crates, my observation was the advisory format is great for cataloging this information. Furthermore, it's been designed to be quite flexible: the alerting behavior for informational crates can be configured on a category-by-category basis. As it were, if we were to catalogue this advisory as informational, by default it wouldn't be surfaced by If we do want to go down this road, I think it might make sense to define a new category of informational advisories for this purpose, although I'm a bit at a loss as to what to call it. Here's what I'd propose as a path forward:
|
I am fine with this being a notice or a warning, but I do find it problematic if that is hidden by default. For one, I have been using and thus to some extend relying on cargo-audit for a while, but I didn't know that I'm not seeing all categories of warnings. And I can't find anything on how to configure that in the README. If it were up to me, Running
Running
It doesn't work, but there is now a mention of a configuration file, hmm... Where is the documentation for how to use the configuration file? I think the point is that people should consent to something like this getting into their dependency graph. Unsafety should be opt in, not opt out. Currently you already need to know about and not forget to run tools like I am fine with notices and warnings returning 0 exit status for CI and such, but for the 0-2 lines of output that an up to date crate should have, is it really that bad to just show everything by default?
No it wouldn't. But if they add it to crates, anyone who notices can file an advisory for it. And if not they need to use a git dep, something that is visible during compilation and can be more consistently detected by cargo deny. For sure there are many ways to do malicious things that are hard to detect right now. The ecosystem isn't very secure. And it's not really feasible to manually verify every version of every dependency, especially as the ecosystem is young and many crates update often. That's where automated tools come in to alleviate the problem somewhat.
People are working on that. |
@najamelan have you misunderstood what fn scary() {
unsafe {
// code
}
} to #[safe]
fn scary() {
// code
} and as such, unsafety is still opt in. It's existence changes nothing about Rust's As for having it be a "this crate shouldn't be used in production code" warning: for one, that's a value judgement that a centralized DB shouldn't be in charge of. (Instead, maybe use a crev review of "don't use," which is a level that they do offer.) But more importantly, how do you define an actual cutoff point for what crates deserve that kind of advisory? There's thousands of toy libraries that shouldn't be used in production, do they all deserve an advisory? And I must stress once again:
Perhaps also cargo-deny should offer functionality to blacklist crates yourself. |
For what it's worth, there aren't presently any advisories in the database using the Agreed the docs could be better, also there are some unmerged PRs which make the warning functionality for informational advisories more flexible.
This is true of any crate an advisory is filed against. The best we can do is handle crates on a case-by-case basis.
I would be perfectly fine with removing the verbiage to that effect from the advisory. Would you mind opening a PR? |
I marked |
I made the wording more objective in #279. I still believe that the advisory should be marked obsolete and the description point people to use |
It is if you use the crate, not if it creeps into your dependency graph. Just to be clear. I just reported this to cargo-geiger, because I felt people should know about it, where it was suggested this should be dealt with by the advisory. At cargo-deny they also think this is something that should be handled by the advisory, so I filed a PR here. Given that this seems to be an uphill battle, just know that it doesn't matter that much to me. Cargo geiger will get fixed, and have got it hardcoded in my cargo-deny configuration. We can agree to disagree, but every time time you do a Probably some companies do development uniquely in containers/VM, but there probably isn't many given the level of friction it adds. And there is no reason to believe Rust developers pick better passwords than npm developers. Seeing plutonium just reminds me of how dire the situation is and warning people about it is a drop in the ocean, but it's a drop. I'd just hope that collectively we find ways to get closer to improving on this one step at a time. |
@najamelan if you care about trusting the packages you're running, you should be using I suppose you should just go ahead and ban proc-caesar as it also allows writing the
You opted in to whatever your dependency is doing when you trusted them to provide a library without doing thorough code review yourself. It really does sound like what you need is cargo-crev. It even provides the geiger numbers as a guideline towards the most important review targets. |
@CAD97 |
I mostly just hope that the RustSec DB can stick to mostly objective advisories. crev's web-of-trust model is built to handle subjective review and trust; the central authority that rustsec uses is best when the central authority has some amount of (perceived) objectivity. |
I actually think the "unsound" class is typically more severe than "unmaintained". Not in this case, but in general. In this case it requires another layer of intent so I still feel it's a different class and should not be the subject of this db. |
That's like saying a buffer overflow is not a bug when the crate says that it is intentional. I do not buy that argument. Sure this is a social system, but it risks becoming meaningless if we do not try to uphold some objective standard. "Soundness" is the objective standard on which the entire Rust ecosystem rests. The social part is the one where we all agree (or not) that soundness is important, and unsoundness a bug. "(Un)sound" is an objective technical criterion, on which crate author intentions have no influence. (The only part I think that is subjective here is how to mark a macro as being "unsafe to use"; I do not know if "it should have We could decide that unsoundness is not a problem when it is intentional. That is how I understand your argument. I strongly disagree with that.
I'd say we should make that distinction. If we did, would you object to an "unsound" advisory being file for plutonium? (EDIT: ah, looks like you do not. We remain in very strong disagreement then.) |
@RalfJung, here's a thought experiment: I think Believing this strongly, I publish a new crate, #[macro_export]
macro_rules! trusted {
{$($tt:tt)*} => {unsafe{$($tt)*}};
} with the intent of using this macro instead of Is this an unsound crate? Does it deserve an advisory, informational or not? I'd argue that it adds an important distinction between encapsulated I ask this because I'd find it unfortunate if we said macros were sound or not based on whether their name contains the string If a macro is intended to always be safe to use, and in some cases allows you to execute unsafe code without upholding the preconditions, then that would be a soundness issue. If a macro is intended to be unsafe to use, even if it doesn't contain the string It's sort of blunt to put it that way, but it comes down to the fact that you need to read the docs for the macros you're using, because they can do anything. (Including, but not limited to, stealing your Bitcoin wallet at compile time.) I'm in full agreement with @Manishearth here; you can use plutonium to write unsound, potentially vulnerable code, but plutonium itself is not unsound nor potentially vulnerable. This is definitely on the edge. proc-ceasar is, honestly, probably also on the edge. The main worry here is, imho, that accepting these "maybe" cases into the central authority decreases trust in said central authority. It would definitely benefit RustSec if it could provide objective rules for when something definitely does deserve an advisory, and some objective rules for things that definitely doesn't deserve an advisory, and should be delegated to more opinionated services like crev, geiger, and/or deny. Even if the middle ground is fuzzy, it's beneficial to have clearly defined areas and guidelines that can be used to make decisions for the middle area. I would personally put the useful "yes this is advisory worthy" main goalposts at
Just a side note: to those saying crev is "worse" than RustSec for this kind of thing because it doesn't have a central authority, for one that's sort of the point, that it doesn't need one. But more importantly, nothing prevents the use of a crev proof repository as a central authority. And yes, crev struggles to bootstrap itself to being useful, due in part to adoption. But if people don't adopt crev because it doesn't have adoption, it'll never get that adoption in the first place. |
A final small wonder: is this (at least in part) due to documentation? If plutonium were more diplomatic in it's documentation, would that change your opinion of its worthiness? I will fully admit that the documentation of plutonium is less than diplomatic; its expressed purpose is to "make everything less safe". But I think the RustSec central authority should at least attempt to avoid making calls based on the diplomacy of documentation. There is, imho, nothing inherently wrong with using macros to create a dialect of Rust where |
For more, see https://doc.rust-lang.org/nomicon/safe-unsafe-meaning.html. From this link:
So what ever I throw in the macro from plutonium, it can never cause any unsoundness, because the compiler has my back right? Unfortunately @RalfJung has already demonstrated that is not the case. By not requiring you to use the keyword Since that is obviously not the case, by using the macro, you say to any onlookers, "nothing to see here, rustc has your back, move on". Which is lying, because you just turned off rustc without wanting us to know that you did. That alone doesn't inspire trust if you ask me. The difference between All in all, the two are conceptually very similar. In
I'm not entirely sure I get what you mean here, but you can have As for reviews, just put a comment on it with a link to the review, or have the actual review text and name of the reviewer in the comment. Of course, if you later change the code, the review is no longer valid and I imagine that's what the discussion was about. No need to remove the |
And that's what the It is just a transform from To be clear, I know the difference between So let me ask you directly, @najamelan: Say I (or @myrrlyn, who has expressed that using this sort of macro would make his crate maintenance easier by separating "kinds" of unsafe) release the /// Alias for an `unsafe` block.
///
/// This should be used to mark `unsafe` blocks that are not in any way dependent
/// on external safe code for correctness. That is, any unsafe preconditions should be
/// upheld solely by code within this block and safety invariants of the code it calls.
#[macro_export]
macro_rules! trusted {
{$($tt:tt)*} => {unsafe{$($tt)*}};
} Would you see it fit to submit a security advisory for that crate? After all, I can write #[macro_use]
extern crate trusted;
fn main() {
trusted! {
*std::ptr::null::<u8>();
}
} and cause UB without the string If you would, I strongly disagree with you. If you wouldn't, what makes this any different than |
Yes
I think I really don't understand what makes the former desirable over the latter. Eg. what problem are you trying to solve? If you want to distinguish between "different kinds of unsafe" in your crate, just put a keyword of your choice in a comment, then you can even search through your codebase for it, no? No unsound, no lying to reviewers, ... |
This seems to be the core argument here. I am inclined to agree with you, with the caveat that deliberately unsound APIs do not contain a “vulnerability” per se (but are still fundamentally “unsound” from an objective, technical perspective). I feel there is some baggage from the way this particular advisory was filed it’d be nice to separate discussion around the above topic on, if anyone wants to open a new issue for discussion (not to mention this issue is closed) |
@najamelan and I don't see the purpose of requiring unsafe code to use the I personally agree that it's probably not worth it to use In any case, I'm not going to argue this point any further one way or another. I agree that you probably shouldn't be using plutonium, after all! What I disagree with is trying to ban plutonium or any other crate that tries to offer a different way to scope |
If we did, I would still dislike it, but I would not be bothered to actually object.
A buffer overflow is different, though. If a crate intentionally causes a buffer overflow, it should be marked as a soundness vuln. This is one level removed, this crate enables others to intentionally escape unsafe. People could, for example, use it the way @CAD97 (and earlier, @myrrlyn) describe, as an "alternate Intent matters because the people writing intentional bugs do not need to be warned, their downstream does. If someone uses plutonium for bad, they should absolutely have their crate placed in this db. (I actually really want the converse of this crate, a macro that converts |
I apologize if the wording in the advisory that it shouldn't be used in production was to strong and to opinionated, and I have no problem with that being changed, but other than that, I really don't see where you are coming from. Nobody is trying to ban anything or lint it out of existence. Only make sure that people are conscious that something really fishy slipped into their dependency tree and that they are ok with that. If there are many like you, it wouldn't be linted out of existence at all. It does sound a bit like the argument that GMO usage shouldn't be labled in ingredient lists because people won't want to buy it. |
That analogy is facile: When you go to the store and buy GMO produce, does the cashier give you a stern look and say "are you SURE you want this"? Labeling something does not make a value judgement, warning on it does. This is why crev and geiger are the right places for this, crev is equipped to handle "this crate does not gel with my subjective values". Crev is the counterpart of the GMO label, not this database. |
@Manishearth what about allowing (Perhaps I should ask them about that idea before suggesting it up front, but) |
Like, third party blacklist databases? Sure. I don't think it belongs here, though |
More like a collection of crates which deliberately expose ...but rather than exposing that information through |
Sure, sounds good |
I also do think the database should try and distinguish between "vulnerability" and "can accidentally let you write UB" (i.e. unsound), because the social processes around fixing the two are different -- specifically the latter may not require action on part of the end user, but might on part of intermediate crates. (End users still need to know, and perhaps pressure their upstreams to verify things, or audit them themselves) |
fn call_asm_bytes(code: &[u8]) {
unsafe {
region::protect(code.as_ptr(), code.len(), region::Protection::ReadWriteExecute).unwrap();
(*(&code as *const _ as *const fn()))();
}
} also let's you intentionally escape unsafe code. It doesn't by itself cause a buffer overflow. Instead you have to pass it asm bytes that perform buffer overflow. However it is unsound, as it doesn't verify the asm bytes for memory safety. This is not much different from other crates that allow you to intentionally escape unsafe. |
If that cashier is called cargo-audit and is there because this shop advertises that they have health and environmental expert at their customers disposal, and I specifically ask them if there is anything I might want to know about this product in those regards, they better. Unfortunately that is not the analogy. It's more like I go and eat at an organic restaurant, because you know, unlike some C-burger restaurants, organic restaurants are not supposed to allow unsoundness in safe food. It so happens that I am one of those customers who always has their FDA expert and a mobile lab with them when they go out eating, so I ask my pocket expert to test the food. The reasoning @CAD97 brings forth here is that my FDA expert should not tell me they detected GMO's in the organic food, because if they did, GMO's would be linted out of existence, which is kind of saying people really shouldn't have the choice, even if they go through lengths of specifically trying to find out about this, because I know that they will reject it and my business model only works if I can force it onto people. I don't say that was their intention, I'm only saying the logic really resembles. |
@najamelan the fact that you've argued for |
That would be my preference, and I feel it's common sense in a safety focused language, but that is not what happens (not today at least), and not what this advisory was about. It also doesn't mean that that needs to happen for all categories of advisories. What I take away from this discussion is that there is demand for:
A possible implementation for |
Just like "GMO" is in actuality a very specifically legislated definition that has gaping holes you could slip a three-eyed fish through, and so people do in fact eat what they would probably label "GMO food" if its production was described to them (whether or not that is a naive decision on their part), it is not the case that people have a choice about whether or not their code includes Sure, people say that open source makes bugs easier to notice, but I sure haven't checked if all 2701 contributors to rustc are in fact not secretly all alter egos creatively devised by Ken Thompson, here to make us really reflect on trusting trust. It would have been really clever of Ken Thompson to find a way to download his mind into my brain if so, but it would hardly be the most surprising discovery of the year, all things considered. I mean... 2020. |
You mean like https://crates.io/crates/unsafe_fn ? :D @CAD97 Those are some good arguments. Indeed I already pointed out the weak spot in my own argument being the definition of soundness of a macro. Re So, given there seems to be rough consensus that tracking soundness violations in the DB would make sense but should be a distinct category, is macro soundness really the main remaining point of contention here? As in, @CAD97 @Manishearth would you agree that a crate with a public function like this should get an advisory filed (in the soundness category) and no amount of docs on the crate's side can make this not an unsoundness? |
Yes, I fully agree that a publicly-exposed safe The language provides no such mechanism for macros. Tangent on the safety of macrosI fully agree that the default for macros is to be safe, and if at all possible, a macro that is not safe to call should require using Unsafe code is tricky, and doing any macro source transforms on unsafe code is scary. |
PR #268 added a security advisory related to
plutonium
, a crate that hidesunsafe
usage.However, the security advisory does not report a security issue with the crate, or any defect with its intended functionality, but makes a value judgement about whether the crate's intended behavior is good.
Security advisories are not for "crates we don't like", they're for conveying information about defects in intended behavior.
The text was updated successfully, but these errors were encountered: