Reflections on a few security vulnerabilities; some recent, some less so.
Rails JSON/YAML bug (CVE-2013-0333). ShellShock (CVE-2014-6271). What do they have in common? A feature which nobody knew existed was plugged into the internet. Rails and bash were arguably working as designed. Unfortunately, parsing all the strings with all the parsers as a general operating principle turns out to have negative security implications. It sure is convenient for all zero people who know about the feature, but less so for the rest of us.
Best way to think of the Bash bug: Imagine one day a new required class of input validation was discovered. “In what?” “Exactly.” - dakami
Eerily, the same could be said about the recent discovery that a perl feature also resulted in a new class of vulnerability.
When features are added to a system, they become potential weaknesses that can be used to circumvent other security mechanisms. Every time a new feature is introduced, all existing software that tries to run in a restricted environment needs to be audited and reviewed for potential interactions. For example, file system access and arbitrary code execution are often considered separate privileges. The sftp server attempts to enforce this boundary. But when a feature is added to the filesystem that directly turns into code execution, it turns into an escape hatch. Keeping abreast of all the ways that new features will tunnel under the walls you’ve built is a Sisyphean task. As another example, combine the ftp program’s ability to pipe files to commands via filenames like |cmd with http redirect’s ability for the server to specify a filename, and you get arbitrary command execution. 1 + 1 = 3.
Winding back the clock to a time even before ye olde internet worme of 1988, there was sendmail wizard mode. There’s an arcane feature. The best part is the wizard exploit depended on another bug and feature combo, sendmail’s frozen config feature and the mistaken placement of the password pointer in the data area. Now there’s some double secret arcana for you. A bug in the quick load feature (which nobody knows about) opens up a bug in the wizard feature (which nobody knows about either).
Fast forward most of three decades, and have we learned not to do crazy tricks involving the C compiler and magic initialization of critical variables? CVE-2014-7284 (Linux kernel net random bug) says no. Security sensitive code should not require comments like “it needs some further explanation why this actually works” (or not) because it should not be dependent on such arcane features working correctly. Seeding a random number generator is one of those tasks where the less magic is involved, the better.
This isn’t even the first time I’ve heard about runtime code patching in the Linux kernel. The e1000e bricking bug has that honor. I’m going to check the box next to “we are not smart enough to use features like this correctly”. We do not need to develop software with a we can do this; therefore we must do this mentality.
Even just linking code can be difficult once you get enough libraries involved.
I’ll drop a link here to 17 Mistakes Microsoft Made in the Xbox Security System. It’s a fantastic read about the many minor decisions and ancient compat features that came back to haunt the Xbox and could be used to break its security.
On the lighter side of things, and not security related, there’s this ancient bug in head. The obvious (to me) way to do things is exactly like in the fix; open a new file for each file to be processed. But the code tried to be a little clever by swapping each new file into stdin and ended up with a bug in some cases.
Thank god we stopped writing software in the 90s. Pretty soon we'll have all the bugs out. - matthew_d_green
Web browsers have existed as a category for about twenty years. In that time, nobody has ever produced one that I’d call secure. We can barely build a browser that doesn’t leak memory like a sieve. Supposedly solved problems like the same origin policy have an unfortunate tendency to revisit us from beyond the grave. There’s enough work to be done just treading water and staying ahead of new discovered vulnerabilities in existing features, but developers are constantly chasing new features and finding new types of input to parse. Or they are finding new ways to expose sensitive memory to attackers. And again.
Right now there is what I can only describe as a conspiracy to connect something called gstreamer-plugins-bad to the internet. I do not want something called gstreamer-plugins-bad to be connected to the internet because that doesn’t sound like a good idea, but apparently somebody decided to call it a feature, and just like that it had to happen. It’s as if somebody looked at the UML diagram for my browser and realized that the boxes labeled malicious input and gstreamer-plugins-bad weren’t yet connected, and in their utopian vision of the internet, all of the boxes must be connected. gstreaer-plugins-bad strikes again, against the linux desktop.
And not just browsers. Even less is playing this game. Personally, if I’m trying to view a PDF with less it’s because I’m so wary of the file’s origin I don’t trust pdftotext to parse it correctly, so I think I’d prefer not to have less run essentially arbitrary commands for me.
Or maybe the problem is that we’re not using enough UML (crazy, right?) and we haven’t got a clue what’s connected to what. It’s not just irreducible complexity; it’s unknown complexity. The set of programs, libraries, modules, and plugins my browser will force feed arbitrary network data into is an unknowable set. Somebody will surely argue that there is a way to configure things such that this doesn’t happen, but that’s bullshit. Browsers go to great lengths push all of the data into all of the parsers. A modern web browser is the software equivalent of Gabriel’s Horn. Finite volume, but infinite attack surface.
Additionally, when we build applications like Mac iMessage out of browsers, sometimes too many browser features remain.
We’ve also started turning libraries like ImageMagick into unwitting browsers. lcamtuf’s thoughts.
Some comments regarding rowhammer exploits. First, rowhammer itself is clearly a hardware problem. Chasing ever faster performance, somebody decided to relax the tolerances, opening up multiple avenues of attack. Some software is more vulnerable to attack than others, however. As noted, the Google Chrome NaCL sandbox is easily attacked. There’s also the more limited rowhammer.js. Both vulnerabilities result from allowing hostile users to run nearly arbitrary code on our trusted system. Generally speaking, even when sandboxes are secure, they provide a convenient platform from which to launch attacks against components outside. The more powerful the sandbox, the more powerful the attacks. The Flip Feng Shui attack is interesting because it attacks yet another feature, memory deduplication. None of these software programs are to blame for rowhammer, but every new feature can be leveraged to exploit “out of scope” vulnerabilities.