260 Core Software Security
runtime. The architect must also have a strong grasp of the sort of threat
agents who are active against this sort of software. Indeed, she or he must
understand the relevant attack methods in order to build a realistic threat
model. Static analysis tools require considerable expertise, as do most
forms of dynamic testing, from Web vulnerability scanning to input fuzz-
ing. The existing tools are nontrivial to learn and run effectively. Code
review requires an understanding of general security correctness, the
flow and structure of the particular code under review, as well as how the
intended function should be implemented. Your most junior engineer is
probably not the best resource to apply to any of these tasks—at least, not
without significant support from experienced practitioners.
If one can build the right set of questions into the SDL, choosing the
correct set of high-level tasks turns out to be fairly straightforward. This
is true even if executing those tasks is nontrivial. There are dependencies,
process flows of tasks that follow logically out of the answers. Once the
task flow is engaged, the appropriate activities will take place in a more or
less linear fashion.
Making the SDL relevant and obviously appropriate opens the door
for meaningful interactions among the different stakeholders of the SDL.
As has been noted, asking intelligent, busy people to do things about
which they cannot perceive value does not enhance confidence in the
security team. Conversely, a transparent process that is inherently obvious
has the opposite effect. Empowering SDL participants to answer basic
questions about which activities are appropriate for their current project
is inherently trust-building. It remains true that execution of many of
these tasks requires deep technical (and often interpersonal) expertise.
The current state of the art does not simplify many SDL tasks enough
to allow these to be executed by “just anyone,” even when every member
of the development team holds a modicum of technical skill. For most
organizations in which we have participated, architecture assessment or
vulnerability scanning remain expert domains. Because of this state of
affairs, relationships become even more important. Achieving secure soft-
ware requires many people to pull together toward shared goals—which,
obviously, means that non-security participants must understand that
security is a “shared goal.” Hence, we advocate as much transparency as
possible coupled to an SDL implementation that stresses people and rela-
tionships as much as technology. The key determining questions are one
step toward achieving a “people” focus of the SDL in the real world.
Applying the SDL Framework to the Real World 261
The key determining questions will be presented later in the chapter,
in context. First we will examine the heart of every SDL; those activi-
ties that are not dependent on amount of change or type of interface.
Without these core tasks, the SDL lacks its most essential ingredients to
produce code that is written correctly for security and that contains as
few defects as possible: writing secure code, reviewing the code, and then
running the code through static analysis.
As we examine the SDL tasks as they are applied to real-world projects,
this chapter will detail the supporting parts of a software security program
that will foster and grow the required skills to execute the tasks well.
9.1 Build Software Securely
At the heart of secure software development, there are three core activi-
ties. Figure 9.2 delineates the three core activities and their relationship
within both Agile and Waterfall development. Every programmer must
attempt to write safe, defensive, self-protective code. There is no secure
path around the need for coders to understand what must be done in
the language in which they are working. Different languages and different
execution environments demand different emphases. In fact, issues in one
language may not be worth considering in another; one only has to look
at the differences between C/C++ and Java to understand this fact. The
C/C++ language allows the mishandling of memory; in fact it’s very easy
to do something insecure. In contrast, the Java programming language
takes care of all memory handling; programmers need not worry about
the allocation and the de-allocation of memory at all.
Even experts at writing correct, secure code make mistakes. And the
current reality is that there are very few coders who are experts in secu-
rity, much less the security issues of a particular language and runtime.
In addition, it should be remembered that writing software code is as
much an art as it is engineering. While there are correct implementations
and incorrect implementations (engineering), a great deal of creativity is
involved in expressing that correctness. There may be several algorithmic
approaches to a particular problem. There will be many possible expres-
sions of whatever algorithm has been chosen. And this does not take into
account innovation: The programmer may encounter computer problems
that have not yet been attempted; she or he will have to create an entirely
Figure 9.2 Core elements of software security will remain the same regardless of development methodology or the
SDL that you use.
Applying the SDL Framework to the Real World 263
new algorithm or significantly modify a standard. And, even with nam-
ing conventions and other coding standards, programming languages are,
in essence, expressive. That may be one of the motivators for becoming
a programmer: creativity at ones job. But with creativity and innovation
come mistakes. Mistakes are the price we pay for innovation. Not every
idea works; perhaps most fail? One very successful approach is to learn
about a problem by trying to solve it. Such an iterative approach is often
used when building software, but iterative discovery guarantees a certain
level of failure and error. We would posit that defects and vulnerabilities
are a direct result of innovation (although, of course, innovation and cre-
ativity are not the only causes of vulnerabilities).
The software security practitioner is faced with a trade-off between
curtailing innovation and perhaps job satisfaction and delivering code
whose security can be assured. This is where the assurance steps provide
appropriate help. We recommend that at the heart of whatever develop-
ment process is used, include manual code review and static analysis. That
is, give the creative coder considerable help to deliver correct code.
Figure 9.3 visually reinforces the central coding flow: Produce secure
code which is then statically analyzed and manually code-reviewed. This
is the essential “secure” version of “build” in software construction terms,
i.e., the “heart” of a secure development lifecycle. These core tasks lie at the
center of secure software, regardless of the development process being used.
Figure 9.3 The heart of an SDL.
264 Core Software Security
9.1.1 Produce Secure Code
Every program has (at least) two purposes: the one for which it was
written and another for which it wasn’t.
1
If software engineers, those who write software, could produce correct,
error-free code, there would be far less of a software security problem.*
And with only correct software there is no need for all the non-design
related tasks of the SDL. At the risk of stating the obvious, writing correct
code has always been difficult, even without security considerations.
Since the dawn of the software industry, when software engineers adopted
the term “bug,” meaning “software error,” engineers have struggled to
produce code that is correct, both logically and without runtime error.
Inferring from the vast experience of all the software that has been writ-
ten, we can conclude that writing error-free code is very, very difficult.
It’s not impossible, but it remains an expensive ideal rather than a norm.
Realizing the error-prone nature of producing code, software engi-
neers have attempted to find a metric that shows how dependable and
error-free any particular piece of code might be. One measure is the num-
ber of defects, “bugs,” per line of code written. It is generally accepted
that production software contains approximately 1 error per 1000 lines
of code. This is a very general statistic. It is possible to produce software
that has far fewer errors; one need look only at critical space mission or
military software, which often must adhere to much stricter defect limits.
And, of course, poorly written software may have orders of magnitude
more errors than 1 in 1000. Generally, however, there are errors in any
moderately complex piece of code. As far as we can tell today, there is no
way for us to ensure that 100 percent of the software or security errors
will be eliminated before software is released. The best approach is to go
through the required SDL activities (see below, determining questions) to
ensure that most of the errors can be caught and fixed before a product
is deployed or sold. If errors are found after software release, one should
* There would still logical errors, errors of architecture and design omission and com-
mission. Logical errors are not dependent upon correct code. It is quite possible to
insecurely specify, and then code that mistake correctly to the specification. That
is, it is possible to correctly follow the incorrect specification and introduce a logical
vulnerability.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset