The AppSec Reanimated series has begun! My goal for this series is to explore positive ways to make security a natural part of the SDLC. We won’t inspire behavioral change by jolting developers with electricity or injecting them with creepy green goo. But we might succeed by highlighting technologies and processes that help security become less of a supernatural event.
This first webinar starts a journey Out of the AppSec Abyss towards the cloudy realms of modern dev concepts. It introduces an underlying theme for this series: How the dimensions of time and space influence appsec.
Time is a key element of modern app development. It also serves as a great metric to track. How long does it take to perform a task well? How might you do the task faster? A task could be updating a system, releasing a patch, analyzing a log for security events, or collecting forensic data. Any of these could fall under the umbrella of continuous integration and continuous deployment (CI/CD).
Today’s development methodologies embrace continuous efforts. CI/CD processes have motivated fundamental changes to building and maintaining apps. They blur the distinction between writing code and managing systems, thus creating the role of DevOps. They emphasize ever-shrinking release cycles, thus necessitating robust testing to maintain confidence in (and stability with) such rapid changes.
DevOps has also been empowered by the way cloud environments have abstracted system management into APIs and scriptable interfaces. Being able to treat systems more like code components increases their predictability and consistency (well, at least it should…).
Treating systems like app components that spin up and spin down on demand also sets different expectations for their management. No longer should system uptime be treated as a badge of honor, but more as a measure of suspicion that the system has not received patches or updates. The uptime of the service is paramount, not the individual systems beneath it.
A benefit of running ephemeral systems like this is that it should be easier to patch and test a single reference image for new instances to clone rather than haphazardly patch every current instance (alas, reality does not always follow theory). Think of this as retire and replace as opposed to patch and preserve. The expected security of this approach is that the window during which systems are not patched should shrink. Or from a risk perspective, the window of attack against known vulnerabilities on these systems has shrunk. In other words, we’re trying to reduce risk rather than chase a more abstract “perfect security.”
There’s a catch. There’s always a catch. This retire and replace premise works well for stateless systems that underpin a service. Stateful systems (think data stores and key/value stores) have different uptime profiles and are more sensitive to nodes constantly going up and down if that impacts availability of data. This catch is a nod to the nuances of app ecosystems, not an argument against the retire and replace model.
CI/CD, DevOps, and cloud can improve security, but they aren’t magic security incantations. They’re more about shifting attack surfaces. Where DevOps removes a lot of separation of duties, it doesn’t remove the burden of separation of data — protecting production data from unauthorized access. The app ecosystem must still ensure attackers can’t trivially bypass hardened cloud networks by merely committing a few lines of code from a compromised dev system.
Think of this shifting of attack surface as the appsec dimension of space.
Even though CI/CD and cloud models encourage behaviors that benefit security, it’s important to see where they introduce new risk or merely rearrange the old.
The ease of spinning up systems may make maintaining patch levels easier, but it may also make scanning and monitoring those systems harder. You’ll always need a strategy for asset management and log collection (this is hardly an earth-shattering claim); it’s just going to have to adapt to the nature (and perhaps scale) of the deployments.
In many cases identity management for services shifts from the systems they run on (like their IP address) to the services themselves. Rather than just tightening IP/port combinations in a firewall, you also need to start thinking in terms of hardening syscalls so that compromised containers don’t infect their peers. The future is compartmented, service-level authorization, not the broad system-level authorization of the past.
Those who have been paying close attention will have noticed that I’ve been focusing mostly on systems, with coding having received the briefest mention. One premise of CI/CD is that apps should be faster to fix when vulns are discovered. But that assumes the vuln is due to an implementation flaw and not a design flaw. Subtle architecture changes or design modifications have far-reaching implications for a code base that can’t be addressed in a two-week sprint. Also, many modern app frameworks have horrendous dependency graphs. So, while your code may be secure and well-reviewed, the quality of the open source libraries and modules it depends on may be weak.
Couch this dimension of space in terms of attack surface management, where changes are potentially reducing network surface while expanding the application. Tackle some easy wins, measure along the way, reduce the time it takes to complete tasks.
It’s a continuous journey to emerge from the appsec abyss, but with planning, metrics, and perseverance you’ll find many discrete benefits along the way.
Read about the second webinar in this series at A Promethean Struggle — PCI’s Lessons for Passwords.