DevSecOps A Leaders Guide To Producing Secure Software Witho
DevSecOps A Leaders Guide To Producing Secure Software Witho
All rights reserved. No part of this publication may be reproduced, stored in or introduced into a
retrieval system, or transmitted, in any form, or by any means (electronic, mechanical, photocopying,
recording or otherwise) without the prior written permission of the publisher.
The right of Glenn Wilson to be identified as the author of this work has been asserted by him in
accordance with the Copyright, Designs and Patents Act 1988.
This book is sold subject to the condition that it shall not, by way of trade or otherwise, be lent, resold,
hired out, or otherwise circulated without the publisher’s prior consent in any form of binding or cover
other than that in which it is published and without a similar condition including this condition being
imposed on the subsequent purchaser.
Foreword
Introduction
1 DevOps Explained
The three ways
The five ideals
Conclusion
2 Security Explained
Types of attacks
Adversaries and their weapons
Conclusion
3 DevSecOps
Security implied in DevOps
Points of contention between DevOps and security teams
A layered approach to effective DevSecOps
Three layers overview
Conclusion
4 Layer 1: Security Education
Importance of security education
Security champions
Gamified learning
Instructor-led training
Self-paced learning
Pair programming and peer reviews
Informal security knowledge sharing
Experimentation
Certification
Avoiding entropy
Conclusion
8 Summary
References
Further Reading
Acknowledgements
The Author
This book is dedicated to Caz, Abs and Emily
Foreword
Michael Man
DevSecOps London Gathering
September 2020
Introduction
The lack of security engineers with experience in Agile and DevOps within
an organisation means that they are not being integrated into the DevOps
teams. Furthermore, DevOps teams fall short in the level of knowledge
required to integrate security into their ways of working. The result: security
teams are treated like external resources; and DevOps and Agile teams are
forced to reach out to security teams to configure firewalls, manage
certificates and keys, and put in place access controls to support the running
of the products. Compounding matters, the delivery team is still likely to
hand the product over to a SOC team for ongoing support, creating even
more distance between security and DevOps, which ultimately creates a slow
feedback loop. The constraints forced upon DevOps teams by security
departments provide the catalyst for managers to look for quick wins, often at
the expense of security.
A potential solution is to integrate security engineers into the DevOps
teams, bolstering the knowledge and skills within the team to address this
challenge. Unfortunately, that solution does not scale. Typically, the ratio of
security engineers to software engineers is very small; estimates range from
one security engineer per 100 developers to one per 400. Overworked
security engineers struggle to meet the ever-increasing demands of the
software delivery teams who are delivering products and product features at
an accelerating pace. Therefore, we cannot simply add a security engineer to
a DevOps team and call it ‘DevSecOps’. A different approach is required –
one that is scalable and effective.
Some may argue that if DevOps is done correctly, security is implicitly
applied. There are two problems with this concept. Firstly, DevOps has
different meanings to different people. Some engineers focus on the
automation of operations to define DevOps, while others focus on cloud
services to define DevOps. Secondly, security is more complex than just
doing DevOps right. There are many factors influencing security best
practices which need to be explicitly defined. The rest of this book proposes a
solution to this problem: I introduce a three-layered approach to embed a
culture of security and security practices within the organisation, putting
security at the forefront of DevOps to create DevSecOps.
I define the three layers of DevSecOps that help decision makers integrate
security into DevOps ways of working. DevSecOps increases the safety of
the products your organisation develops while continuing to deliver new
products and features that give your company a competitive edge.
ONE
DevOps Explained
‘DevOps’ – the word – is simply the merging of the first letters of two
distinct functions within IT: the Developers, who are responsible for writing
software, and the operations staff, who are responsible for maintaining the
infrastructure on which the software is developed and deployed. Of course,
‘DevOps’ – the function – is far more complex than a merging of two roles
into a single team. To understand what DevOps is, you need to delve into its
history. Traditional software development is based on the waterfall
methodology, framed within a project that starts with ideation and ends with
the delivery of a working application. There are many problems with this
delivery approach, the main one being the lack of flexibility. Often, the
requirements change over the course of the project, leading to increased
scope, missed milestones and higher costs. To keep projects on track, it is not
uncommon to see a lack of quality in the final project deliverable. The
constraints associated with scope, time and cost, and their effect on quality,
are represented below.
Constraint triangle: the effect of increased scope and reduced cost and time on quality
Three ways of DevOps: left-to-right process flow, right-to-left feedback and continuous
improvement
The five ideals
Following the release of The DevOps Handbook, Gene Kim’s The Unicorn
Project extends the principles of DevOps into five ideals that collectively
define the core values of DevOps. The first of these ideals is locality and
simplicity. In order for a team to independently build, test and deploy value to
customers, it needs to avoid having dependencies on a large number of other
teams, people and processes. Each DevOps team can make its own decisions
without needing a raft of approvals from others, it promotes the decoupling of
components to simplify development and testing, and it recommends making
data available in real time to those who need it to complete their tasks
efficiently.
The second ideal states that teams must have focus, flow and joy, meaning
they must be free from constraints that hinder their ability to complete their
tasks. Individuals who have to work on multiple activities at the same time or
have multiple disruptions while working on an activity are less likely to work
to a high standard. If teams are able to focus on individual actions without
interruptions, they gain a sense of joy from being able to complete their work.
This helps the team deliver value to customers.
Improvement of daily work is the third ideal; it focuses on the reduction of
technical debt, including security weaknesses. Technical debt, if not
addressed, will grow to such an extent that most or all daily work will need to
work around it to deliver features, fix defects and mitigate risks. Therefore, a
significant proportion of the team’s daily work must involve investing in
developer productivity and reducing technical debt. Within The DevOps
Handbook, Kim identifies four types of work: business related (such as
creating new features), IT, infrastructure improvement and unplanned work.
Unplanned work becomes a distraction from delivering value and is
symptomatic of large amounts of technical debt.
DevOps teams should not be fearful of being open and honest, which is the
essence of the fourth ideal, psychological safety. Rather than evolving a
‘blame, name, shame’ culture, individuals must be able to speak up without
fear of repercussions. It is important to reinforce a culture of openness within
a DevOps team so that if a problem is identified, it is exposed and fixed.
The final ideal is customer focus. DevOps teams have two types of
customers: external (the paying customer who benefits from the features that
are delivered to them) and internal (individuals or teams who receive outputs
from those immediately preceding them in the value stream). By focusing on
the immediate consumer of your output, there is greater opportunity for
instant feedback, leading to greater customer experiences.
Conclusion
DevOps was born from the need to accelerate product development to gain an
advantage over competitors. I have seen the word ‘DevOps’ used arbitrarily
to describe Agile methodologies used during development and justified by
the use of certain processes, such as CI, automated testing and
containerisation. However, I have also witnessed scenarios in which DevOps
is framed within a project, teams stick rigidly to predefined processes, and
individuals within DevOps teams act as heroes to keep the project on track.
In this book, I endeavour to remain faithful to the true meaning of DevOps as
outlined in this chapter, while ensuring that the principles I introduce in the
rest of the book can be applied to less mature DevOps practices as well as
more mature DevOps organisations.
TWO
Security Explained
Hardly a week goes by without some form of security incident making news
headlines, from large financial institutions announcing a data leak involving
thousands, if not millions, of stolen customer credit card numbers, to
government offices unable to serve their citizens due to an ongoing
ransomware attack. Unfortunately, these happen far too frequently and affect
many people, including your customers and employees as well as specific
groups with the general population. In most cases, the attackers were able to
exploit weaknesses in the organisation’s public-facing network due to
vulnerabilities in the underlying software or configuration issues within the
environment on which the application is hosted.
Implementing security hygiene throughout your organisation has become
more critical than ever and security is a topic that is as broad as it is deep.
There are many ways to exploit an organisation through myriad weaknesses:
theft of data stored on laptops, removable media or even paper documents left
in poorly secured locations or in public places; passwords exposed through
social engineering or phishing emails; or customer data stolen from poorly
secured data stores or via weaknesses in web-based applications. Security
keeps your valuable assets safe and keeps intruders with criminal intentions
away from your critical systems. In software engineering, keeping your
products and services secure has become increasingly complicated as more
devices connect to the internet and users have instant access to your online
offerings from anywhere in the world. This opens up greater opportunities for
attackers to exploit more devices and enables more users to steal valuable
information. In this chapter, I explain the types of attacks that may affect
your organisation, the types of adversaries that may attack your organisation
and why security is important in software engineering.
Types of attacks
Attacks come in different guises, including phishing attacks normally used to
obtain user credentials, an advanced persistent threat (APT) to harvest
information from a system over a period of time, or a denial of service (DoS)
attack. There are many attack scenarios, each with a specific goal. You may
not always be the intended target: some organisations suffer from collateral
damage as a result of a partner or supplier coming under attack. However,
many attacks are targeted. In these cases, a determined attacker will spend
many days, weeks or months finding a way to hack a specific organisation. In
other scenarios, the attackers scatter their attacks across the internet to
compromise as many machines as possible. For example, viruses are able to
infect a system, replicate and spread to other systems. Their motives for
creating a ‘botnet’ (a network of compromised systems) are usually to use the
accumulative computing resources to harvest Bitcoins, send large quantities
of unsolicited emails or enable a distributed denial of service (DDoS) attack.
The fight against those wishing to do harm through hacking is drawn across
multiple constantly changing battle lines. Engineering teams need to be
armed with the tools and skills to maintain the security of their products and
services at all times. There are three information security principles which
should form the foundation of your organisation’s security policy. These are
confidentiality, integrity and availability, commonly referred to as the CIA
triad. Some would add a fourth element: trust, although the motives for
exploiting trust are directly linked to the other three. Let’s delve a little
deeper into the CIA triad.
Attacks on confidentiality
In the digital world, our personal data lives in many different places. Our
banks hold our financial data, which we can access via online services such
as mobile banking, social media companies have information on our personal
and professional relationships, and online retailers have data on our
purchasing history and often store payment details for the goods we buy. As
consumers, we empower and trust these organisations to protect our data and
prevent them from falling into the wrong hands – to keep our data
confidential – yet many of us are victims of a data breach, often
unknowingly. Troy Hunt’s Have I Been Pwned website reveals an enormous
number of email addresses and passwords that have been stolen and
published on the dark web, which is a part of the internet hidden from normal
web browsing tools and search engines. We think our usernames and
passwords are confidential, but many people, including your customers and
potentially your employees, have their credentials published by hackers. We
also hear about stolen credit card details that have been harvested during a
breach or learn that confidential information about our private lives has been
leaked by a website we thought we could trust. One popular social media
company was affected by a breach in which millions of records were
harvested for commercial and political reasons. Attackers can amass large
quantities of money either by selling the information or by exploiting the
details to steal money from an unsuspecting user.
The responsibility for denying attackers access to data managed by the
applications and services your teams develop sits within the engineering
team. Those developing the products and services that collect and store
sensitive data must keep the data confidential at all times. Accountability for
protecting the data’s confidentiality sits firmly within the organisation’s
leadership team, who provide the funds and governance to implement
effective controls to protect the data. I believe that both engineers, who write
software, configure environments and administer databases, and the
organisation’s leadership team have a moral duty to protect users’ data. It is
the responsibility of the production teams to use the most effective controls
available to them, while leaders are accountable for ensuring the organisation
has the capability to protect users’ data.
Encryption prevents attackers from seeing the data in a clear text format.
Encryption policies must be supported by an effective and robust key
management policy to protect the keys used to encrypt – and, more
importantly, to decrypt – the data. Attention should also be given to the
algorithms used to encrypt and decrypt data, which must be strong enough to
prevent hackers from cracking them. I would suggest that your organisation
should never try to create and use its own encryption algorithms. Standard,
publicly available algorithms developed through academic research are more
secure than any that your engineers can create.
Be aware that not all data needs to be protected. Indeed, there is a trade-off
between performance and the processor-hungry encryption and decryption
algorithms. Classifying the data based on its sensitivity allows engineers to
focus on the more highly restricted data, while public data can remain
unencrypted. Encryption and key management are huge topics on which
many resources have been written, so this book will not go into specific
details. However, it is worth promoting a basic knowledge of encryption
among your engineers: they should know the difference between public and
private keys, hashing and encoding (which is not a form of encryption
although is often mistaken as such). They will also benefit from learning how
keys should be transferred between users in order that data can be safely
exchanged between systems.
Confidentiality does not relate solely to user data (such as customers,
employees and suppliers). Many artefacts within an organisation should
remain confidential. These include system passwords which are often used to
gain privileged access to a production system. Privileged Access
Management (PAM) systems are designed to provide short-lived or one-time
passwords to relevant employees under strict criteria, such as investigating an
incident or applying an emergency patch. PAM systems are a control to
prevent attackers from gaining privileged access to the production system.
Your engineers should avoid creating privileged credentials and sharing them
with each other or on unprotected internal systems including email, intranet
pages and file systems.
Other confidential artefacts that need protecting include source code,
configuration files and libraries of the products and services that are produced
by the engineering teams. These are targets which attackers exploit by
gaining access to these artefacts to insert malicious code, backdoors or
Trojans into your organisation’s products and services. To avoid such
breaches, it is paramount that exclusive access to these resources is restricted
to the teams and individuals that need access. Role-Based Access Controls
(RBAC) define the roles associated with particular functions, such as
developers, database administrators and testers. Individuals within these
functions are assigned to the relevant roles within the RBAC data store and
policies applied to the roles defining the resources to which they have access.
Thus, developers may have write-access to a source code repository for the
product they are working on, while testers will have read-only access to the
same repository. The use of public repositories can provide greater risk to
your organisation if not configured to limit access to specific individuals and
teams within your organisation.
Maintaining confidentiality of a product or service, and the resources and
artefacts used to develop and build it, is the first of the three main controls
against attackers.
Attacks on integrity
The second type of attack is an attack on integrity. Maintaining the integrity
of a system involves ensuring the data behaves in a controlled and predictable
way. This means that, when data flows through an application, from a
frontend user interface (UI) to the backend system, or is stored in a database,
the data can only be altered in a controlled and expected way. Better still, the
original data should remain completely unaltered, and only copies of the data
should be manipulated to meet business requirements. Unfortunately, many
systems allow changes to data which opens the door to potential attacks on
the integrity of the data. For example, an attacker may be able to intercept a
transaction within an order and alter the delivery address without the user
knowing. This means the buyer pays for an item that is sent to an address
chosen by the attacker. The retailer will likely have to either reimburse the
buyer or dispatch another item to the correct address at no extra cost, which
directly impacts their profit.
The attacker could also intercept a file being uploaded and replace it with
another file that contains malicious content. If the unsuspecting victim
downloads and opens the file – or, if it is an application, runs the file – with
the malicious code, it could cause considerable or irreparable damage to the
user’s system. Such an attack can also cause reputational damage to the host
of the original file.
These attacks exploit weaknesses affecting the integrity of data within a
system to the advantage of the attacker. There are a number of controls to
mitigate against this type of attack; for example, creating immutable objects
that are instantiated with the correct state from classes with no accessors
reduces the risk of the attacker intercepting an order to change the address.
The object cannot be changed; it can only be read. Extending this further, if
your DevOps engineers develop servers or services and deploy them as
containers, they should follow best practices that recommend containers
remain immutable for their lifetime. Remote access to these containers should
be avoided.
DevOps promotes the use of automation to remove the need for manual
changes to systems. All changes that are made to an application should be
delivered through the CI/CD pipeline. Not only should these changes be
automated, any changes in production should be audited. Keeping a record of
what the change is, who made the change and for what business outcome the
change was made can help identify unauthorised changes to the system.
Another control to maintain the integrity of the system involves generating
a hash value from a file that has been downloaded – normally referred to as a
checksum. This checksum is compared to an expected hash value already
generated from the file. A hash is an encoded value created from the file that
needs to be protected; it is a one-way encryption technique using a hash
algorithm such as Secure Hash Algorithm (SHA). If the hash value of the
original data is identical to the hash value of the data being accessed, the end
user is assured that the file being downloaded has not been tampered with. If
the hash values are different, the file being accessed is not the same as the
original expected file.
Maintaining data integrity is an important function of the DevOps
engineering team. Data is at risk from being manipulated and altered whether
it’s in motion, such as flowing through the application or the deployment
pipeline, or at rest when stored in an application data store or a source code
repository. All members of the team must identify ways to protect data from
malicious or accidental manipulation.
Attacks on availability
Today’s consumers demand availability. They have an expectation that
online services are available on demand, at any time of day and on any day of
the year. Whether they are watching a film or listening to music through an
online streaming service such as Netflix or Spotify, accessing their online
bank account, or buying products from an online store, consumers expect a
seamless user experience 24/7. Even when users are browsing sites for
information, they expect the information to be immediately available.
Consequently, if a user tries to access your organisation’s services and they
are not responding quickly enough, or not responding at all, they will likely
go elsewhere. If your organisation generates revenue through your websites,
either directly through online payments or through indirect revenue streams
such as advertising, not being able to deliver content in a timely manner can
damage your company financially.
You must guarantee your organisation’s online services are available as
close to 100% of the time as possible. As discussed above, the DevOps model
is designed for minimal disruption to customers; when DevOps is fully
functioning within an organisation, releases are automated through the
deployment pipeline, which undergoes constant review and improvement,
while experimentation improves the commercial offering to the consumer.
However, a significant attack on the service, affecting its availability to
consumers, could negate the inherent benefits of DevOps in minimising
downtime. For example, an attacker could disrupt the service by orchestrating
a DDoS attack on it. DDoS attacks are designed to overwhelm a service by
sending it so many dummy requests that it is no longer able to process
legitimate requests efficiently, including traffic from your customers.
Eventually, it can cause the service to stop entirely. Attackers often have
huge botnets at their disposal to launch DDoS attacks. These botnets are
collections of internet-connected devices that have been infected with
malware designed to send requests to a particular IP (internet protocol)
address on command. For a company targeted by these types of attacks, the
outcome can be devastating.
Unfortunately, many botnets offering DDoS services are available on the
dark web for a small fee, but there are likewise numerous controls that protect
your business from DDoS attacks. Some are built into firewalls while others
involve caching data in a separate server. Both types of defences control
traffic flowing to the internal network. Developers and operations share
responsibility for defending against DDoS attacks by implementing controls
across the Open Systems Interconnection (OSI) layers, including the
application, session, transport and network layers.
Another kind of attack on availability, and one that has become more
common in recent years, is ransomware attacks. These normally extort
money from a victim by taking services offline. The only realistic way for an
affected organisation to bring the services back online is to pay a sum of
money, usually in Bitcoins, to the perpetrator. The most common method of
disrupting services is to encrypt all files within the target environment,
including application files, configuration files and databases. In many cases,
the encryption can be far-reaching and include all files for normal operation
of the company, such as emails and documents. Once the victim has been
compromised, they must pay a ransom to the attacker to receive a key to
decrypt all the files back to their normal state. Unfortunately, some
ransomware attacks may result in permanent damage. Even when trying to
restore from backup, the files will continue to be encrypted, rendering normal
business continuity methods ineffective.
There is a third form of attack on availability (as well as data integrity)
which is worth touching upon. Some hackers are happy to disrupt a website
by posting different content onto a page. Sometimes this can be for political
reasons, such as the hacker group Anonymous sabotaging websites of
specific organisations by replacing normal content with political messages or
offensive images. These are designed to embarrass the victim as well as
impact site availability.
Defending against DDoS and ransomware attacks is complex. For the
former, there are multiple controls that a DevOps engineering team would
need to consider for application code and the environments in which they are
hosted. These include using good coding principles such as validation,
memory management and application code flow, and good operations
principles such as load balancing, firewalls and resource management. We
will delve into some of these later in Chapter 5.
Attackers may target the confidentiality, integrity and availability triad for
financial gain, to disrupt a service or to make political statements. Many
attacks exploit weaknesses in more than one area of the CIA triad. For
example, if the integrity of a file is not checked, it may be a Trojan that
initiates the ransomware attack that affects availability. Likewise, a DDoS
attack may be a cover for an attack to exfiltrate information, targeting
availability and confidentiality. While focusing on the triad components
forms the basis of your defence strategy, it is also important to factor in
protecting trust within your organisation’s security policy.
Now that you have an understanding of what types of attacks to be aware
of, I will explain who your adversaries are.
Malicious hacker
Weapons of a hacker
Hackers are equipped with an arsenal of weapons to attack systems with
varying degrees of sophistication. Their tools can be classified under four
categories, which form the four basic phases of an attack:
1. Reconnaissance
2. Scanning
3. Exploitation and weaponisation
4. Control and management
Conclusion
By now you should have the basic understanding of what security means to
your organisation. There are many individuals, groups or state actors
determined to exploit your organisation for personal, financial or political
gain. They look to expose confidential information, diminish the integrity of
an organisation or affect the availability of the services needed to run an
organisation smoothly. Whatever their motives, they are often persistent; the
greater the reward, the greater the effort to find a route to the jewels of an
organisation. Even if your organisation is not the ultimate target of hackers,
they may exploit weaknesses in your applications and services, leaving a trail
of collateral and reputational damage in their wake. The hacker community is
well organised and has developed a large number of effective tools over
many years to simplify their tasks. Your threats are not just external but
internal too. It is the collective responsibility of everyone within the DevOps
organisation to protect your assets and those of your customers.
THREE
DevSecOps
In the next three chapters, I describe how to build each of the three layers to
empower DevOps teams to construct secure applications using processes that
are equally secure. Together, these three layers describe DevSecOps – not as
a team, but as a culture. It is important to not skip the first two chapters and
race to the automated testing chapter. Like any reliable structure, each layer
needs to have time to settle. Equally, though, it’s not necessary to plan and
build the whole of each layer before moving on to the next. In fact, the
principles of Agile should apply to building these layers, meaning you should
adopt an incremental approach to build vertical slices that allow your teams
to continuously improve how individuals and teams are educated, apply their
skills and assess progress.
Conclusion
In this chapter, I introduced the concept of DevSecOps, the need for it to be
explicitly defined and explained, and the points of contention that exist
between traditional cybersecurity ways of working and DevOps practices.
This book proposes a layered approach to solving this problem, enabling
DevOps teams to deliver applications and services securely, while allowing
security departments to focus on strategy to support the business needs for
faster digital delivery to their demanding customers.
I have introduced the three layers that sit below DevOps to form the
foundation of DevSecOps. Each layer builds on the previous one to create
strata of security education, secure by design and security test automation. In
the next chapter, I explain the details of layer 1.
FOUR
In this chapter, I develop the first of the three layers by explaining why
security education is so important to DevOps before describing the various
ways in which education can be delivered within your organisation to
promote a strong understanding of security. I also explain how you should
identify those with a deeper interest in security within the engineering teams
so they can play an important role in expanding the security skills of DevOps
teams. Finally, I highlight the importance of maintaining an elevated level of
security knowledge and skills within your organisation to continue offering
high-quality products to your customers.
Security champions
Everyone responds differently to education. Some learn just enough to do
their job well, others learn more than is needed, and a few will struggle to
grasp certain concepts required to complete their tasks effectively. This is a
normal distribution within an organisation. Occasionally, there are
individuals who learn a new discipline that sparks a passion within them. In
my experience, it is important to feed this enthusiasm by giving the
individual the time and resources to grow. With the industry struggling to
find enough quality security resources to support the increasing scale of
software engineering, finding and helping members of your organisation who
are prepared to pivot their career towards security is crucial. As they increase
their security knowledge and skills, in addition to their existing skills, they
will become key players in helping DevOps teams improve the security of the
products they create. We call these people security champions. They play an
important role in the continuing education of other team members by
supporting peer reviews, engaging in threat modelling exercises and helping
peers analyse outputs from security scanning tools. The key advantage
security champions have over a central cybersecurity function is having
specialist skills (such as software development, architecture and
configuration management) in addition to their growing security knowledge.
As you introduce different education tools to improve security within the
delivery lifecycle, it is important to identify the security champions early to
continue investing in them. Their passion for security will improve the
overall security of the products they are helping to deliver. You should allow
them to work as cross-cutting members of the organisation, helping multiple
delivery teams to improve the security of the products they are working on.
There is a temptation to place them within the teams that are working on the
most valuable products in terms of revenue, but you should avoid siloing
your best individuals in this way. By giving security champions a wider
remit, they can potentially nurture aspiring security champions across the
organisation’s product portfolio by becoming security evangelists.
Security champions that evolve from being software or infrastructure
engineers also play a crucial role in building security into the development
and automation process. They become prime candidates for writing re-usable
security components that other developers can consume when writing
software. They are also well-placed to write security tests that can be
integrated into the CI/CD pipeline or configure the tools used for testing the
security of your products.
Security champions are not security experts, so you should not expect them
to replace the entire function of a security team. However, their role can
provide a conduit between your organisation’s central cybersecurity
specialists and the DevOps engineering specialists to improve the relationship
between the two groups, providing better outcomes for your customers.
On the few occasions I have come across security engineers who have
pivoted the other way, moving from a central security role to a development
role, they have played a similar role to the security champion. Their main
strengths lay in the wealth of security experience they bring to a DevOps
team and their potential to motivate your next security champions.
Through education, you will discover the engineers inspired to further
develop their own security knowledge and skills. As these individuals grow
in maturity and confidence, they too can educate and inspire DevOps
engineers to become better at doing security and doing it well.
Gamified learning
Education should be fun. The more candidates enjoy the learning process, the
more they are likely to remain engaged with the subject, which, in turn,
increases their potential to absorb more knowledge. Gamification is the act of
turning something that is not a game into a game that involves scoring points
or competing against others; however, gamification in the context of learning
is more complex. The aim is to increase enjoyment, engagement and loyalty
in performing a set of tasks that ultimately enhance the learner’s capabilities
and knowledge. There are many vendors who offer gamification services;
their games all assume a basic understanding of coding practices and may
offer modules specific to the language that is familiar to the engineers. These
include application development languages such as Java and .NET, as well as
infrastructure coding languages such as Terraform and Ansible.
Usually, players are presented with a detailed description of a particular
type of vulnerability (or common weakness) and an integrated development
environment (IDE) emulator containing code with an example of the
vulnerability. These tools teach players how to directly exploit weaknesses
deliberately written into the code. Hacking code in a safe environment is a
fun way for engineers to learn how poorly written code can have severe
consequences. To score points in the game, the engineer has to fix the
vulnerability. There are normally added incentives for the participants such as
a certification programme or tournaments. Certification programmes provide
engineers with badges of honour, which enhance their profile among their
peers or improve their self-worth. Tournaments add intense competition
between individuals and teams vying to prove their statuses within their
organisation as leaders in security. With each successive tournament, they
need to defend their positions, incentivising them to learn more about writing
secure code. Matias Madou, co-founder and CTO of Secure Code Warrior,
offers a cautionary note on running leagues and tournaments: ‘Don’t focus
exclusively on the leaders. You need to focus on the lower ranked individuals
in order to keep them engaged. You don’t want to lose them.’
It is not essential to use third-party gamification tools. It is possible to
develop internally hosted games by collating and presenting real-time data to
the engineers. The goal is not necessarily education; rather, it encourages
safer and more secure products and services. However, education plays a part
in understanding how to tackle certain types of vulnerabilities. For example, a
dashboard could indicate the number of vulnerabilities identified and fixed by
each engineer over a specific period of time. Although this particular scenario
requires a reasonably high level of maturity within the team – not only to
identify and fix issues but also in having the metrics to present to them in a
dashboard – gamification in real time can be adopted in small increments.
The first step could be to collect information about the adoption of security
testing tools, pitting teams against each other to incorporate security testing
into their working practices. Over time, data relating to the number of
vulnerabilities these tools identify can be measured before recording the
number and type that are fixed and by which engineers. This form of
gamification creates competition between teams and individuals to reduce the
number of vulnerabilities being promoted to a live environment, which makes
the products safer for their customers.
Gamification, if done correctly, can have high engagement among
engineers. Debasis Das, of one of the world’s largest banking organisations,
has implemented a security gamification product across the company’s digital
organisation in India. He identifies a number of key factors that led to the
widespread use of gamification among his DevOps teams. This high uptake
has significantly reduced the number of vulnerabilities introduced into the
software solutions that the DevOps teams produce. Running regular
tournaments has been highly successful, but Debasis cautions that this must
be done correctly to avoid lethargy among engineers. A successful
tournament must provide incentives beyond bragging rights; therefore, he
suggests that teams and individuals play for prizes that are worth playing for.
If the prizes are of value to the engineers, they are more likely to want to be
involved. He also advises that the organisation’s leadership team must fully
support tournaments to avoid conflicts of priorities between delivery and
engineering. Delivery leads must be open to allowing development to stop for
at least half a day for the tournament to go ahead. Debasis says of the senior
leadership team: ‘They should agree on a time and block out the calendars of
the engineers to participate in the tournament.’ Leadership teams must also
support the ongoing education of the engineers by allowing a percentage of
the engineering workload to be dedicated to gamification (as well as other
forms of training and learning) – not just in security, but in all areas that
improve the quality of the end products.
Instructor-led training
There are advocates who argue that traditional teacher-led training in a
workplace should be avoided. However, I believe that businesses can benefit
from teacher-led security training applied in the right way. The main
advantage is that the course content can be tailored to the needs of the
business: the content can focus on certain types of security weaknesses that
have been identified during vulnerability assessments, or the course can be
contextualised with examples from the organisation’s source code repository.
In schools, the teachers follow a curriculum which presents course material to
the students in a predetermined order, irrespective of the students’ motivation
to learn. In business, you should avoid the temptation to follow a pre-set
syllabus if the content is not aligned to your organisation’s requirements,
especially if the course is fixed by the trainer without any input from the
candidates. Remember that you are not dealing with schoolteachers but with
professional instructors who provide a service to you; you can design the
syllabus that meets your organisation’s requirements.
With any instructor-led training, it is imperative you ask the supplier to
sign a non-disclosure agreement and limit access to the resources required to
perform the training. If an access key is required to enter the facilities, ensure
that access is time limited and is only for the training room. If the trainer
needs to access digital resources on the company network, implement
policies to restrict access to the absolute minimum to the relevant
information. The instructor may wish to plug devices, such as USB sticks,
removable media devices, or laptops and tablets, into your network, perhaps
to share documents with the course attendees. To protect your company from
malware or viruses being accidentally (or even deliberately) installed by the
instructor, you must follow your organisation’s security policies in relation to
BYODs (bring your own devices).
The human element of instructor-led training is an important factor, as it
provides an opportunity for students to ask specific questions to drill into a
topic or to clarify a point. In business, an effective instructor may determine
from the students’ feedback that pivoting the content during the course will
produce the best outcome for the students and the organisation. Students and
instructors can develop a strong rapport, which can create an ideal learning
environment, resulting in your DevOps engineers gaining a solid
understanding of security in the context of what they are doing via a two-way
conversation with the instructor.
Cost is often a prohibitive factor for instructor-led training. However,
online training can mitigate this as well as broadening the target audience and
reducing travel costs for the trainer and the attendees. Remote video
conferencing tools such as Zoom, Microsoft Teams and Google Hangouts
make this approach easier.
Self-paced learning
Many individuals are self-motivated when it comes to learning something
new. They are happy to spend time (often their own time) reading about and
playing with new technologies to understand how they may improve the
products and services they are developing. There are plenty of resources
available to people who like to take this self-paced approach to education.
These include the more traditional paper-based resources such as books and
magazines (although many are available as e-books or e-magazines); online
resources such as blogs, webinars and tutorials; and myriad short video clips
available through social media outlets such as YouTube. From an
organisational perspective, team members should be learning about topics
relevant to the goals of the organisation. This is important in the context of
cybersecurity, because individuals may focus on subjects that benefit
themselves personally, which may or may not align with the requirements of
the organisation. Providing an internal training repository of resources that
focus on security can counter this problem. Your organisation’s security team
can play a key role in identifying the relevant security resources that will
benefit the delivery teams. You can build an internal library of books and
magazines that cover security as well as the technologies used within the
organisation. You can also create an online catalogue of relevant training
resources such as links to blogs, videos and articles.
When security is not the core subject of the learning material, the self-
paced training resources have a tendency to focus on the technical problems
they are trying to solve and do not necessarily emphasise the security
elements of the solution. Indeed, it is common for these resources to
completely ignore the security aspects of the solution or, at best, provide a
disclaimer that the reader should add a security control, but the lack of space
or time (or perhaps knowledge) prevents the author from including the
control in the text. As an added exercise, your DevOps teams should be
encouraged to identify these gaps and document more secure solutions. Your
library needs to contain material that specifically covers security and it is
equally important to encourage team members to include these resources in
their self-paced curriculums.
By providing access, resources and time for your DevOps engineers to
educate themselves on security, they are more likely to engage in a self-paced
approach to learning. Unlike instructor-led courses, this methodology does
not suffer from timing issues. As long as relevant resources are accessible,
engineers will use the material to help them overcome problems that are
affecting them when they need it. In a DevOps environment, the provision of
just-in-time resources to solve problems helps remove blockers and improve
the flow of the value stream.
Self-paced learning is also cost effective. Some resources you will have to
purchase, such as books and tutorials (although these are cheap compared to
instructor-led courses and conference tickets); however, there is also a huge
amount of free security education material available online, particularly
resources available through OWASP, SANS, MITRE and local government
agencies. The following subsections provide a brief overview of the various
types of self-paced learning resources and their relevance to security within
DevOps.
Tutorials
Webinars
If you are fortunate enough to have teams of appsec engineers within your
organisation, you can create an environment in which the DevOps engineers
and security engineers work together to review the code-base. This could
involve an appsec engineer peer-reviewing finished code or working
alongside one or more DevOps engineers as code is being written. This
allows appsec engineers to share their knowledge with software or
infrastructure engineers to improve the security of the application and
infrastructure code. For example, if a software engineer is not familiar with
SQL injection flaws and has introduced this vulnerability into the code, it
would be beneficial for the appsec engineer to walk the developer through an
SQL injection attack scenario and explain why code written this way is poor.
It is only by understanding and observing the potential dangers of writing
such code, rather than just seeing the code fixed by the appsec engineer, that
the developer will learn to appreciate the importance of their actions.
We should not overlook the benefits of this model for appsec engineers as
well. In application development, technologies are changing constantly.
Involving appsec engineers in pair programming and peer reviews gives them
an opportunity to learn about the technologies and frameworks used within
the DevOps value streams and better equips them to support engineers when
advising them to write secure code.
As mentioned previously, the number of appsec engineers is vastly under-
represented in organisations compared to the number of software
development engineers. I introduced the concept of security champions
earlier in this chapter. As you nurture security champions, appsec engineers
can focus on educating these individuals to perform security code reviews
and help identify security weaknesses during pair programming. It then
becomes the responsibility of the security champion to propagate security
knowledge within the team. If possible, your teams’ pair programming and
code review strategy will match those who have great security knowledge
with those who have little or no security knowledge.
Security champions and other individuals who have learned new security
skills may wish to share what they have learned with their peers using other
informal forums. Your teams will benefit from having the time, space and
resources to run informal knowledge sharing sessions such as regular lunch-
bag meetings and short training sessions. You should also invite members of
the central cybersecurity team to share some security knowledge during these
informal sessions.
Experimentation
The most effective way of learning new skills is to be hands-on. There are
times when an engineer will only understand the nuances of a new
technology or process through trial and error. In DevOps, value streams use
experimentation to deliver the best outcomes for customers. This means
DevOps teams can work on several new features or products and deliver
them to small groups of customers to see how well they perform. The ones
that are better received by their customers become standard features, while
those that were less successful are either confined to the rubbish bin, archived
or re-worked and delivered as a new experiment.
Experimentation can also be applied to the process of assessing new tools
or technologies to be integrated into the product value streams. Those that
make design, development and delivery of features more efficient and secure
will be adopted and expanded within the team, while those that are less
effective are quickly removed. For example, engineers may choose to adopt
static application security testing tools (more on this in a later chapter);
however, their effectiveness must be evaluated against outcomes. The ones
that provide the greatest benefit in terms of accuracy (identifying genuine
vulnerabilities), ease of integration (used within the IDE or build pipeline)
and ease of use (identifying and fixing vulnerabilities) are adopted, while
others are rejected. This approach reduces cost (because only effective tools
are adopted) and improves security (everyone benefits from using the tool).
You should resist the temptation to allow security teams to unilaterally assess
and purchase security tools and instead create a culture in which security
engineers collaborate with DevOps engineers to choose the right tools for
their value streams.
Security features can also be assessed in a similar way. To provide a basic
example, if engineers are undecided on which authentication methodology
creates the better customer experience, they can develop two authentication
features and deploy them in an a/b experiment to see which one produces the
best outcome. Metrics gathered by management information (MI) tools may
identify that one feature has a higher drop-out rate or takes each customer
longer to action on average. These measures can be assessed alongside the
benefits from a security perspective to provide a more balanced risk
assessment of the feature based on business impact. In the example scenario,
the impact due to the lack of customer engagement may outweigh the impact
of using a feature that has reduced security but is easier for customers to use.
Ultimately, understanding risks is part of the education process and this type
of experimentation creates that learning experience.
Experimentation is more likely to be effective if the whole delivery team is
involved. If it is assigned to one or two senior engineers within a team, it will
be difficult to obtain full buy-in from the other members. On the other hand,
if everyone is involved they will feel fully engaged and part of the decision-
making process, as well as benefiting from learning a new skill or
technology. It will also make adoption of the technology or product more
acceptable to the whole team.
‘Play’ hacking
Certification
Receiving awards for achieving specific goals is a healthy motivator for
many people. Runners completing their first marathon will wear their medal
with pride, no matter their finishing time or position; the evidence of their
achievement gives them great satisfaction. Within the professional
environment, this evidence of achievement manifests itself in different ways:
a bonus payment, a voucher for a family day out or a meal, tickets for a show
or even a decorated lanyard ribbon can have the same effect. From an
education perspective, beyond the accolade of completing a difficult course
or learning a new skill, students like to receive a certificate when passing an
exam or completing their study. Many tech giants such as Microsoft and
Amazon, as well as specialist training and certification associations such as
(ISC)2, ISACA and CompTIA, offer industry-recognised certificates via their
own training programmes. Some of these programmes involve considerable
time investment to learn the skills to pass the relevant exams, whereas others
evaluate current knowledge and skills and issue certificates to professionals
who demonstrate they have the necessary qualifications to pass the exams.
Despite the requirement to spend time studying for exams, the knowledge
gained by students is likely to benefit their teams and the products they are
working on. It reassures their customers that accredited professionals built the
products and services they are delivering to them, and therefore, investing
time and money for employees to gain qualifications is worthwhile.
Avoiding entropy
To remain competitive, products need to be constantly updated with new
features, modified customer journeys or bug fixes. The alternative is poorer-
quality products, diminishing market share and shrinking profits. Investment
in products is essential to maintain a healthy market presence in which
products can thrive commercially. Knowledge suffers the same fate: failure to
invest in education will result in diminishing skills, poorer products and a
disenfranchised workforce that will eventually harm profitability. If you
invest in education, you will maintain the knowledge and skills to deliver
better products, allowing your organisation to maintain its competitive edge.
Entropy describes loss of information – in this case, knowledge and skills.
It is caused by two factors: attrition, when staff leave the organisation, taking
their skills with them; and technological advancement, when technologies
and processes used for developing applications and software progress faster
than those used within an organisation. The two components of entropy are
intertwined; as engineers find their skills are not keeping up with
technological advancements, they are likely to leave the organisation to seek
opportunities to improve their skills elsewhere.
Continuous investment in education is necessary to mitigate against
entropy in your organisation. This is not a one-off exercise, or a regular
catch-up programme: education is an ongoing process. It needs to be
embedded in the daily activities of the organisation. From a DevSecOps
perspective, engineers need to engage in a continuous programme of
improvement to make use of the latest technologies and processes to deliver
high-quality and secure products that will continue to delight your customers.
DevOps engineers need to continuously research the most effective
development practices using the most suitable and reliable education
programme. Since individuals respond differently to the various ways of
learning described above, it is advisable to adapt multiple approaches and
review them constantly with staff members. The goal is to constantly
improve the knowledge and skills of the organisation as a whole. The lower
the entropy of knowledge and skill, the more likely your organisation will
deliver high-quality, feature-rich and secure products.
Measuring entropy is difficult, although there are some techniques that can
be used. Let’s imagine, firstly, that the number of injection attack
vulnerabilities in your organisation’s production code is too high. Secondly,
let’s say the level of knowledge of each individual in the team who can
design, develop and test controls that mitigate this threat is known. Finally,
let’s say you’ve calculated the probability of these members leaving the team
based on the team’s attrition rates. Over time it is evident that, as the
probability of individuals leaving the team increases, the knowledge and skill
within the team required to fix this defect will also decrease. As this skill
value tends to zero, the greater the risk to your organisation. Knowledge is
not lost exclusively through members leaving the team; it can also diminish
over time as team members forget what they have learned previously. If your
organisation does not invest in continuous learning over time, it will lose the
knowledge and skills needed to maintain up-to-date and secure applications
and infrastructure, resulting in lower customer satisfaction and reduced
market share. On the other hand, if you maintain the level of knowledge
within the team, the risks remain small.
Conclusion
Education is at the foundation of DevSecOps: it is explicitly identified as one
of the three ways of DevOps. Everything DevOps engineers do is a learning
experience, whether it involves learning new technologies or processes,
learning about their customers’ behaviours and how changes to the
applications they develop affect them, or learning how to develop secure
systems. Cybersecurity is everyone’s responsibility, not just that of a central
security function. For DevOps to be effective, everyone in the value stream
must understand their role and their responsibility to develop secure products.
They must have an appreciation of how threat actors exploit vulnerable
systems so that they can defend against them.
In this chapter, I have identified a number of methodologies to integrate
security knowledge into the value stream. I do not suggest that everyone
working in DevOps be experts in security; instead, I proposed that the
collective knowledge within a DevOps delivery team is comprehensive
enough to deliver secure software. I suggested that those who show a
willingness and capability to learn over and above the security requirements
of their role are prime candidates to become security champions and
propagate knowledge throughout the team. Finally, I discussed the perils of
letting entropy reduce the security capability within the value streams.
In the next chapter, I move on to the next layer of DevSecOps, secure by
design, which builds on the knowledge acquired through a robust security
education programme.
FIVE
Threat modelling
Although I have separated education and security design principles into two
distinct DevSecOps layers, the glue that joins the two together is threat
modelling. Threat modelling is at once an exercise in education and a process
of making the right security design decisions.
DevOps engineers should be familiar with the types of security weaknesses
that attackers search for so that they can mitigate against them being
exploited. When designing a new product or a feature within an existing
product, it is essential to understand the risks inherent within the design so
that they can be eliminated or mitigated early in the delivery lifecycle. Threat
modelling is a process in which engineers assess the design of the product or
feature to identify threats and to work out how to build in protection against
them. There are several documented methodologies, including one described
by Adam Shostack in Threat Modeling – Designing for Security, which
introduces a four-step framework designed ‘to align with software
development and operational deployment’. The four steps are:
To obtain the best results from threat modelling, all DevOps engineers
working on the product or feature to be assessed should dedicate a significant
period of time to the exercise, preferably co-located in a room with a
whiteboard. The process starts by having engineers draw a data flow diagram
(DFD) of the product, paying particular attention to where data is at rest or in
transit, and mapping the security boundaries across which data flows, such
API contracts, as well as the actors who should have access within these trust
boundaries. Focusing on data is important because an attacker’s goal is to
target data; for example, exfiltrating personal details (including credentials)
or manipulating data such as shopping baskets, financial transactions and
even source code.
Trust boundaries define areas that share the same level of privilege and
where changes in privilege occur. These are important to identify because
attackers look for ways to access different areas of a system using
weaknesses in privileged access control. For example, customers have access
to view their own shopping basket but do not have access to other customers’
shopping baskets. However, the fulfilment team needs access to view many
customer shopping baskets in order to process their orders. Attackers search
for weaknesses that allow them to assume the identity of a customer but gain
the elevated access rights of the fulfilment team to view all customer
shopping baskets. Data should be protected behind different trust boundaries
implemented by robust access control policies. DevOps often involves small
incremental changes to an application; if there are no updates to the flow of
data in and out of the security boundaries, or there are no amendments to
existing security controls, the threat modelling exercise can focus purely on
assessing the change in the context of existing architecture.
Finding threats is a complex process which, if not carried out correctly, can
lead to missed potential weaknesses in the application or service. As
discussed previously, there are three types of attacks: those on
confidentiality, those on integrity and those on availability. The main
objective of threat modelling is to identify how the application may be
exposed to these types of attacks. In addition to the CIA triad, there are also
elements of trust that require threat modelling to identify weaknesses
associated with authentication and authorisation. There are several threat
modelling techniques, such as STRIDE, LINDDUN, PASTA and VAST,
each with its own set of advantages and disadvantages. The most mature
methodology is STRIDE, which has been around for two decades at the time
of writing this book.
STRIDE
STRIDE was invented in 1999 by Loren Kohnfelder and Praerit Garg. It is an
acronym in which each letter describes a particular type of threat:
STRIDE
Testing threats that have been mitigated should form part of the strategic
testing programme. Automating tests to evaluate the controls that have been
put in place to mitigate risks provides DevOps engineers instant feedback in
the event that a subsequent change to the application or infrastructure impacts
the mitigating control. As I will demonstrate in Chapter 6, not all tests can be
automated, so it is important to use manual penetration testing to determine
whether the risk can be exploited. An identified threat may not be exploitable
due to other controls that already mitigate the risk of an exploit. Conversely,
a risk that is considered low may be combined with other low-rated risks,
which collectively raises the threat to a level that is less acceptable to the
business stakeholders.
Threat modelling is a useful DevOps tool in the ongoing battle against
hackers. It helps to identify potential exploits quickly so that they can be
managed accordingly. By bringing engineers together to discuss threats, they
share knowledge of the system and gain a better understanding and awareness
of security.
Clean code
In his book, Clean Code, Robert C Martin defines a number of principles for
writing code that is well structured, concise, and easy to read and understand.
Martin does not explicitly cite security as the main reason for writing clean
code, but poorly written code is a significant factor negatively affecting
business outcomes, including an increased risk of security incidents. The
adoption of clean code practices within the DevOps engineering team is a
simple yet effective way to reduce security risks within your organisation’s
applications.
Substandard code is synonymous with technical debt. Unfortunately,
maintaining code of inferior quality introduces even more technical debt.
Ultimately, this will cripple a software engineering organisation’s ability to
deliver high-quality features and products to an expectant market. Clean code
is an enabler of the five ideals of DevOps discussed in Chapter 1: it
introduces simplicity, allows developers to focus on outcomes, creates a
platform for minimising technical debt (maximising psychological safety)
and ultimately allows engineers to satisfy the needs of their immediate
consumers.
Martin describes a number of principles, patterns and practices within his
book on writing clean code. Each plays a part in mitigating against writing
vulnerable software as well as infrastructure code. Not all teams have the
luxury of developing new products from scratch, which we call greenfield
products; therefore, if your DevOps engineers are working with poorly
written legacy code, I would advise them to refactor the code to make it
cleaner. Although this effort may sound like a waste of investment, the long-
term returns will include fewer security defects and faster software
development.
Data abstraction
Hiding the database structure is a key factor when writing secure code. By
exposing the database schema through public interfaces, you are giving
hackers knowledge about what data is stored and their relationship with other
data objects. It can also lead to confusing code in which data objects
representing data structures are chained together in order to provide a
representative model of a complete object. The following simple example
provides a lot of clues about the structure of the database and other objects:
<CustomerAddress = getCustomer(customerid).
getOrder(orderid).getDeliveryAddress>
In the second version, there are fewer indications of how the data is
structured.
Boundaries
Using third-party libraries in software has become a necessity in recent years
to let engineers focus on the features that add value to the product while
leaving grunt work to software written by open source communities. We
discuss open source libraries from a pure security perspective later in Chapter
6; however, in the context of clean code, it is preferable to avoid direct
communications at the boundary level between your organisation’s code and
that of the third party. If engineers are given free rein to access the interface
of the open source library directly, they are susceptible to changes made by
the community developers affecting the functionality of your applications and
services. For example, if a method signature changes, anywhere the method
is called will have to be changed too, otherwise an exception may be thrown
or an unexpected result is returned, leaving your application open to potential
vulnerabilities. Martin suggests writing an abstraction method for the third-
party library, meaning the code only needs to be changed in one place.
Writing tests to validate this abstraction provides a safety net when changes
occur, allowing DevOps engineers to respond to these changes quickly.
Validation
The primary reason for validation is that you must never trust user input.
Whenever an application expects a parameter, such as from an input field on
a web form or from a query string from an HTTP request, developers should
always implement a mechanism to validate these inputs to protect from
nefarious activity. Using domain primitives (as mentioned later in this
chapter) provides developers a certain level of control to manage input values
and the state of the primitive object. As we have seen, some of the OWASP
Top Ten vulnerabilities involve failures to validate input data. In SQL
Injection and Cross Site Scripting (XSS), an attacker could manipulate user
input to cause an application to behave in a way it is not supposed to.
In a multi-tiered application, there are multiple layers each requiring its
own set of defences. It is a common mistake made by developers to validate
only one layer of the application. For example, a standard application has
three tiers: the frontend presentation layer, the backend server layer and a
database. The easiest layer to validate data is at the point of user entry.
Therefore, developers tend to put all their validation into the frontend forms
to check the validity of the data users enter. Unfortunately, less emphasis is
put on validating the inputs at the server and database layers. The engineer
makes the basic assumption that all traffic arriving at the server is validated
by the front-end client. Unfortunately, this cannot be guaranteed. An attacker
has access to a number of proxy tools to intercept requests to the server and
change values after they have been validated by the client. This allows the
hacker to bypass the client validation process and send unvalidated data to
the server. Obviously, if the server is not validating this input, the attacker is
able to inject non-validated values into the unprotected server. Likewise, if
the database does not validate these values, the data will be inserted into the
database. Why is this the wrong approach? If an attacker is able to insert any
value into the database, it could be used to run scripts (such as XSS attacks)
from subsequent page requests, alter data including personal or financial
information, or corrupt the content of managed websites.
It is important that validation logic remains consistent across all layers of
the application. If the rules between the different tiers are different, it could
create defects that cause unexpected outcomes. For example, if an allow-list
of valid characters is used for client validation and a block-list used for server
validation, there could be conflicts in which characters are permitted. If
validation rules change, it means they have to be updated in multiple places.
Domain primitives provide an excellent mechanism to build validation into
all layers of the application with minimal effort. The authors of the book
Secure by Design, Dan Johnsson, Daniel Deogun and Daniel Sawano,
describe how domain primitives work; I provide a brief summary below.
Domain primitives
As we have just seen, an important mechanism for protecting applications is
to validate all input data across the boundaries of the application. This means
checking the format, whether it comes directly from a user, from a
dynamically constructed query string, or from another endpoint or API. A
feature expecting a string of a certain length with a limited character set
should only allow strings that meet this criterion. All other values should be
rejected.
Let’s take the example of a UK postcode. This value has a specific format
that follows a documented standard. Most UK postcodes consist of one or
two letters at the start, followed by a number from 1 to 99, followed by a
space, another number from 1 to 9, and two more letters. There are no non-
alphanumeric values in the format. Each time a user enters a postcode, the
application needs to ensure that they use the correct format; submitting an
incorrect format may indicate an attempted injection attack. The string may
include the pattern of an SQL injection attack, or the user may enter a long
string that takes a long time to process (which may indicate a denial of
service attack). Your security-educated engineers know that it is important to
validate the submitted string, so each time a postcode string value is used in
the application it is validated. However, if the postcode value is used in
multiple places within an application – which, in a DevOps organisation, is
developed by different engineering teams – it is likely that not all instances of
the postcode are validated correctly. If the UK Post Office changes the
postcode format, or the product is made available in a region that uses a
different format, all code that validates the string will need to be changed.
Unfortunately, inconsistencies may creep in or some are not validated at all,
resulting in your products accepting incorrectly formatted and potentially
malicious postcode values.
A more elegant approach is to use domain primitives. The authors of
Secure by Design define these as a combination of ‘secure constructs and
value objects that define the smallest building block of a domain’. Returning
to our postcode example, instead of using a string object, the developer
creates a domain-specific object to manage postcodes. This object is self-
validating, and it will only be created if the format of the postcode provided
by the user is correct; if the postcode format is incorrect, the object cannot
exist. However, once the object has been instantiated it is passed as a
parameter within the application. This ensures that the postcode value is
always in the expected format. Finally, if the format of the postcode needs to
change, the developer only needs to alter the validation code in one place.
Designing applications and services to use domain primitives is a simple
solution to a difficult problem and enhances the security of your
organisation’s products.
Regular expression validation
The validation of strings often requires the use of regular expressions. Within
the domain primitives, you may need to validate the conversion of the string
value to the domain-specific value against a regular expression. However,
developers must use them with caution because they have their own security
weaknesses if not used correctly. To avoid one potential issue, developers
should validate the string length before parsing the string through a regular
expression validation function. The reason for this is that longer strings take
an exponentially longer time to perform the regular expression validation.
Hackers often exploit this weakness to perform a DoS attack against the
application performing the validation. Returning to our postcode example,
your engineers need to check that the string is no longer than eight characters
before stepping into the regular expression validation.
Ideally, you should use at least two factors in determining the identity of a
user, preferably more for accessing the most restricted areas of a system. This
is known as multi-factor authentication (MFA). There are several common
MFA implementations which your DevOps teams should be encouraged to
adopt in developing their applications and building the infrastructure. For
example, once a user has provided a username and password (what the user
knows), they receive a one-time password (OTP) that is sent to their phone
(what the user has) via SMS. To complete the authentication journey, the user
must enter the OTP into the web browser or application. A recent threat
against this method is SIM-jacking, which involves an attacker taking
ownership of the mobile telephone number, allowing them to intercept the
OTP message sent to the phone. The solution is to ask the user to enter an
OTP generated on a physical access token or by an authentication provider
installed on their phone, which bypasses the need to use SMS messaging.
When designing a product or feature, or even a process within the value
stream, you should determine whether you need to implement authentication.
In some cases, the employment of anonymous users is valid; for example, if
your products are informational, such as a news portal. However, there are
many instances in which users of an application need to register in order to
perform a number of tasks. A typical model would be an application in which
customers buying a product from a website on which they have already
registered need to log on in order to access their payment details and delivery
address. The customer’s experience of using the website is enhanced because
they do not have to retype this information each time they visit the site to buy
a product or service.
Not all principals are human, which means some of the authentication
methods are irrelevant, such as biometric and behavioural authentication.
Non-human authentication involves establishing trust between entities – a
process that often uses public key certificates such as X.509. Because these
certificates are public, they are not a proof of identity unless the entities know
the private key corresponding to the public key. Of course, management of
the private key is crucial to avoid it being exposed and exploited by hackers.
Keys must never be hardcoded within the entities, even if they have been
encrypted. They must be kept in a separate secure store, such as a secure
password repository or a hardware security module (HSM).
Your engineers need to design applications and services with a high degree
of assurance that the identity of the principal is legitimate. Further, as systems
become more distributed, it is critical to establish identities and authenticate
them across multiple services. This increases the complexity of the
authentication process. Fortunately, there are a number of protocols in use
today that simplify the task, including IdP, SAML, and OAuth supporting
OpenID Connect. DevOps engineers should be familiar with these
technologies and apply them accordingly.
Authorisation
Accountability
Immutable objects
Designing security into application classes is another area requiring some
attention. I have worked with developers who try to do too much with their
classes, and I’ve been guilty of this too. We end up creating a bunch of public
accessors in our classes so that consumers can alter the state of an object after
the object has been instantiated. Thus, a class may have a number of public
setters that allow a user to change the value of the property at runtime. For
example, if developers create a customer class, it is considered practical to
provide a writeable name property in case a customer needs to change their
name (following a change in marital status, for example) or a writeable
address property in case the customer wants to change their delivery address.
However, public accessors provide no control on how or when these values
are altered. A hacker can use a public accessor to change the value of the
instance property such as the address value during the final stages of an order
fulfilment process. Instead of the customer receiving the goods, the hacker
diverts the items to another address by setting the address value during
runtime. To counter this risk, customer objects that are created for use by this
fulfilment process should remain immutable. Developers should design
classes in such a way that the objects are pre-populated with correct values
only during instantiation. These properties should also be read-only, which
means there is no way to change the state of the object at runtime. As a result,
hackers cannot change the state of an existing object. In the above example,
the delivery address remains as the customer intended.
Error handling
Logging exceptions
When exceptions occur, it is important to log the details in a suitable logging
tool. Error messages produced during an exception must contain enough
information to help developers, testers or operations staff resolve the problem
that caused the initial error. As stated in the ‘Error handling’ subsection, the
customer does not need to know the low-level details of what went wrong
within the application. They will benefit from a friendly error message with a
brief explanation of what went wrong and offering a way out of the situation.
On the other hand, engineers must have as much detail as is necessary to
resolve the problems causing the exception; therefore, providing a full stack
trace is useful for the engineers. However, it is worth repeating here that
hackers can mine details from stack traces that give clues to the design of the
application and the environment on which it is hosted, so it is imperative to
add controls to defend the logs from attackers. Highly sensitive data must be
encrypted or obfuscated (ie masked with characters such as ‘#’). Access to
logs must be restricted and time limited, preferably with a privileged access
management system.
Within DevOps, logs are important to the overall function of continuous
feedback. Logs need to be mined constantly to identify when exceptions are
thrown so that engineers can provide a timely fix. There are many logging
tools that make this process easy, using heuristics and pattern matching to
identify potential security defects from exceptions recorded in log files.
Logging exceptions also feeds into the alerting and monitoring tools which I
discuss in Chapter 6. These can identify where exceptions are thrown due to
potentially nefarious activities, such as blind injection journeys carried out by
hackers.
Microservices
The concept behind microservices is to create an architecture that allows
independent services to be designed, developed, deployed and maintained
according to a business domain model. Each service has the capability to
communicate with other services without having direct dependencies on
them, and each service independently manages its own data storage, data
retrieval, business logic and presentation. This architecture is in stark contrast
to a traditional monolith in which all business logic is packaged into a single
deployable application. These types of applications can be huge and complex.
Although monolithic systems may be modularised around business domains,
generally the various components are tightly coupled together and connect to
one or more databases with large schemas that store data for all relevant
business domains. When engineers need to make a change to a feature in a
monolith, the whole application and database need to be re-compiled, tested
and deployed together.
Deployments are invariably problematic. They normally consist of
complex manual steps, requiring the entire application to be taken offline
leading to long periods of disruption for customers. It’s not unusual for
operation engineers to spend long periods over weekends and evenings fixing
issues during the deployment process, while development engineers remain
on standby to apply quick fixes to the code. Mistakes are frequently made
during these high-pressure scenarios as engineers battle with instability
issues, sporadic failures or even corrupt data. From a security perspective, in
their haste to push the monolith into a production ready state during the
release window, engineers exercise poor practices. For example, if a service
fails to start due to incorrect access policies to read data from a database, the
engineer will ignore the principle of least privilege and assign the service
higher permissions than necessary to work around the problem. It is common
that code changes are made during deployment, bypassing normal activities
such as code reviews and testing. These changes often create security
weaknesses in the application.
Microservices, on the other hand, are designed, developed, tested and
deployed as isolated components by a dedicated cross-functional team
working as a unit. As a result, they are an enabler for the five ideals of
DevOps I discussed in Chapter 1: independent and focused teams with
greater productivity, psychological safety and excellent customer
experiences. Teams can also achieve greater security within their value
streams through low-risk releases driven by security focused design, test
automation and continuous learning.
Microservice security
Container technologies
The growth in container technologies has been driven to a large extent by the
adoption of cloud hosting services; the emergence of DevOps; and the need
to develop, test and deploy new products and features to customers with ever
greater efficiency and lower cost. These technologies are designed to simplify
the value stream and minimise disruption to customers, yet this simplicity
belies the underlying complexity in the way these technologies integrate.
With added complexity comes greater risk in terms of cyber security.
Misconfigurations, poor design and improper implementation can leave
gaping holes in the defences for attackers to exploit; therefore, it is essential
that DevOps engineers and infosec understand the security implications
involved in setting up a container-based service. I will describe these
technologies next and provide some guidance on how to design, implement
and maintain the security of products hosted in a container-based
architecture.
Container security
Liz Rice, in her excellent book Container Security, provides a checklist of the
various security requirements for designing and implementing containers.
This list is an excellent starting point for anyone looking to deploy containers
in their organisation. There are several threats directly affecting containers
which your engineers must be able to defend against, including escaping
containers, exposing container secrets, and compromising container images
and container hosts. The applications running within containers, as well as
the connectivity between the network in which the containers are running and
the organisation’s network, must also be designed securely. Therefore,
container security requires a number of architectural design decisions that
your engineers must consider to address these threats.
Each container must be isolated into its own workspace via a set of
namespaces. Isolation limits their ability to access other workloads running in
other containers, as well as restricting access to the host file system and
control groups. Since containers run as root, explicitly isolating them is
critical to prevent malicious actors exploiting weaknesses, causing them to
escape the container to access other resources.
In most cases, applications running inside containers will need to access
credentials at runtime to access other resources such as databases. How they
manage these secrets is a critical step in the design process. There are various
options for injecting secrets into running containers, including embedding
encrypted values in the container image so that they are injected during the
build process, storing them in environment variables or using the file system
accessible through a mounted volume. Each of these methods has weaknesses
and strengths, which means that choosing the appropriate one should be
based on risk appetite and context.
Images are built using a set of command-line instructions listed in a simple
file such as a Dockerfile. The contents of this file must be maintained and
reviewed by individuals with an understanding of the security risks
associated with image files. The file must also be treated as a highly restricted
resource stored and protected through access controls and monitored for
changes. Failure to protect the images risks malicious content such as
malware being injected at build time.
Finally, containers are hosted on virtual machines (VMs), either in the
cloud or on bare metal, so it is important to design these systems to minimise
their exposure (such as ensuring only the bare minimum services are installed
to run containers) and scan them regularly for emerging known
vulnerabilities.
Containers can be a weak link if they are not designed with a strong and
robust architecture. I strongly recommend that your engineers familiarise
themselves with the types of threats associated with containers and know how
to apply security measures to protect your organisation.
Image security
Image files describe how containers are built and run. In other words, they
define any application running in a container. This means they must be
treated as highly sensitive assets to prevent malicious users taking advantage
of them. They must be stored securely, which I talk about in the ‘Image
registries’ subsection. They are also prone to misconfigurations that can
create security risks, which I discuss here.
Images are based on layers, the lowest of which is the base layer. This layer
normally contains the operating system (OS) on which the applications
within the container will run. It would be a mistake to include a full OS in the
image file because a containerised application only needs the bare minimum
OS features required to execute. There are a number of lightweight base
images your teams should use which are designed to be small, secure and
efficient, compared to fully-fledged OSs. By not using a full OS, you
significantly reduce the attack surface of the running container that hackers
can exploit, minimising your risk. You can also use multi-staged builds to
reduce the image size, further removing the features of the base image
required for the build and compile phase to a smaller subset required for
running the application.
Your DevOps engineers must also consider the identity of the container at
runtime when creating the image file. Unfortunately, many image files use a
default user that has root access to the container host. This means it is
essential that engineers specify a user with least privileges to run the
container. Because the default value is the highly permissive root user, if the
engineers do not explicitly set this user, the risk of an attack on the host,
which we call escaping the container, is significantly higher.
Another common mistake made by DevOps engineers is to hard-code
secrets within the image files, either encrypted or in clear text. Since these
files are human readable, it is extremely bad practice to store any secrets
within them. Even if the files are not accessible to engineers without the right
level of privilege, these secrets can still be revealed and exploited in a
running container, described in the ‘Container security’ subsection.
Therefore, the simple rule for your DevOps teams is: do not hard-code
secrets in the image files.
Ensuring that images can be trusted by other teams consuming them needs
to be factored into the design of the image file. Firstly, your DevOps
engineers should sign their own images and put in place mechanisms to
verify their authenticity. This action prevents an attacker from altering the
image files between when they’re deployed and consumed – a man-in-the-
middle (MITM) attack. It is also advisable to design a naming convention for
the image tags that help engineers distinguish between the different versions
of images. This is important in identifying potentially vulnerable images from
their patched versions. Engineers should name their tags with a version
number, such as alpine-v2.01, instead of relying on the tag latest (numbered
versions can be easily identified whereas latest is potentially misleading).
Although this may carry overheads in automation that looks for the latest tag,
you can overcome them with design principles that support a dynamic
naming convention.
Image registries
An image registry is a service responsible for storing and distributing
container images. Most organisations use a third-party registry such as
Docker Hub, Google’s Container Registry or Amazon’s Elastic Container
Registry. They can be public or private, their use determined by your
organisation’s policy on image registries: private registries need to be
maintained within your organisation. Each image is stored along with its
image manifest, which defines the layers that make up an image, and its
image digest, which is a unique identifier of the image based on a hash of the
image and its manifest. Images can also be labelled for easier identification
using tags, such as using a version label. However, since these tags can be
applied to multiple images, a tag is not a guarantee of pulling the same image
from the repository each time. From a security perspective, there is an
important distinction between a tag and a digest, particularly for asserting the
integrity of the image.
There are obvious security measures that your DevOps teams should
implement to mitigate risks associated with image registries. One of the main
concerns is using an image that a hacker has compromised either at rest in the
registry or when pulled from the registry. An effective control for this is to
restrict engineers to access only approved registries, whether private or
public. Engineers should have limited access to images within the registries
based on their role within the value stream. For example, engineers should
only use approved base images that have been scanned for known
vulnerabilities. To guarantee the use of approved images, they should be
signed with a cryptographic algorithm that can be verified at runtime.
The Dockerfile is an important asset for images and should be treated like
any other valuable source code file – it should be version controlled and
protected through access controls. There are also some security
considerations to factor into the design of the Dockerfile, such as referencing
trusted base images and using multi-staged builds to remove components that
are not needed at runtime (such as compilers).
Orchestration
Orchestration is an automated process for managing the workloads of
containers across multiple clusters. Each cluster consists of a control plane
which controls a set of worker machines called nodes. The control plane
facilitates activities such as scheduling, provisioning and scaling instances of
containers. When the containerised service requires more resources on the
host infrastructure, such as CPU and RAM, orchestration spins up more
containers across multiple hosts to meet this demand; when demand drops, it
terminates containers to free up the host resources, reducing costs. There are
many open source and vendor orchestration tools available, such as Docker
Swarm (a native clustering engine for Docker) and Kubernetes (K8s), which
has become the main player in container orchestration. HashiCorp Nomad
and Apache Mesos(phere) also have a small share of the market (at time of
writing), and there are cloud-native versions such as Amazon Web Services
(AWS), Elastic Container Services (ECS), Google Cloud Kubernetes Engine
and Azure Container Instances.
Designing a secure orchestration architecture is important. A rogue user
taking control of your clusters could cause a lot of damage to your
organisation, so you need to build in protection from the start. Unfortunately,
some of the tools – particularly older versions – are not secure by default, so
familiarise your engineers with the inherent weaknesses of the orchestration
tools they are using and mitigate against them accordingly. Orchestration is
managed either through an API or through a dashboard. In both cases,
authenticated users must be authorised to perform the necessary tasks on the
cluster. Without this control, anonymous users would have full access to the
cluster, giving them root access to your organisation’s crown jewels.
Orchestration is powerful and needs careful design and implementation to
protect against malicious activity. There are tools available, including the
Center for Internet Security (CIS) Benchmark checklist, that provide
guidance on how to build a secure container architecture.
Service mesh
Conclusion
By following good design principles in developing application software and
infrastructure software, DevOps teams can implicitly and substantially reduce
the risk of introducing vulnerabilities into the products they develop and
support. Building on security education strategies, engineers should design
products using principles that have been established within the software
development industry over many years.
In this chapter, I explained the importance of a secure-by-design strategy
and then moved on to the practice of threat modelling, which allows
engineers to assess risks when designing a feature within the value stream. I
then explained the common weaknesses associated with poor application
design and the importance of being able to identify these weaknesses within
your organisation’s software. I then went on to describe a number of critical
design patterns that can help development engineers and operations engineers
produce high-quality applications and infrastructure. In the next chapter, I
introduce the third layer, which builds on the first two and allows teams to
test that products have been developed securely.
SIX
Having put in place the first two layers, I move on to the third and final layer
of the security foundation for DevOps. In this chapter, I introduce the concept
of security automated testing. I start by explaining the importance of this
layer before describing the security test pyramid, which is based on an idea
that has already gained traction in Agile software development. I present
various application security testing tools, explaining the different concepts
behind them, and I explain why you should not implicitly trust all the code
your engineers use and how you can validate the use of third-party
components. I touch upon a number of ways to integrate test automation of
infrastructure code before explaining the purpose of non-automated security
testing and why it is important to include it within DevOps practices. Finally,
I explore alerting and monitoring and managing vulnerabilities within a
DevOps framework.
There are also different types of security testing, ranging from simple
assertions that components of the application have been configured correctly
to complex penetration tests which are designed to check whether any
vulnerabilities have been introduced across the entire platform. With so many
tests required, it is important to fully automate as many of them as possible. It
is also essential to provide feedback from testing early in the delivery
lifecycle when it is more cost efficient to identify and fix issues. Feedback
should also be accurate and easy to consume so engineers know what issues
to fix and how to fix them as well as eliminate false positives that can waste
valuable engineering time to validate.
Some vulnerabilities within an application can be discovered implicitly
through various forms of functional and non-functional testing. For example,
validating whether a password format meets a specific criterion is normally a
test case within a functional test suite, and performance testing can identify
potential performance issues that may lead to a denial of service attack if
exploited. But these tests are not specifically looking for security defects and
are not comprehensive enough to give infosec confidence that an application
or service has been fully tested for security vulnerabilities. Security testing is
a specialist area with its own set of tools and practices designed to expose
these vulnerabilities.
There is a trade-off between the accuracy of manual security testing and the
speed and coverage of automated testing. Cost and efficiency should govern
how you incorporate manual testing and automated testing. Manual security
testing is better suited to finding outlier defects, while automated testing
provides greater coverage to identify common weaknesses. Traditionally,
projects rely on a round of manual security testing when the project is close
to going live. The cost of finding defects this late in the software delivery
lifecycle is high as it often requires delays to the product delivery to
remediate any high-risk vulnerabilities – or, worse, the project goes live with
known defects that could not be fixed in time. On the other hand, DevOps
product development does not have the concept of a final project delivery; it
is based on a continuous evolution of a product. In this scenario, DevOps
builds on the Agile practices in which automated testing is carried out on a
continuous basis during the delivery lifecycle. As we shall see, manual tests
are still relevant in the DevOps way of working, but more emphasis is given
to automated security testing.
At the lowest level of the security test pyramid are unit tests and
static code analysis tests. These allow engineers to test their code as
they write it and fix problems within their IDE or when they commit
code to the source code management tool.
The middle level consists of several tools that work across
components such as software composition analysis (SCA), container
image scanning, network scanning and instrumentation tools. These
tools require integration between an application’s services and
components, such as databases and APIs.
At the top of the pyramid are dynamic end-to-end test automation
tools that perform exploratory testing on complete customer
journeys.
Sitting above the pyramid we find a ‘cloud’ of testing practices that are not
integrated into the CI/CD pipeline, such as manual penetration testing and
bug bounty programmes. We also find more invasive manual processes such
as code reviews.
The objective is not to flatten the pyramid but to maintain its structure by
integrating testing practices across the delivery value stream. Unit testing and
static code analysis cannot identify potential weaknesses at the integration
points of the various components, so service tests and UI-driven tests are
essential for detecting vulnerabilities across boundaries. Running a full
penetration test involving many different components to locate easy-to-detect
vulnerabilities is wasteful in terms of time and cost: you would expect to
identify these vulnerabilities using tools further down the pyramid. An
efficient and effective testing strategy involves minimising costs while
maximising the ability to discover weaknesses in your products.
One of the core values of continuous delivery is the incorporation of fast
feedback loops; therefore, automate tests as much as possible and make their
results immediately available to the engineers who need to act on the test
outputs. If engineers are unable to run tests and see their results for several
hours after making the code changes, failed tests will take a long time to
resolve, slowing down the delivery pipeline.
Test duplication should also be avoided; if you are testing for a condition
lower in the pyramid, there is no need to replicate the test further up. If a test
fails at the higher level but there is no test at the lower level, write the lower-
level test (such as a unit test); once it has been validated, you can safely
remove the higher-level test from the test suite. It is preferable to push the
security tests as far down the test pyramid as you can where the costs are
lower.
Application security testing
An application is the gateway between the customer and the core business
function. The customer uses an application to access services or purchase
products that the business offers, so it provides the greatest security risk for
the business and its customers. Hackers exploit vulnerabilities in the
application to target an organisation’s commercial assets or its valued
customers. To eliminate these risks, a company could interact with its
customers through a traditional bricks-and-mortar exchange, in which the
customer visits a physical site to purchase goods or access resources. This
type of exchange is not a viable option in the digital age. People want instant
access to shops, banks and services via the internet; the high street of today
reflects this changing attitude as retail outlets lay empty and banks become
trendy cafes and wine bars. In the world of traditional bricks-and-mortar
commerce, security means that when the stores are closed assets are kept in
safes overnight, shop fronts are shuttered and locked, and intruder alarms are
activated. In the world of online commerce, security is more complex and we
have seen how critical it is to develop applications with security from the
outset. But how do you know that your security controls are doing what they
are meant to do? Once you have designed secure systems, you need to test
them, and, in DevOps, this means automated security testing. There are
several options available to your teams to integrate automated security testing
into your value streams.
Unlike SAST, dynamic application security testing (DAST) does not have
access to the source code. It is a form of black box testing that attempts to
detect vulnerabilities by performing certain types of attacks against a running
application, usually a web application. The tests are designed to perform
common fuzz testing (also known as fuzzing) techniques or brute-force
attacks. Fuzzing is the process of injecting various types of malformed strings
into a website in an attempt to make the application perform an unexpected
and potentially harmful action. Although DAST is a common manual testing
technique, several vendors and open source projects have attempted to
automate the process. These automated DAST tools are integrated into the
deployment pipeline to test running applications in a pre-production
environment. By recording functional test scripts, using tools like Selenium
to automate the behaviour of a user, the DAST tool can replay the resulting
scripts multiple times using different predefined malformed payloads, such as
SQL Injection and Cross Site Scripting (XSS). There are some potential
drawbacks, though, depending on how test environments are set up. For
example, well-designed testing environments mimic production enforcing the
use of a random, non-repeating value called a nonce to prevent replay attacks;
this would hinder the DAST tool’s ability to run multiple payloads using the
same nonce. Your DAST tool needs to be able to work with this particular
application feature rather than requiring DevOps engineers to turn this feature
off in the target application to allow testing to progress.
DAST’s effectiveness is dependent on the amount of interaction between
the web client and other services; more interactions normally results in lower
code coverage. For example, websites feeding dynamic content to the user
based on specific data inputs may limit the effectiveness of DAST; to counter
this, your test engineers could write scripts that use different values to cover
more use cases, although the permutations could be too high to provide
comprehensive coverage.
Because DAST replicates real attacks – which, if successful, prove the
exploitability of a vulnerability within the application – the number of false
positives is much lower than with SAST. This means engineers can focus on
fixing genuine vulnerabilities rather than spending time on validating them.
Configuring DAST requires advanced security knowledge to set the tests up
correctly based on the potential attack surface of the target application. It is
worth considering inviting experienced penetration testers into the DevOps
team to help configure these tools, imparting their knowledge to the team
members in the process.
Many DAST tools work across multiple languages and frameworks,
providing greater coverage of the application’s footprint compared to SAST
tools. But this comes at a cost: it is often difficult to pinpoint exactly where to
apply a fix within the source code when a vulnerability has been identified.
DevOps engineers need a deep understanding of the application source code
as well as advanced security knowledge to fix the defects. For DAST to be
effective in a DevOps value stream, the layers of DevOps security discussed
in the previous two chapters of this book must be in place. Applying DAST
without laying the foundations first means that the DevOps team is dependent
on central security teams to provide ongoing support in maintaining DAST
and interpreting their results. DAST use illustrates my point that educating
DevOps engineers improves flow by allowing them to work independently of
dedicated infosec teams.
Stuart Gunter highly rates DAST as an automated testing tool. When used
appropriately, its low false positive output and proximity to the actions of
manual penetration testing can produce excellent results. However, he does
caution that engineers must be capable of configuring the dynamic testing
tool for the most accurate outcomes. They also need to integrate it into an
application during runtime, which makes it more difficult to integrate into the
IDE; it is therefore better suited to the CI/CD pipeline, in which runtime
analysis can be carried out.
Unit testing
Unit testing is a low-level testing framework that tests a small unit of
software to assert that its functionality is working as intended. Unit tests are
normally written by developers using their normal programming language.
Although software unit testing has been around for many decades, it surged
in popularity following the publication of the Agile Manifesto. Unit testing
became a cornerstone of the Agile movement for upholding its core value of
‘working software over comprehensive documentation’. One of the
signatories of the manifesto, Kent Beck, was a ‘big fan of automated testing
at the heart of software development’ and built the first version of JUnit in
1997 specifically for the Java language. Since then, the xUnit framework has
been extended to support many common development languages. xUnit tests
allow developers to write, organise and run unit tests to validate the output of
a function against expected values. Kent Beck is also credited with creating
the eXtreme Programming (XP) methodology, which expanded the use of
unit tests through the invention of test-driven development (TDD). TDD
consists of three simple steps:
1. Write a test for the functionality you want to write. The test will fail
as there is no functional code to test at this point.
2. Write functional code until the test passes.
3. Confidently refactor the code to make it well structured.
As engineers cycle through these steps, they build an application that has
functionality supported by a full suite of unit tests. When developers change
features, they edit the unit tests first to reflect the new functionality before
writing the functional code. Because each unit test provides a use case for the
feature being tested, it implicitly documents the underlying application or
service. Additionally, code that has been developed with unit tests is often
cleaner and better designed than other code; this is because developers, in
writing the absolute minimum to pass a test, are forced into adopting secure-
by-design principles.
Security engineers or security champions should also be involved in this
process by helping the developers write unit tests that assess the security of
the application or service. They could write unit tests to check that functions
with string parameters validate the input for injection attacks, or they may
produce unit tests that ensure secrets are encrypted correctly. Unit tests can
also be used to validate defects that other types of testing used by the DevOps
engineers have identified; this involves the developer writing a unit test that
replicates the security vulnerability and refactors the functional code until the
unit test passes. This increases the chance that the security defect is detected
earlier in the lifecycle than during DAST and IAST validation, and it reduces
the number of false positives normally associated with SAST tools.
Not only is unit testing integrated into the IDE, it also plays an important
role within the CI/CD pipeline. Unit tests are run whenever a build is
triggered, usually when a developer checks in source code or when the build
is scheduled. When unit tests fail, causing the build to fail, developers are
unable to check in new code until the build is fixed, and, ideally, the DevOps
team works as a unit to fix the build.
DevOps engineers must fully commit to writing a comprehensive suite of
unit tests to reap their full benefit. Teams that work under pressure often
remove failing unit tests or do not write them at all in order to maintain
successful builds. This is a false economy because if a failed unit test covers
a security defect, the resulting vulnerability will become a bigger problem
when it is promoted to a live system.
Your organisation’s DevOps team may be supporting older products that
have limited or no unit test coverage. Particularly if your company is
transitioning from project-based delivery to product-based, there is a
tendency to try to retrofit tests into the software delivery lifecycle. I believe
this is not ideal. Older applications have likely been poorly designed and
developed, making it difficult to incorporate unit tests into the value stream. I
recommend that software engineers only write unit tests for features that they
are currently working on, rather than writing unit tests systematically to
increase code coverage. Although the initial number of tests will be small,
over time more unit tests will be written as more of the legacy code is
changed, providing greater code coverage. A side benefit of this process is
the steady improvement in the quality and security of the legacy product.
Unit tests are the cheapest option and provide the greatest accuracy, but
only when your organisation is committed to a strategy of TDD. You may
consider writing unit tests an overhead, yet they provide the most cost-
effective way of automating the testing of functional and non-functional
security features. Unit tests, combined with SAST, DAST and IAST provide
powerful lines of defence against simple security weaknesses.
Network scanning
All software is deployed into an integrated network of computers. From
desktop computers to mainframe servers, and from routers to printers, every
piece of hardware is connected to other hardware either directly or indirectly.
This integration is what makes life so easy for us. Not only can we use the
internet to do our shopping, banking and research, we can also use it to adjust
the heating and lighting in our homes or answer the doorbell, even when we
are miles away. Within your organisation, there are plenty of interconnected
devices, from laptops and routers to printers and smart card readers.
Connectivity can be physical (using cables to chain components together) or
wireless (such as Wi-Fi routers or Bluetooth).
Within this interconnected super-highway, in order for messages to be
routed correctly, each device uses a system address known as an IP address,
which is a unique identifier within a network that allows these devices to
communicate with each other. The most common and oldest IP in use today
is IPv4, which is a 32-bit address divided into four octets of 8 bits, each
represented as a number from 0 to 255 and separated by a dot (eg
198.51.100.34). Due to the huge number of devices now connected to the
internet and within private networks, and the limitation of the available IPv4
address range (approximately four billion), a new IP version is available. The
new IPv6 is made up of eight segments of 4 hexadecimal digits, each
separated by a colon (eg c689:a275:99ef:ce0f:8f73:6438:e19f:61eb).
There are also 65,536 TCP (transmission control protocol) and UDP (user
datagram protocol) ports for each IP address, allowing multiple services and
applications to communicate across networks using a common network
protocol. With so many IP addresses and network ports, the risk of a rogue
application exfiltrating data to a specific port and IP address can be
significant if left unchecked. This is where network scanning comes into
play. System administrators use tools that scan networks, such as the free and
open source Nmap, to determine the availability of hosts on the network, the
types of services offered by the hosts, and the OSs that are running. The
scanning tools can also target specific firewall rules that may be in place on
the network.
Network scanning allows system administrators to maintain an inventory of
their ecosystem; it also allows hackers to build up knowledge of a system to
determine attack vectors they can use. This makes network mapping essential
for cybersecurity to identify potential ‘holes’ in the perimeter defences that
may allow an attacker in. Within a cloud platform – governed by shared
responsibility contracts between cloud providers and consumers – the
infrastructure (including the physical network) is the responsibility of the
cloud provider. This means that the cloud provider is responsible for the
hardware infrastructure, including all the IP addresses in its remit. The
consumer is responsible for securing the network connectivity within the
network instance allocated by the cloud provider, such as AWS VPCs (virtual
private clouds), Google VPCs and Azure VMs; however, if your teams are
deploying to an on-premise infrastructure the security of the whole network is
your organisation’s responsibility.
Network scanning is not a process that sits easily within a CI/CD pipeline.
Unfortunately, if your DevOps engineers scan the network every time they
check in code, or when the service or product is deployed, the network is
likely to start underperforming. If network scanning is to be integrated into
DevOps value streams, it is more beneficial to schedule scans at regular
intervals such as daily or weekly and use feedback loops to create backlog
tickets to investigate and fix any anomalies. Infrastructure as code, by
contrast, allows engineers to create a network topology using scripts such as
Terraform and Ansible. As with application code, infrastructure code can be
scanned using static analysis tools that alert engineers when potential
vulnerabilities are present. These tools are not as mature as their application
security scanning counterparts, but your engineers should be able to research
and experiment with a number of them to integrate into the CI/CD pipeline.
Penetration testing
Vulnerability management
Managing vulnerabilities is a critical process within your organisation.
Automated and manual testing will identify a number of security defects and
each one must be carefully recorded, rated and prioritised so that it can be
resolved according to your company’s cybersecurity policies. There may also
be regulatory requirements that the vulnerability management system must
meet. Let us explore how DevOps and cybersecurity can work together to
manage security defects.
Vulnerability database
Whether vulnerabilities are discovered through manual penetration testing,
automated security testing, code reviews or even by bug bounty hunters, they
must be recorded in a system that can be accessed by the engineers who can
fix the issues. Some traditional vulnerability management systems are
managed by a central cybersecurity department who maintain the
vulnerability data store under lock and key at all times. Reports of the
vulnerabilities are generated when they are discovered, and the reports are
sent to the product owners or project managers responsible for fixing them.
These reports are likely to be PDF documents, spreadsheets or paper copies.
In many cases, the reports are produced many weeks after the code was
written and, in some cases, after the project team has been disbanded. If
(rather than when) an issue is fixed, the engineers responsible for developing
and testing the fix have no direct access to the vulnerability database to
update it. Instead, they have to contact the central cybersecurity team to
update the status of the vulnerability on their behalf, or, in many cases, the fix
is not reported back to the central cybersecurity team at all. The updated
application remains unchecked until another round of testing is scheduled.
Sometimes, the vulnerability remains in production with potentially
disastrous consequences. In the meantime, if another bunch of issues is
introduced to the application the whole cycle is repeated.
Unfortunately, the model I have just described is probably familiar to you,
especially if you have experience of working in large organisations. These
practices are in conflict with DevOps ways of working which rely on fast
feedback mechanisms, continuous testing, and continuous integration and
deployment. The engineering team needs access to the vulnerability database
managed by the central cybersecurity team so they can assess, prioritise and
assign each vulnerability to an engineer. Engineers must also update the
vulnerability database with evidence that the defect has been fixed, but often
they have limited access to do this and rely on convoluted feedback
mechanisms involving clumsy email communications to have the
vulnerability database updated for them. This is a bottleneck that hinders the
flow of work in a DevOps team, and DevOps engineers and cybersecurity
teams become disjointed: DevOps engineers do not report fixing
vulnerabilities to cybersecurity teams and even avoid notifying the security
departments when they discover a vulnerability. Instead, they manage their
vulnerabilities using their own defect tracking systems independently of those
used by central cybersecurity teams. In the meantime, the security
departments erroneously believe their database is the single source of truth of
the organisation’s security risks.
To overcome this problem, DevOps engineers must work closely with
cybersecurity engineers to define the processes for managing security defects,
whether they are discovered by automated or manual testing. This process
must completely satisfy the requirements of the groups involved. This means
it needs to incorporate fast feedback loops so engineers can fix the issues as
quickly as possible, appropriate access rights enabling the various
engineering and security team members to do their jobs while protecting data
from others, and also add reporting mechanisms that provide accurate views
on the security status of your organisation. Ultimately, the vulnerability
management system must provide the best outcomes for your customers, who
expect your products to be secure and meet the regulatory requirements of
your local jurisdictions.
The security of a vulnerability management system is critical. Each defect
documents the vulnerability with detail to allow engineers to locate the defect
in the application or service, know the state of the application when the defect
was detected (that is, the specific data used) and the sequence of events that
led to the defect being found. In other words, details of security defects that
have yet to be fixed are playbooks that hackers can use to locate potential
weaknesses and exploit them. Therefore, access to the vulnerability database
must be restricted to the relevant groups and carefully audited for unusual
activity.
Vulnerability reports
Vulnerability management systems must be transparent; it must be possible
to generate meaningful reports from the vulnerability data store as well as
maintain a live status of current vulnerabilities. The key metrics that should
be tracked are:
Conclusion
In this chapter, I have described the final layer of DevSecOps, which
incorporates security test automation into the value stream. There are many
tools available to integrate this functionality into the delivery lifecycle, each
with its own strengths and weaknesses. Using the security test pyramid as a
guide, your engineers have the ability to choose the tools that are more suited
to the technologies and frameworks they use, have the greatest accuracy and
provide the best outcomes. Unfortunately, there is no silver bullet, so you are
advised not to choose a single tool for your automated security solution. I
prefer a combination of several tools, such as SAST, DAST or IAST, and
SCA for applications security testing, but the decision ultimately resides
within your DevOps engineering community with the support of the
cybersecurity teams. Some security testing technologies (such as AST and
SCA) are more mature than others (such as IaC and container image testing).
Your security policy should reflect the possibility of a changing landscape to
provide the best automation tools for your organisation.
In this chapter, I also highlighted the need for manual security testing
within DevOps, either through scheduled pen testing or via bug bounty
programmes. The key to their success is the integration with your DevOps
practices to provide fast feedback loops and continuous improvement that
ultimately turns manual security testing into validation that your automated
processes are effective.
I also showed how to apply monitoring and alerting tools to your
automated test strategy. These technologies can detect and report on unusual
behaviour indicative of an attempt by hackers to exploit a vulnerability in
your production systems. This feedback loop can be integrated into your
value stream to provide greater vigilance against security defects.
Finally, I described how security vulnerabilities are managed to foster a
culture of reducing them rather than one of recording them. Together with
education and good design principles, this third layer completes the core
foundation of DevSecOps.
SEVEN
Now that I have introduced you to the three layers of DevSecOps, the next
step is to build the security foundations of DevSecOps. In this chapter, I
explain how to increase the maturity of your DevOps practices to transition
your organisation into a fully functional DevSecOps culture. I start with the
important task of reducing your technical debt before moving on to how to
implement the three layers, starting with education, then secure by design,
and finishing with security test automation. This chapter describes how to
measure the success of DevSecOps within your organisation.
The three layers of DevSecOps: laying the foundation for secure DevOps
Experimentation
Test automation sounds simple to implement, but it is not as easy as you may
think. I have seen many instances where security teams have acquired a test
automation tool and thrown it to the operations engineers to integrate into the
pipeline, while developers are told to start scanning their code for
vulnerabilities. This approach is common, but ultimately it does not work.
Organisations must adopt security test automation in a considered way. The
first step is to invest time in understanding what each tool does and whether it
is appropriate for your organisation. For example, does it support the
languages and development frameworks the application engineers use? Stuart
Gunter says, ‘Organisations do not invest enough in assessing testing tools.
They need to understand how they work by using them manually first in
order to determine the best configuration, before applying it to the
automation pipeline.’ Operations engineers must resist the temptation to
immediately integrate the tools into the pipeline without understanding their
value to the security testing process first.
Using lean methodologies to experiment with different product features is a
key benefit of DevOps. Teams can test hypotheses about their customers and
products by developing experimental features that can be quickly rolled out
to a small customer base in order to learn how customers interact with the
new feature. If the feature is considered a success, it is refined and rolled out
to the other customers; if it is a failure, it is simply removed from the
product’s offerings. This approach can also be applied to choosing the correct
security test automation tools for your organisation. Thus, your engineers
should run small experiments with the various security test automation
products to see which ones will offer the greatest benefits to your
organisation. To start with, engineers should run manual scans using these
tools and address the outputs of the scans within their regular daily activities.
If running the manual scans gives your DevOps engineers the level of
confidence that the tool is suitable for your organisation, you can make the
investment to integrate the tools within the CI/CD pipeline.
Feedback loops
Feedback from manual testers and bug bounty hunters tends to be in report
format, and these static documents can be interpreted out of context. For
example, a critical issue discovered by a penetration tester may not factor in
other controls that mitigate the risk of the vulnerability, making it less likely
to be discovered or have a lower impact on the business than indicated.
Conversely, a low-rated issue may be treated as a low priority because the
issue rating is taken at face value, but the impact on the business if the issue
is exploited could be significantly higher. In both scenarios, the rating of the
issue must be contextualised, documented and prioritised accordingly.
Qualitative data is difficult to measure, and this is certainly the case for
understanding the level of knowledge and skill within your engineering team.
Traditionally, managers maintain a skills matrix that indicates each
engineer’s capability scores against a particular skill. Often the score is
recorded in years or in a scale based on each developer’s subjective self-
assessment percentage rating. These matrices are usually unreliable and
rarely updated, and I would not recommend scoring your team’s skill level
this way. You need to assess the skills as objectively as possible using
quantifiable data, and there is greater benefit in assessing groups or teams
rather than individuals. Collective knowledge is more important than
individual knowledge, so you should explore options to capture data that
implicitly measures the skills for whole teams. Data showing that a particular
team is prone to writing code that contains a particular type of security
vulnerability indicates that the team’s understanding of that issue is worth
exploring further. The assumption being made is that the code is vulnerable
due to a weakness in the collective knowledge of the engineers in the team.
To avoid jumping to the wrong conclusions, it is worth recording how often
the team makes the same coding error rather than assuming that the first
instance of the vulnerability is the result of a lack of knowledge or skill.
Mistakes can be made, so it is important to identify consistent weaknesses
over time rather than just a one-off anomaly.
Creating regular tournaments using training gamification software as
discussed in Chapter 4 can also offer insight into engineers’ capability.
Running competitions regularly can identify potential weaknesses within a
team and provide information for focused learning as part of the continuous
improvement process.
Visualising the weaknesses within your DevOps capability is important and
provides valuable information to help establish the goals of an education
programme. You can visualise weaknesses by creating radar charts where
each spoke represents a vulnerability type (perhaps based on the OWASP
Top Ten lists), and the magnitude of each is determined by the frequency
with which they appear in testing. When you plot these charts, you start to
see where you may have strengths and weaknesses.
Automated testing gives engineers a fast feedback loop for discovering and
fixing security defects. Each time automated security testing fails a build, it
logs the cause of the build failure. By analysing this data over time, you can
identify trends to determine which types of defects engineers are making
most regularly, allowing you to choose which vulnerabilities to focus on
during training. I will discuss measuring automated testing later in this
chapter.
Be wary of using learning metrics during individual performance reviews.
The motivation for collecting this data is to find gaps in the collective
knowledge and advance the group skills that lead to the best outcomes for
customers. When collective knowledge is directly linked to positive customer
outcomes, individuals within the teams will be motivated to acquire the skills
they need to provide the best outcomes. You can thus create a culture of
learning by empowering teams to educate themselves.
This is a more useful indicator than looking exclusively at the total number of
false positives recorded. The aim is to configure the tools to minimise the
number of false positives in the result set without reducing the number of true
positives. Monitoring the false discovery rate will give early indications on
whether the number of true positives is affected by overly aggressive
configuration of the tools. The target is to reduce the false discovery rate to 0
without reducing the number of true positives.
Another important value is the number of false negative results not reported
by the automated testing tools. These indicate that the testing tool has failed
to recognise a genuine vulnerability within the code. This metric is more
difficult to determine as it is inherently an unknown value; the tool cannot
report on what it cannot find, so a heuristic approach is required. Because
automated testing tools have different strengths, it is possible to indirectly
observe the number of false negatives (and false positives) each tool records
by using more than one product within the delivery pipeline. Tool A will
identify genuine vulnerabilities that Tool B misses, and vice versa.
Once you ascertain the false negative value for each tool for a specific
codebase, you can measure the sensitivity of the various automated testing
tools. Calculating the sensitivity is based on the correlation between the
number of true positives and false negatives. The more vulnerabilities the
tool misses, the less sensitive the tool is. This is represented by the following
formula:
sensitivity = number of true positives
(tp)/(number of true positives (tp)
+ number of false negatives (fn))
Over time, engineers need to configure their testing tools to reduce the
number of false negative results without negatively affecting the number of
true positive results. The closer to 1 the sensitivity value, the more accurate
the tool is in capturing vulnerabilities within the codebase.
These metrics provide an ongoing assessment of the value the tools bring to
delivery teams, which can be factored into the impact analysis when
considering the risks of using specific tools. Although it is important to
identify vulnerabilities within your organisation’s products and protect your
customers’ data by integrating security controls, there are valid reasons to
choose alternative measures. For example, if the cost of integrating security
tools is higher than the impact of a vulnerability within a product or service
being exploited, the decision to implement less expensive tools is reasonable.
In all cases, this decision must be based on evidence from the metrics
available to you and not just on assumptions.
Conclusion
In this chapter, I have described the steps to build the layers of DevSecOps. I
started by describing technical debt and explaining that this can be a
hindrance to continuous improvement as all your efforts are focused on
workarounds and spiralling into perpetual inefficiency. By reducing your
technical debt and tackling open vulnerabilities, poorly designed architecture
and code, you can start to mature your DevSecOps practices with confidence.
We then explored how to integrate an education programme, how to instil
the need for designing for security, and the efficient adoption of test
automation practices, followed by a guide on how to measure the three layers
within your organisation so that you gain the most from them. Finally, I
briefly tied all the layers back to the five ideals by explaining that security in
DevOps starts with your people.
EIGHT
Summary
This book has introduced you to an approach for adopting DevSecOps within
your organisation. In it, I presented three layers that form the foundation of
DevSecOps. No matter how far down the DevOps journey you are, you can
apply the principles I outlined. Each layer builds on the previous one to form
a solid foundation of security principles that support the DevOps philosophy.
I started this journey talking about the bedrock of your DevSecOps platform,
which is security education. The collective knowledge of your DevOps teams
must incorporate the skills required to build secure applications and their
supporting infrastructure. Without the necessary understanding of the threats
their systems face, your DevOps engineers are already facing a losing battle
against the malicious actors who want to steal your organisation’s data and
disrupt services for their own gain.
There are numerous learning methodologies that offer different benefits
based on personal preferences, existing company culture and budget. The
most effective form of education is one in which individuals are able to adapt
their learning according to the work they are doing and practise their new
skills, while the worst methods are those in which employees are sent off to
complete a course on a topic that may not be perceived as relevant to their
day job. Your organisation should look to establish a culture of learning,
where individuals are encouraged to openly share ideas, help their peers and
learn from incidents without any fear of repercussions.
Consider filling empty walls with posters that present easy-to-read details
of the most common security weaknesses, buy books and subscribe to online
resources, giving your DevOps engineers free access to them at any time.
Give your teams the freedom to experiment and learn from their experiences;
give them space and time to continue their security education by letting them
have the chance to attend events that interest them and supporting local
forums where your staff can share ideas with their peers. Make learning fun
by setting up tournaments or gamifying their workloads.
Ultimately, knowledge is power, which translates into a working
environment where key decisions are based on the collective knowledge of
your teams and not on the seniority of the decision maker. By establishing a
culture of security education, you reduce the risk of entropy by preventing the
slow haemorrhaging of security knowledge and skills from your organisation.
Once you have developed a sustainable security education programme, the
next level is to apply that knowledge to develop applications and
infrastructure in which security is at the heart of every decision made by
everyone involved in the value stream. Your DevOps teams should have the
freedom to design, develop and deploy security features that protect the
interests of your customers and your employees. This means they should
always endeavour to write clean code that is easy to maintain, less likely to
contain defects and is built within a robust architecture. The infrastructure
that supports the development of your applications, as well as the hosting of
your products, must have security at its core, from access controls based on
least privilege to controls that protect the data as it passes through the
ecosystem. Security is best served by simplicity, so make the design of the
applications and services less complex. You should promote the practice of
incremental changes and small work packages that are easier to design and
code, rather than demand overly complex deliverables that are difficult to test
and integrate.
Finally, you must integrate automated security testing into the DevOps
workload. These tools must be fit for purpose and effective. Their goal is to
assert the first two layers of DevSecOps by validating that your engineers
know how to secure their applications and infrastructure and have adopted
good security design principles throughout. There are many forms of security
testing, so you should create an environment that empowers your engineers to
choose the products that provide the best outcomes. There are many factors
involved in this decision, from the technologies and frameworks your teams
use to the accuracy and effectiveness of the testing tools. This is not a
decision that should be made centrally by a security department but
collaboratively between security subject matter experts and the DevOps
engineers. Once you have adopted these tools, engineers should continue to
evaluate their effectiveness at identifying security issues so that they can
iteratively improve their performance.
Through security test automation within the continuous integration
pipeline, DevOps engineers can deliver features at speed with minimal
security risk. The feedback loops from automated testing allow engineers to
identify and fix features before they occur in production. When combined
with an effective education policy and good design principles, security test
automation enhances continuous learning through these feedback loops and
provides an environment where security is at the heart of software delivery
without negatively impacting flow and customer outcomes.
Continuously monitoring your three DevSecOps layers gives you the
opportunity to hone the skills your DevOps engineers need as well as
improve the quality of your products. Ultimately, this adds value to your
bottom line by giving your customers the confidence to return to your
applications and services. With security education, security design principles
and automated security testing in place, you minimise the risks of pushing
defective code to production. Equally, if your engineers identify
vulnerabilities in production, they have the capability to fix them cleanly and
efficiently to reduce the impact on your customers.
You may be wondering where you start in laying down this DevSecOps
foundation. First of all, you need to define what DevSecOps looks like in
your organisation. You also need to decide how your teams begin to apply
the layers to gain the most benefit. If you try to develop a comprehensive
education programme before moving on to secure by design, the task may be
too large and too disruptive to be effective; therefore, start small. Identify the
value streams where you can introduce an education programme specific to
their requirements and where you can integrate security as a design feature
from the start. Then look at the tools these value streams should assess based
on the technologies and frameworks they use. Over time, each layer will start
to expand into more value streams until more of the organisation is working
with DevSecOps principles.
As the adoption of DevSecOps practices widens and you realise the
benefits, continue to measure what works and what does not, keeping the
more effective processes and tools while discarding those that are less
effective. Over time, your organisation will have laid a solid foundation for
integrating security and DevOps into Dev . . . Sec . . . Ops.
References
I could not have written this book without the help of many individuals who
inspired me, gave me insights and kept me motivated to the end. In particular,
I am grateful to my mentor Rob Kerr, who showed me that writing a book
was within my potential and gave me encouragement throughout the writing
of the book. He also pointed me in the direction of Alison Jones, who helped
me formulate the book and give it structure, for which I am truly thankful.
I am also indebted to Johnathan Haddock, whose feedback on the
manuscript was invaluable to correct a number of inaccuracies that had crept
into the original draft. I was also encouraged by regular feedback from Chris
Wilmott and Seb Ben M’Barek, who gave different perspectives on some of
the topics covered in the manuscript.
During the writing process, I received help from a number of experts who I
consulted on technical matters covered in the book. My gratitude is extended
to Eliza-May Austin, Steve Giguere, Jamel Harris, Stuart Gunter, Matias
Madou, Ray Coulstock, Debasis Das and Chris Rutter.
The drawings in this book were created by the talented Crystal Tamayo,
injecting some visual humour into the prose and for that, I am very grateful.
Thank you to the talented team at Rethink Press, especially to Maya Berger
whose edits made this book so much better, Joe Gregory for translating my
vision into the wonderful cover design, and Kate Latham for managing the
whole publication process and for keeping it on track.
I have been inspired by Michael Man, who has been a big supporter of my
journey in DevSecOps over the many years I have known him. He has given
me opportunities to share ideas presented in this book at his brainchild
community forum, the award-winning DevSecOps London Gathering. Thank
you, Michael.
Finally, I would like to thank my family for their support and, of course,
my lovely partner Caz for encouraging me to reach for the sky!
The Author
[email protected]
https://dynaminet.com
www.linkedin.com/in/glennwilson
@GlennDynaminet