Lessons from Mistakes
One of the easiest things we
can do to enhance security is learn from our mistakes. As we design and build
systems, we can document our decisionsnot only what we decided to do and why,
but also what we decided not to do and why. Then, after the system is up and
running, we can use information about the failures (and how we found and fixed
the underlying faults) to give us a better understanding of what leads to
vulnerabilities and their exploitation.
From this information, we can build checklists
and codify guidelines to help ourselves and others. That is, we do not have to
make the same mistake twice, and we can assist other developers in staying away
from the mistakes we made. The checklists and guidelines can be invaluable,
especially during reviews and inspections, in helping reviewers look for
typical or common mistakes that can lead to security flaws. For instance, a
checklist can remind a designer or programmer to make sure that the system
checks for buffer overflows. Similarly, the guidelines can tell a developer
when data require password protection or some other type of restricted access.
what it is supposed to do.
Unfortunately, results in computer science theory (see [PFL85] for a description) indicate that we
cannot know with certainty that two programs do exactly the same thing. That
is, there can be no general decision procedure which, given any two programs,
determines if the two are equivalent. This difficulty results from the "halting
problem," which states that there is no general technique to determine
whether an arbitrary program will halt when processing an arbitrary input.
In spite of this disappointing general result,
a technique called program verification
can demonstrate formally the "correctness" of certain specific
programs. Program verification involves making initial assertions about the
inputs and then checking to see if the desired output is generated. Each
program statement is translated into a logical description about its
contribution to the logical flow of the program. Finally, the terminal
statement of the program is associated with the desired output. By applying a
logic analyzer, we can prove that the initial assumptions, through the
implications of the program statements, produce the terminal condition. In this
way, we can show that a particular program achieves its goal. Sidebar 3-9 presents the case for appropriate use
of formal proof techniques. We study an example of program verification in Chapter 5.
Correctness proofs depend on
a programmer or logician to translate a program's statements into logical
implications. Just as programming is prone to errors, so also is this
translation.
Deriving the correctness
proof from the initial assertions and the implications of statements is
difficult, and the logical engine to generate proofs runs slowly. The speed of
the engine degrades as the size of the program increases, so proofs of
correctness are even less appropriate for large programs.
The current state of program
verification is less well developed than code production. As a result,
correctness proofs have not been consistently and successfully applied to large
production systems.
Program verification systems
are being improved constantly. Larger programs are being verified in less time
than before. As program verification continues to mature, it may become a more
important control to ensure the security of programs.
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.