10 ms·
So, we get it. Complicated file and network formats, handled in C code leads to these types of security issues. We are told that Rust will save us. Glib answer
by askyourmother 10y ago
So, we get it. Complicated file and network formats, handled in C code leads to these types of security issues.
We are told that Rust will save us. Glib answer - if it was going to, it already would have (and this is from someone already writing Rust code).
I hope it will lead to a change on two fronts:
1. Simpler formats for file representation and data interchange. When someone tries to add an extra bitfield option, say no. When they keep trying, get a wooden stick with "no" written on it. Part of the disease of modern computing is bloated specs.
2. Restrictive not permissive code bases. Exit and bail out early. Tell the user "file corrupted". Push back.
- quanticle 10y agoRegarding point 2, I think we need to consider Postel's Law a design antipattern, rather than a hallmark of good design. From now on, good software should not be permissive in what it accepts, because there is no good way to guarantee that such permissiveness will not lead to security breaches down the line.
- eudox 10y agoAdditionally, being conservative in what you accept forces people to be conservative in what they emit upstream. Win-win!
- unlinker 10y agoTell that to HTML engines ;P
- catnaroek 10y agoHas any browser implementor ever given it a serious try?
- seba_dos1 10y agoXHTML?
- catnaroek 10y agoThat wasn't serious enough. Did any browser ever reject a Web page just because it wasn't well-formed XHTML? Basically, give people a hand, and they'll grab your whole arm. It's human nature, and Web developers aren't above it.
- unlinker 10y agoThat would be madness. Imagine a browser that did that, or that crashed the tab in case of a JS error. There would be no pages left :P
- catnaroek 10y agoIt would be a lot more sensible than you think. When I get a compilation error, what I do is take a breath, think about the meaning of my code, correct any logical mistakes I can find, and try to compile again. Why couldn't Web developers do the same? Also, there's no need to crash the tab. The browser could simply stop running any JavaScript, and leave the user with a static page.
- regularfry 10y agoAnd this is precisely the point. If the very earliest browsers had insisted on correctness rather than permissively accepting broken HTML (and JS - see semicolon insertion), we would not now have a situation where browsers need to do a ton of work to allow graceful degradation in the face of awful markup, simply because the tooling would have evolved in the other direction. Postel's Law gains a little temporary sender convenience in exchange for a nasty mess of permanent receiver headaches.
- GrumpyYoungMan 10y agoI would disagree with that greatly. Postel's law says there's no need to excessively constrain what's considered valid input, not to ignore basic bounds checking and security. Not following Postel's law would result in brittle system components that break when other parts of the system evolve.
- eudox 10y ago>Not following Postel's law would reult in brittle system components that break when other parts of the system evolve. Being liberal in what you accept is precisely the definition of brittle: if there's an update that reduces the set of representable input data, but you keep the code that processes the user's input into data, then an untested, little-used edge case could invalidate your assumptions about the rest of the system.
- pbh101 10y ago>Not following Postel's law would result in brittle system components that break when other parts of the system evolve. This depends how much graceful degradation you have available to you. In systems/domains where little is available, following Postel's law can result in silent failures rather than explicit/loud ones. The question isn't whether they break or how brittle they are, but whether you will notice whether they did break. Each system exists within a range on a continuum of how acceptable Postel's law is.
- catnaroek 10y agoAlso, just because Postel's law worked for a small group of highly skilled systems programmers implementing common infrastructure for everyone, it doesn't automatically follow that it will work for a large and fast growing group of programmers of wildly varying skill, each implementing their own or their employer's brilliant business idea.
- deleted 10y ago[deleted]
- saidajigumi 10y agoCounterpoint: Literally the only thing that allows forward compatibility on the web is permissiveness. When a browser sees something like this in CSS, .foo { someprop: boring-old-value; someprop: awesome-new-value; } instead of old browsers that don't understand just throwing a fit and dying, they ignore stuff they don't understand and carry on. So we know that a browser which doesn't implement 'someprop: awesome-new-value' will go ahead and read 'someprop: boring-old-value' instead of stopping processing of the CSS, or worse, emitting an error and refusing to render the page altogether. Without this, it would effectively be impossible to ship new web features until old browsers had died off to <epsilon-of-users-we-don't-care-about>.
- ashearer 10y agoThere's a crucial distinction to be made. Ignoring unknown properties is a defined part of the CSS spec, so implementing it that way is just being correct. Postel's Law leads to trouble when "being liberal" means unilaterally extending the spec in ill-defined and ultimately incompatible ways. Example: autocorrecting "awesome-new-value" to its closest known match "alternative-old-value".
- saidajigumi 10y agoI'll agree that Postel's Law should not be interpreted as "when something doesn't fit, force it". The most effective examples tend to have a duality: areas where permissiveness is allowed and areas where it's constrained. (E.g. The CSS/JSON must be well-formed, but the properties can vary.) Getting underneath the patterns and anti-patterns of permissiveness in an informed way is a lot more useful IMO than the knee-jerk reaction of declaring all permissiveness harmful and running away. Especially in light of the web's incredible wins via this strategy.
- catnaroek 10y agoFrom a purely financial point of view, you may well be right: the technical and social benefits of clean, elegant, reliable, correct software probably don't justify sacrificing something as profitable as the permissiveness of the Web. But these are pretty damn twisted priorities. A little bit of social responsibility wouldn't hurt.
- jfaucett 10y agofrom googling and looking at the source this looks like it has nothing to do with c, its more of a logic error where a handler delegates control to another process, curl for example, based on image type. I could be wrong but thats what it looks like to me.
- amluto 10y ago> So, we get it. Complicated file and network formats, handled in C code leads to these types of security issues. Actually, the magic byte thing makes me think this is a content sniffing issue, and the RCE might be due to a "feature". Rust won't help or, at best, would make it more awkward to exploit. A capability-based (i.e. memory-safe, no accessible globals that can induce side effects) system would mitigate this, though. If I call out to ImageMagick and say "rescale this image", ImageMagick should not be able to initiate network requests in response.
- gamache 10y ago> A capability-based (i.e. memory-safe, no accessible globals that can induce side effects) system would mitigate this, though. Check out OpenBSD's pledge, it's addressing precisely this problem. http://man.openbsd.org/OpenBSD-current/man2/pledge.2 http://man.openbsd.org/OpenBSD-current/man2/pledge.2
- lmm 10y agoThat's a whack-a-mole approach that doesn't even try to define a real security boundary. It will catch the most common errors, sure, but it's not a long-term solution.
- amluto 10y ago> Check out OpenBSD's pledge, it's addressing precisely this problem. Au contraire. You can fork(), restrict yourself to a couple of pipes in a subprocess, pledge(), do the calculation in the subprocess, and exit the subprocess. It'll work, and it'll be slow. But this isn't at all specific to pledge() -- seccomp can do exactly the same thing, arguably more simply. Performance will suck either way. <rant>I have yet to see a credible argument for how pledge() is better than seccomp. You could almost implement pledge() as a library function that uses seccomp, and the I consider the one part of pledge (execve behavior) that this won't get right to be a misfeature in pledge<./rant> The performance of that scheme will be abysmal for anything that does very fine-grained sandboxing. What you want is language support. E (erights.org) does this as a matter of course. Rust and similar languages could if they were to allow subsetting of globally accessible objects. Java and .NET tried to do this and fell utterly flat. I've considered trying to get a nice Linux feature to do this kind of sandboxing with kernel help (call a function that can only write to a certain memory aperture without the overhead of forking every time), and maybe I'll get this working some day.
- m0th87 10y agoI've been writing Rust too, but I'm not why the argument that it'll reduce the attack surface is glib. It can't prevent all security holes, though, because nothing can.
- marssaxman 10y agoThe solution I've been experimenting with is to run this sort of code in an isolated, network-stack-free unikernel environment. Imagine that you've built the ImageMagick library into a unikernel server using a virtio serial port for I/O. When you need to process an image, you boot a VM with this imagemagick kernel, then pipe the image data through its virtual serial port. Data goes in, data comes out... And if the attacker manages remote code execution inside the VM, who cares? There's nothing in there. There's no network stack, there's no access to storage, there's no access to other processes; all you give this VM is the RAM and serial port the unikernel needs to do its job.
- stormbrew 10y agoOr... you could just run it as nobody and maybe unshare its network and chroot it and not add the surface area of some virtio driver to your stack? Like, there's no magic to a unikernel. It's just a process in a jail, unless you're legitimately running it directly on the cpu. Adding more layers of abstraction does not inherently add security.
- 3pt14159 10y agoI think the difference is that that seems like something I would screw up. I know how to make a $5 DigitalOcean instance that only has ImageMagick that I can pipe photos to and from. I don't trust myself to unshare the network from some running process without leaving other holes. There are all these gotchas when you have stuff running in the same OS and it just takes one little mistake and your adversary has root.
- sedachv 10y agotl;dr Unix security model is too hard to use. Let's put another layer of crap around it!
- mplewis 10y agoDon't be reductive – OP made a very good point, and you're not arguing it head-on. > There are all these gotchas when you have stuff running in the same OS and it just takes one little mistake and your adversary has root.
- pcwalton 10y ago> 1. Simpler formats for file representation and data interchange. When someone tries to add an extra bitfield option, say no. When they keep trying, get a wooden stick with "no" written on it. Part of the disease of modern computing is bloated specs. How is creating new image formats and getting the entire Web to adopt them easier than making more secure image decoders? It's especially irrelevant to this series of vulnerabilities, since they work by getting ImageMagick to parse less popular image formats. Inventing new ones won't do anything to mitigate these flaws. > if it was going to, it already would have (and this is from someone already writing Rust code). I don't understand what this is trying to imply.
- askyourmother 10y agoThe 'Magick' in this case is less welcome when your system is pwned. Maybe less magic formats and tools will have, I don't know, less vectors for compromise. We had better options before and after C, yet here we are. Not to piss on Rust's parade, but it may prove not to be the white knight of code hoped for. And I like Rust - I am probably just less emotionally clouded in my view point.
- pcwalton 10y agoI don't see anything in this comment that is responsive to anything I wrote.
- askyourmother 10y agoIt is a shame, a second read may have helped.
- matthewmacleod 10y agoI agree to the extent that "Rust will save us" is a glib answer, but dismissing it completely is equally silly – safe-by-default is an excellent tool to help prevent many of the common sort of vulnerabilities we see in C code. I don't really agree with the rest. "Simple file formats" is a theoretically nice idea which is impractical – after all, features are added to file formats for a reason. "Restrictive not permissive" is, as others have pointed out, a divergence from the generally useful Postel's law. Writing a library which cannot handle common problems in file formats – of which there are a huge number, due to sloppy implementation – is a good way to ensure you have developed a library which will be used by few.
- xrange 10y ago>I agree to the extent that "Rust will save us" is a glib answer, but dismissing it completely is equally silly – safe-by-default is an excellent tool to help prevent many of the common sort of vulnerabilities we see in C code. There have been all sorts of safe languages that are appropriate for image processing and other types of programs, but people apparently like programming in C more than they like secure software. It is hard to see how something like Common-Lisp/Ocaml/Haskell/Java/Eiffel/C#/Ada wouldn't be more than up to the task, with only a slight speed penalty. It seems more like a social issue than a technical one. Maybe Rust will finally be able to break through, but I wouldn't hold your breath.
- 0x0 10y agoIs it C's fault here though? Is it not just improper shell escaping? You could do that incorrectly in any language. If you're not quoting | and ` and stuff correctly when you call system() you're doomed no matter the language.
- JdeBP 10y agoqmail has already been pointed to elsewhere in this discussion. One of the qmail security principles, which are fast approaching 20 years old, is the maxim: Don't parse. This is directly applicable here. * http://cr.yp.to/qmail/guarantee.html http://cr.yp.to/qmail/guarantee.html * http://cr.yp.to/qmail/qmailsec-20071101.pdf http://cr.yp.to/qmail/qmailsec-20071101.pdf The GNKSOA-MUA comes to mind, too. The other vulnerabilities (there being five -- see the mailing list message) are related to the idea of allowing input data files to contain embedded actions and commands to be executed by the data processing tool. In the world of mail there were many variations on this theme. Clifton T. Sharp Jr's Usenet signature was "Here, Outlook Express, run this program." "Okay, stranger.". * http://homepage.ntlworld.com./jonathan.deboynepollard/Proposals/gnksoa-mua.html#NoAutoFetchExternalContent http://homepage.ntlworld.com./jonathan.deboynepollard/Propos...
- pjc50 10y agoIf you don't like bitfields, you'd better stay away from H264/5.
- wbond 10y agoHopefully it will convince developers to not trust the client and actually confirm the user uploaded a .jpg, .png or .gif. But I guess that isn’t nearly as useful for us when we want a reason why we need to rewrite everything. :)
- jrochkind1 10y agoYou know what a lot of people do to confirm the user actually uploaded a jpg, png, or gif? Use ImageMagick. http://www.imagemagick.org/script/identify.php http://www.imagemagick.org/script/identify.php
- chubot 10y agoI think before #1, #2, or Rust, we need a better "libsandbox". You don't even need containers to do this -- DJB showed how to do this with Unix over a decade ago [1]. See section 5.2: isolating single source transformations. I think the reason people don't do this is because it's extremely platform-specific. Most of this C code runs on Windows too (ImageMagick, ffmpeg, etc.) And it's complicated. But if there were a nice library to do all this stuff, I think people would use it. If you're just shelling out to command line tools like ImageMagick, you don't even have to change any C code... you can just run it under a wrapper (sorta like systemd-nspawn). But I think most people are not using ImageMagick that way -- they are using a Python/Ruby binding, etc. But it can still be done -- it just takes a little effort. MUCH less effort than changing any of that old crufty code, much less rewriting it in Rust! [1] Some thoughts on security after 10 years of qmail -- https://scholar.google.com/scholar?cluster=9814570315440570792&hl=en&as_sdt=0,5&sciodt=0,5 https://scholar.google.com/scholar?cluster=98145703154405707...
- dozzie 10y agoDJB maybe is a prominent cryptographer, but his code and security practices, especially around Qmail, are simply atrocious. I wouldn't quote him for anything that touches real C code.
- regularfry 10y agoUncompromising and inconvenient to work with, maybe. Why atrocious?
- sedachv 10y ago> 1. Simpler formats for file representation and data interchange. When someone tries to add an extra bitfield option, say no. When they keep trying, get a wooden stick with "no" written on it. Part of the disease of modern computing is bloated specs. > 2. Restrictive not permissive code bases. Exit and bail out early. Tell the user "file corrupted". Push back. The best talk on computer security I have seen is Meredith Patterson's Science of Insecurity at 28c3: https://www.youtube.com/watch?v=3kEfedtQVOY https://www.youtube.com/watch?v=3kEfedtQVOY It is really interesting that the techniques needed to achieve these security goals (theory of grammars) is one of the oldest and best explored areas of computer science.
- jlg23 10y ago1. is not applicable even in mid-term, unless you want to break the internet 2. is breaking the internet I'm not sure I'm ready to accept the collateral damage of your solutions. How about looking at "C" (or any other language with direct memory access) as the culprit? (EDIT: Assuming it's a C-issue after all and not just some dumb input validation problem.)
- serge2k 10y agoThat's a pretty ridiculous answer considering the volume of C code and rust being a new language.
- ashitlerferad 10y agoShell metacharacter and option injection vulnerabilities exist in almost every language, not just C: http://bonedaddy.net/pabs3/log/2014/02/17/pid-preservation-society/ http://bonedaddy.net/pabs3/log/2014/02/17/pid-preservation-s... http://www.defensecode.com/public/DefenseCode_Unix_WildCards_Gone_Wild.txt http://www.defensecode.com/public/DefenseCode_Unix_WildCards...