Friday November 12, 2021; 8:52 PM EST
- (13 min read)#
- I can't stop thinking about just how incredibly stupid this idea really is. When I get done describing how stupid it is, you're going to say, why yes, Gary, that is the stupidest fucking idea I have ever heard, and, in fact, you have succeeded in making it even more stupid than I already thought it was, and that was pretty fucking stupid.#
- I'm referring, of course, to this little gem:#
- This code depends on the standard environment to sanitize data.#
- #
- I guess the reason I can't stop thinking about it, is that maybe it's just stupid enough to work. #
- #
- To review, I'm describing a hypothetical place in the cloud where I can put little snippets of Drumkit code, and call them when I need them. This implies a few things, most importantly, a virtual machine in the cloud that is executing my Drumkit code, and some sort of supervisor/traffic router that knows to how to start up the virtual machine, or wake it from sleep, route requests to it, and send the responses on toward their final destination. #
- Here are the pieces we are talking about:#
- The client #
- The client is going to call my Drumkit code snippet. This could be Drummer, another snippet, a browser, etc.#
- The traffic router#
- The client sends the request to the router, which is a service that runs in the cloud, and is actually the public face of the universe. The router inspects the request and identifies which universe should handle the request.#
- The VM #
- This is the actual universe in which my Drumkit snippet runs. It's a virtual machine. Normally, in this type of scenario, this is where any input validation and cleanup occurs. #
- The standard enviroment#
- This is a separate process, in a separate VM, which runs the input validation and cleanup code.#
- #
- I should be clear about the exact problem I am trying to solve: I want that snippet to run literally forever, until the end of time. I am not kidding about this. When I talk about how you should go see what Vernor Vinge says about how software ages, this is what I mean.#
- #
- Here's how it works now.#
- My snippet is running in the VM#
- Input is handed to the VM#
- As part of the handoff to my snippet, there is actually a long series of calls before it gets to my code. This is all in library code. It's doing things like unstitching arguments, repackaging things, and, critically, sanitizing input.#
- All that code is executing in my process, in my VM, because that's how it works. The call can never get to my code unless it can be processed by all that other code first.#
- If a security flaw is found in that library code, it needs to be fixed. The dream is, the library code gets fixed, the VM environment gets updated, and now all that code that processes my requests is up to date, and runs properly, in my VM.#
- Sometimes, fixing these things means that the maintainers need to break things. That library cannot possibly be fixed the way it works now, we need to change the way it works. Because that code calls my code, and my code calls that code, my code needs to be updated, too.#
- If my code doesn't get updated, we have a problem. There is a security flaw, which means it isn't safe. So we can't launch it. If we do try to launch it, it will crash, because it is no longer compatible with the new, safe environment.#
- My code wasn't at fault, my snippet was fine. The security flaw is somewhere else entirely, but suddenly, anything that depended on that snippet stops dead in its tracks and starts throwing exceptions.#
- Or, maybe, my code was at fault. It can't handle the latest version of UTF encoding, or something. Either way, my snippet can't run because it can't be trusted to properly handle the input.#
- #
- So instead, I'm proposing that the input and validation code all runs in a completely separate process, that can get updated whenever, because all it has to do is one thing: make the input safe. For lack of a better name, I'm calling that process the standard environment.#
- #
- Obvious objections why this is stupid#
- If you are writing code, you need to be working with the latest standards and libraries, so you should keep up.#
- This is less efficient, because now we have a whole extra process in the way.#
- #
- The first objection is valid, but only for code that is actively being maintained by someone who can literally drop everything and fix it when the cloud environment gets updated. That's basically nobody who isn't a team of developers for any non-trivial project. And when I'm dead, who's going to maintain my snippet? That's right, nobody. #
- Because even if that snippet is so incredibly brilliant and useful that a whole team of people have stepped up and are keeping it up to date, this is how open source works, guess what kind of people do that? People who like to make things with software. I am one of these people. And we may like tinkering and keeping things running, but what we really like is making things better, and sometimes the best way to make something better is to make a whole new thing. So that little snippet will not be running forever, it will stop spinning eventually, when enough people stop caring. #
- The second objection is valid, and is the really, really stupid part. Because what I am proposing is so monstrously stupid and wasteful, I am going to once again, apparently, take someone else's brilliant obsessions, and turn them into an electric toothbrush you can also shave with. #
- And sometimes, the ideas I am rummaging through are so brilliant that so many brilliant people have spent so much time thinking about them that other brilliant people have written books with hundreds and hundreds and hundreds of pages just trying to summarize them and tie them all together, and quite often, this results in a cannot-put-down must-read. #
- #
- So, spoiler—#
- #
- Go read Gödel, Escher, Bach, by Douglas Hofstadter, and then come back here.#
- #
- If you have any interest at all in the recursive nature of reality, the way ideas work, the way music can reach deep inside you in ways that are literally mathematical, and how that could result in a record, made by a turtle, which, when you play it, causes your record player to explode in a shower of brilliant engineering, or how to talk to a colony of ants, or so, so many other things, it is worth the effort. #
- I'm not kidding, it's a lot of pages, but if you did in fact lose your mind and listen to me and do what I suggest, and go read that book, and then come back here, you would, like that guy in Hellraiser 2, when he got back from his little journey, say to yourself, with wonder, "To think I even hesitated." No joke.#
- #
- Right, so I am deeply concerned with the idea of attacks from parallel universes. (Well, in fiction, and metaphor, I am, I'm not literally of unsound mind, work with me here, people.) #
- Recall that my snippet is there, spinning away in its own little universe. And its only real problem is that it can't handle certain things, it literally can't adjust, something comes along it wasn't prepared for, and kaboom, there it is, useless, and so it stops spinning.#
- But why is that? I've described some of the things that keeps software from spinning: inertia, change, interest, progress. I think it's literally impossible to expect that snippet to be maintained in the long run. The long, long run. This is just the way humans are.#
- What if I take the humans out of the equation, though? Are there any other reasons why I can't keep that snippet running forever, useful, somewhere, doing what it was supposed to do? Well, it turns out, yes, there are. And you can prove it with math. That's why we needed the humans to do the maintaining in the first place.#
- Here's the gist: If you try to make a system that can handle everything, that system will not be able to handle things which are not described fully by the system. Which, it turns out, is the system itself.#
- BOOM.#
- If you have never encountered this idea before, and something just jolted into place for you, that is what we call an epiphany.#
- #
- Let's try again, using one of Hofstadter's examples. #
- Here's how a record player works: On a record, there are tiny grooves. The grooves wiggle from side to side, and the wiggles are exactly analogous to the vibrations of sound waves. As the record spins, we drag a very small, delicately suspended diamond through the grooves. The wiggles in the grooves make the diamond wiggle. #
- We have sensors, tiny electrical generators, usually, though there are other ways. We use those sensors to turn that physical vibration into electricity. The electricity wiggles, it varies the same way the diamond is wiggling, which is the same way the grooves are wiggling. #
- We use that electricity to drive motors, which is what speakers are, they're small electric motors, like in your Tesla. The speaker surface, usually a cone, but sometimes flat, wiggles due to the motor. That pushes the air around, and so we get music.#
- When you strike a bell, it rings. If you strike it again, it rings with the same tone. (If you want to make melodic music with bells, you need a lot of bells.) This is the bell's natural resonance.#
- If you strike your record player, it will ring like a bell. That is your record player's natural resonance.#
- If you make a record that includes vibrations that are just like that resonance, that record player will do something it was not intended to do: It will make those vibrations stronger than the ones you want, because the record player will start to resonate. Which is to say, it will vibrate. And if you vibrate something enough, it will start to shake. And if you shake it enough, well, pieces may start flying off.#
- BOOM.#
- We have a record, which, when played, can cause your record player to explode. It won't work on my record player, because mine is different, and resonates differently. So I am totally, one hundred percent, safe and secure from this attack. I can play that record all day long. (In fact, if you brought your record player over here, and I played that record, long and loud enough, I could probably explode your player without even touching it. But that's not actually the parallel universe attack I'm talking about here.)#
- #
- My point is, my record player is safe from the record that broke yours. But you can easily create one that will break mine. This is a problem, but it's OK, I can work around this. I can add something to my record player that changes it, now it is no longer vulnerable to that record. #
- But now, it is vulnerable again, to a different attack, because it still has the same problems it had before. I can't get around it, you will always be able to make a record that will cause my record player to explode in a shower of recursive good intentions.#
- You can prove this with math and logic, and lots of brilliant people have built on each others' work through the years to figure this out. It is literally impossible to work your way out of this problem.#
- So my goal, of keeping that snippet running forever, is impossible. You can work it through on the whiteboard, if you have one big enough, to go through every single point of failure that will keep that snippet going, and plan around it, and every single flaw you identify, every single mitigation you come up with, given enough time, someone can find an attack that will render your preparations useless.#
- #
- I'm tired of giving up on impossibly hard problems. Just because I can't solve it doesn't mean I can't make things better, so here goes.#
- Instead of patching up my snippet, keeping it up to date, the standard environment is a separate process, a wrapper if you will, that intervenes, and filters, and keeps safe. You can't do this forever, because each snippet is unique. You will need to make a lot of variants on the standard environment. But, each snippet runs in a particular universe with a particular set of assumptions and flaws and resonant frequencies, and actually shares those assumptions and flaws and resonant frequencies with a lot of other universes. So, much of the filter that helps my universe, could help yours, as well.#
- This is so not the same as keeping the libraries up to date in your VM, I cannot over-emphasize it. This is not maintaining the VM. In an AWS Lambda scenario, this is not keeping your node.js library up to date. This is not even keeping the virtual machine that runs the VM that runs the node.js that runs your code, up to date. This is a separate, new layer, that goes in between those things. It's an entire, actual, separate process that runs independently. That's how stupid this idea is.#
- #
- But wait, it gets stupider! I am assigning a lot to this here little "standard environment", in fact, I'm giving it a pretty impossible job. Some attacks are sneaky. Many, many kinds of attacks involve tricking your machine into thinking one kind of thing, is actually another. One of the ways you do that, is you disguise what you're trying to do. You fool the guards. You have an escape, you can get away with this and they'll never know. See above for why. You can render your attack literally invisible.#
- How this works is, you obfuscate. You scramble. You try to mix up the layers. If warning signs and critical instructions are in red paint, you will use red paint. If you have something that is, obviously, at first glance, very, very bad, you break it up into innocent pieces, scramble those, sneak them in, and assemble them where no one's looking. For example, if SCRIPT says "start executing this very bad code", you break it up so it says SCR in one place, and IPT someplace else, and later you stitch them together.#
- How do you detect these kinds of attacks? Well, you have to do what the attack wants, actually. You can take a look at the plan, the raw material of the attack, and look for patterns you've seen before. You can look for SCR and IPT, of course, but that doesn't help if someone uses SC and RIPT. You can use heuristics, little handy guidelines that say things like, "if someone is assembling a string, and it is S-C-R-I-P-T letters long, that is suspicious." #
- But in the end, you can't figure it out just by looking. This is why Alan Turing is famous, that's the part he added. At some point, to find out what's going to happen, you are just going to have to fire up that machine and see what happens.#
- #
- That's how insane the standard environment is.#
- I am literally saying that it might be worth it to fire up an entire virtual machine and just see what happens, to see if a string is valid, before handing it off to my little snippet of Drumkit, spinning there in the cloud, all by itself, long after I'm gone.#
- This is in addition to the standard environment VM, by the way, that I've already inserted here. The standard environment forks a whole extra universe (or two, or...), just to see what happens.#
- #
- Anyway, this is one of the stupidest things I've ever come up with, but it got stuck in my head yesterday, so I just wanted to put it out there. #
- I mean, if we're willing to burn processor to mine fucking Bitcoin...#