In this lesson,
we will learn about software assurance.
Software assurance is the process of ensuring software
is developed and maintained in a way
that consistently meets security and reliability standards.
This protects the software from vulnerabilities
and malicious threats.
Software assurance concepts include
a Software Bill of Materials, or SBoM,
Software Composition Analysis, or SCA,
and formal methods of validating software correctness,
safety, and security.
First, we have a Software Bill of Materials, or SBoM.
An SBoM is like a detailed ingredient list for software.
Just as a food label shows all the ingredients in a product,
an SBoM provides a clear breakdown of every component,
library, and dependency used in a software application.
This level of transparency is important
because it helps developers and users understand
what the software is made of.
Each component in a software bill of materials, or SBoM,
is identified by its name, version,
and a unique identifier, such as a cryptographic hash.
The identifier ensures the integrity of the software
by verifying that no components have been altered.
In addition to listing direct dependencies,
such as libraries and modules explicitly called
or imported by the software,
the SBoM also tracks transitive dependencies.
Transitive dependencies are the components
that those direct dependencies rely on.
For example, if the software directly depends on library A
and library A depends on library B,
then library B is considered a transitive dependency.
Direct and transitive dependencies create
a full dependency graph outlining every element involved
in the software.
This transparency is crucial for developers,
cybersecurity teams, and users alike,
as it provides insight
into any known vulnerabilities associated
with specific versions of libraries or dependencies.
This allows for quick action when a security issue arises.
The software bill of materials also ensures there
are no hidden, outdated,
or insecure components within the application,
significantly improving the software's security posture
and compliance with security standards.
So, imagine you are developing a web application
and you rely on open source libraries like React
for the frontend, Express.js for the backend,
and a MongoDB database.
Your software bill of materials
would list all of these components,
along with the details about their versions
and any dependencies they bring in.
If a security vulnerability is then found
in a specific version of React,
you can quickly identify
that your application uses that version
and take immediate action to update or patch it.
Without a Software Bill of Materials,
quickly identifying this type of issue
would be very time consuming and prone to oversight,
putting your application and your users at risk.
So, by using a software bill of materials,
companies can proactively manage their software security,
making it easier to track down and address issues
before they become a problem.
Second, we have Software Composition Analysis, or SCA.
Now, whenever you or your vendors
use third party dependencies or open source components,
you are taking the responsibility not just
for the code you wrote,
but also for the code you didn't write,
like the libraries and frameworks you import
into your code base.
To identify what libraries
and components are in your software,
even when you didn't write them,
you can perform Software Composition Analysis.
This involves scanning your software
to find all the third party components
and checking them for known vulnerabilities.
Automated tools can make this process easier.
For example, the Open Web Application Security Project,
or OWASP Dependency-Check is a widely used tool
that scans a project and its libraries
to identify any publicly disclosed vulnerabilities.
Another OWASP tool called Dependency-Track
offers even deeper insights by continuously monitoring
and analyzing the security of components within your code,
allowing you to act quickly if a vulnerability is found.
To put this into perspective,
let's consider widely used frameworks like Apache Struts.
Apache Struts did have an unpatched vulnerability,
which played a significant role in the Equifax breach.
The vulnerability CVE-2017-5638
was within Apache Struts 2.
Specifically, the flaw involved improper handling
of file upload requests using
the Jakarta Multipart Parser,
it allowed attacker to execute remote code on the system.
This incident highlights the risks of unpatched software,
but Apache Struts is just one example.
Other common frameworks like Microsoft.NET,
Ruby on Rails, Hibernate for Java,
and Django for Python also help developers
by providing reusable code and simplifying development.
However, by using these frameworks,
organizations also inherit any potential vulnerabilities
that exist in the reused code.
Therefore, when new vulnerabilities are discovered,
it's very important for organizations to track
and patch these issues to maintain software security.
Tools like Software Composition Analysis, or SCA,
can help automate this process,
ensuring that both direct and transitive dependencies
are up to date and secure.
Third and last, we have formal methods of validation.
Formal methods of evaluation and validation
for software assurance use mathematically based techniques
to guarantee that software is free from errors, bugs,
and security vulnerabilities.
These methods go beyond traditional testing
by mathematically proving that the software behaves
as expected under all possible conditions.
This approach is especially important
for systems like aviation, healthcare, or finance,
where even minor failures can have serious consequences.
Model checking is a popular form of validation
that involves creating a model of a system
and rigorously verifying it against predefined rules.
Tools like the Simple Promela Interceptor, or SPIN,
are frequently used in distributed systems
to ensure that every possible state
and transition is explored,
helping to identify issues such as deadlocks
or safety violations that might be overlooked
in standard testing.
Another powerful technique is theorem proving
where tools like C-O-Q, or Coq,
and Isabelle generate formal proofs
to verify the correctness of algorithms
and software components.
For example, Coq has been used
to formally verify cryptographic algorithms,
providing a mathematical guarantee
that these algorithms meet their security requirements.
Abstract interpretation is another validation technique.
Abstract interpretation uses tools like Astree
to analyze the software's behavior
without actually running it.
Astree was famously used in the aerospace industry
to ensure the safety of Airbus flight control software.
Checking for runtime errors like division by zero
or buffer overflows.
The abstract interpretation method helps ensure
that software remains reliable under all conditions.
To simplify our understanding of formal validation methods,
let's consider a traffic light control system.
By using formal methods,
we could model how the traffic lights should change
based on traffic flow,
and then use a tool like the Simple Promela Interpreter
to check every possible scenario.
SPIN could then validate
that no two directions get a green light at the same time,
preventing accidents.
In real-world software,
these methods similarly help developers spot flaws
and potential failures early on
before they cause major issues.
So, remember, software assurance is the process
of making sure that software is built
and maintained to meet high security
and reliability standards.
One important concept in software assurance
is the Software Bill of Materials, or SBoM.
An SBoM provides a detailed breakdown of all components,
libraries, and dependencies used in a software application.
This transparency helps identify any vulnerabilities
in third party software components.
Another key concept is Software Composition Analysis,
or SCA, which involves scanning software
to detect known vulnerabilities in the libraries
and frameworks that are used.
SCA tools include the OWASP Dependency-Check
and the OWASP Dependency-Track.
Finally, formal methods of validation
use mathematical techniques like model checking
and theorem proving to guarantee
that software is free from bugs and vulnerabilities,
ensuring it behaves as expected in all scenarios.
These methods are particularly useful in critical systems
where even small errors can lead to major issues,
like in aviation or finance.