Software design is all about separation of concerns. First, separation of concerns through layered abstraction is one of the most fundamental tenet in software engineering today. If JavaScript programmers, say, needed to know the minute implementation details of all the libraries, the browser, the operating system, and even the hardware, they would not get much work done. Second, we separate concerns even when it comes to vulnerabilities: we distinguish different classes of vulnerabilities, such as memory errors, hardware bugs, etc., and train specialized experts to solve these issues separately. Unfortunately, the concerns are not separated at all! First, those nice abstractions layers are leaky: the internals of one layer frequently spill over other layers, with important implications for the security. As a result, our programmers need to be aware of what is going behind those elegant interfaces. Second, attackers don't care of such class separation of vulnerabilities because they will misuse multiple bugs to compromise your system. Different exploitation techniques can be combined such that the strength of the combination is greater than the sum of their parts. In this presentation, I will discuss 100,000 years of history, including how we develop software and mitigate threats. I will explain why the emphasis of separation of concerns is both necessary and dangerous. Finally, I will illustrate other depressing messages with uplifting stick figures and a fun case study that combines Spectre with memory errors.