
Security advisory for crates.io - aurhum
https://users.rust-lang.org/t/security-advisory-for-crates-io-2017-09-19/12960
======
tetraodonpuffer
the response time of the rust team was extremely quick, great job!

2017-09-13 @ 19:19 - Justin sends mail to security@rust-lang.org about this

2017-09-13 @ 19:28 - response sent to Justin acknowledging the vulnerability

2017-09-13 @ 21:14 - a patch to crates.io was finished, all current tarballs
verified not-malicious

~~~
nindalf
Gotta agree, a response that rapid is impressive.

------
steveklabnik
As always: there are no silver bullets. Static typing, nor Rust, can save you
from all bugs.

If you follow the link to the security announcement list, you can see the one
other advisory we've had since 1.0 as well.

~~~
tetromino_
Rust gives us memory safety. But I wonder if somebody is working on a language
which syntactically enforces safe filesystem access, and relegates anything
resembling the POSIX API to unsafe{}?..

~~~
otakucode
'Safe' filesystem access? Honest question, but what would that look like? How
is my software going to know that inserting 'no' into my mail file or
overwriting a file or creating a new one was a 'bad' operation? Aside from
adopting an immutable content-addressable storage system (something like
Camlistore) I'm not sure how filesystem access could ever approach 'safe.'
But, I haven't given it a great deal of thought or reading, so you might be
referring to something entirely different or have better ideas.

~~~
tetromino_
For example, the hypothetical language could require you to declare that a
block of code is allowed to write only within a certain filesystem path (or
list of paths). Attempts to escape from the path prefix - e.g. using /../ \-
would be caught by the compiler for static paths; and non-static strings
representing paths would be required by the language's type system to be
passed through a specific validator before they can be used for filesystem
access.

~~~
wahern
Symlinks mean that you cannot simply validate the path string. You need to
iteratively walk the path using openat(2) to avoid TOCTTOU bugs. But
iteratively walking the tree with openat makes it tricky to tell if you've
left the containing directory, especially if you dereference symlinks
(disallowing them would be easier). This sort of thing is better handled in
the kernel; or rather, whatever code is resolving and creating the resource
handle in the first instance.

Unix chroot provides precisely the behavior desired here; unfortunately it
requires root privileges.

Capsicum introduced the O_BENEATH flag to the openat(2) system call.
openat(somedirfd, path, O_BENEATH) will fail if the path references a file
above somedirfd. Unfortunately I don't think it has yet made it into Linux or
FreeBSD, no doubt because the semantics are trickier than you'd think (there
are very good reasons why chroot is limited to root, so you can't simply reuse
the chroot infrastructure). See
[https://lwn.net/Articles/619146/](https://lwn.net/Articles/619146/) and
[https://reviews.freebsd.org/D2808](https://reviews.freebsd.org/D2808) and
[http://capsicum-linux.org/](http://capsicum-linux.org/)

------
benmmurphy
the second 'precaution' fix looks actually important because it stops an
archive from a following a symlink it creates that would allow it to write
outside of the package directory. my thoughts are:

before the precaution fix this was a legal archive:

    
    
        $crate_name-$crate_version/outside -> ../
        $crate_name-$crate_version/outside/$other_crate-$other-version/blah/blah
    

then you have this code:

[https://github.com/rust-lang/cargo/pull/4493/files#diff-
ce3a...](https://github.com/rust-lang/cargo/pull/4493/files#diff-
ce3ac564b3688633fe9c7ccb934e6253L316)

    
    
      tar.unpack(dst.parent().unwrap())?;
    

so while Archive#unpack protects you against following symlinks outside of
`dst` (which is a really good default!) it doesn't protect you from following
symlinks inside of `dst` so presumably you can use the symlink trick to
overwrite other packages.

i haven't tested this so this could be wrong :/ like maybe archive by default
doesn't create symlinks or reorders the extraction so symlinks are always
created last.

------
majewsky
I cannot read this security advisory because I don't allow third-party JS. No
punchline.

~~~
steveklabnik
If you subscribe to rustlang-security-announcements@googlegroups.com , you'll
get emails. No JS required there.

(With Javascript disabled, that page still renders, so I'm not sure why it
doesn't show for you.)

~~~
cesarb
It might depend on how the Javascript is being blocked. I use uBlock Origin
advanced mode to selectively block Javascript (I imagine uMatrix is similar),
and always have to whitelist discourse's CDN.

The difference is probably that selective blockers like uBlock/uMatrix don't
show <noscript> elements, while globaly disabling Javascript does, and
discourse might be relying on the noscript element (on mobile right now, so I
can't check to be sure).

~~~
steveklabnik
Possibly, yeah; I went to about:config to disable it and triple check before I
made my comment. Maybe it interacts differently with various plugins.

------
jacquesm
Why is it that people are still writing code in languages such as Rust when we
have much better alternatives such as C. In C this bug would have never
happened. ;)

