By Adam Cecchetti
Previously we’ve discussed the scope of the security problem and took an abstract look at how most of the industries bugs can be classified into three categories. The main goal of this thought exercise is to continue the type of thinking that addresses two fundamental questions:
(1) How do we maximize the timeline between a system’s release and the user value being exploited?
(2) How do we reset the attacker’s starting point in that timeline as often as possible?
Can we get there? Yes but only if we continue to see time as the most valuable resource for users, attackers, and defenders.
Looking at the problem on the axis of time reveals a few notable things.
Over an arbitrary period, bugs are found, targets move, opportunity ends, patches are applied, systems are shut down, legacy lifetimes are extended, interests shift, and more important targets emerge.
The odd combination of OCD and ADD that is prevalent in the security community can work both for and against you. When a dedicated attacker locks on to a produced target and obsessively, compulsively hunts, it is only a matter of time before they uncover bugs. When real motivation and skill is behind that dedicated hunt, the timeline shrinks rapidly. As the Cyber Grand Challenge recently demonstrated, it is going to eventually be a matter of milliseconds - not hours or days - before bugs are discovered.
No matter which side of the equation you are on - fixing bugs or finding bugs - time is always the greatest asset. And time is ever ticking: on a long enough periodic, time is always undefeated. Eventually, the sun implodes and the silliness of programming with side effects in a Turing machine is put fully into context.
Until then, however, the relative security of any system can be imagined as a snapshot of its components in time. No matter how mature your development process eventually the clock hits the point where shipping is the only feature that matters. When the ship pressure is high enough, a snapshot of the system state - bugs and all - is taken and the snapshot is released to the world.
So how do we level the temporal playing field? Let's take a look at the life of a bug. Whenever software or hardware is released, two actions immediately begin to happen. (1) users begin to use the system, which creates a target value for the system, and (2) attackers have the ability to attempt to exploit the system. This assumes that the release did not ship with any known vulnerabilities, and that the attackers have to put some amount of time into finding an issue. On those assumptions, the following is the ideal timeline a defender can hope for today.
Sadly, many systems ship with a less-than-ideal timeline.
Where can we force attackers to spend more time?
At nearly every step of this timeline.
Classic methods of extending or shrinking the timeline from a defenders’ viewpoint have included training, security [or code] audit, fuzzing, threat modeling, and patching. Each of these actions resets, expands, or contracts a part of the timeline.
Training helps remove bugs from occurring in a new snapshot and potentially removes them from a current one.
Audits and threat models remove bugs from a snapshot before or after its release.
One of the reasons Deja vu Security has emphasized fuzzing so much over the years is that it cuts two directions into the timeline. Fuzzing, generates test cases automatically and monitors the target for a negative results. By automatically testing the software with fuzzing it extends the amount of time it takes an attacker to find a useful bug while at the same time taking a useful discovery tool away from them.
Once a snapshot that is trivial to exploit is released in the wild it is difficult to get convergence back to a dependable point in time by updating all of the places that snapshot was used. As patches are applied, timelines for the product begin to fracture. Some instances stay frozen in an exploitable state, others become shifting targets of both user value and time required to exploit.
In the best case scenario using all of these methods the clock is reset for the attacker as often as possible and the time between release and value gets exploited is maximized. In a perfect defensive scenario an equal amount of new effort must be performed to get back to an exploitable state.
By using all of these methods and focusing on technologies and methods that give a time to a defender and take time from the attacker. The real way to do that is to make users' lives better where better also happens to be defined as secure; and secure is defined as taking as much time away from and causing as much frustration to an attacker as the design allows. Build a better world the user wants to migrate to. Secure the user. Frustrate the attacker. Build, secure, repeat. Build securely, repeat. Build.
When are we going to fix this mess?
When we build a better one.