Achieving security in practical systems is a hard task. As it is the case
for other critical system properties (i.e. safety), security should be a concern
through all the phases of software development, starting with the very
early phases of requirements and design, because of the potential impact of
unwanted behaviour. Moreover, it remains a critical concern throughout a
system's life-span, because functionality driven updates or re-engineering of a
system can have an impact on its security. The cost of using formal methods
is clearly justified for critical applications. But in the context of a wider class
of industrial applications answers to two questions are important: What are
the gains and limitations of light-weight formal security guarantees achieved
at different abstraction levels? What are the advantages of those techniques
for reasoning about change?
For the first question, we discuss different detailed modelling techniques,
ranging from UML models to CPU cache modelling at the level of binary
code. To tackle the second question, we discuss results on compositionality
and incremental verification techniques which, besides being useful tools for
verification in general, allow re-utilization of existing verification results in case of changes in the models. We apply these techniques to exemplary security
properties with focus on confidentiality, and pin down security assumptions
and guarantees of information
flow control across levels of abstraction.