In this lesson,
we're going to discuss software composition analysis.
Software composition analysis describes a process
by which software can be analyzed for open-source components
because these open-source components
could contain vulnerabilities in their source code,
and those vulnerabilities will then be assumed
by our applications when we use those components
in our own web apps.
If you or a vendor are going to build a piece of software
that's going to be publicly accessible like a web app,
you need to pay special attention to the risk associated
with those applications.
There's almost no applications these days
that are written completely
by your own developers or vendors.
Instead, most developers are going
to rely on third-party dependencies like library packages,
JavaScript scripts, and CSS files.
The problem with that is that even if your code is written
extremely well from a security standpoint,
if those third-party dependencies
have a security flaw in them,
you just inherited that flaw into your own application too.
All code is going to be subject
to the same types of vulnerabilities,
things like cross-site scripting,
cross-site request forgery, clickjacking, injection flaws,
and many other different types of attacks.
Yes, you can scan and protect your own code
from these attacks,
but if you're pulling in somebody else's library,
you also are going to be pulling in their vulnerabilities.
For this reason, it's important to track
and moderate the common exposures
and common vulnerability databases
for those dependencies and open-source components
that you've included in your applications.
As the saying goes,
"A vulnerability in a third-party dependency
becomes a vulnerability in your own application."
Nowhere was this more true than the case of Equifax
back in 2017.
When they suffered a data breach,
they exposed the sensitive data
of over 140 million American consumers.
What was the root cause of that breach?
Well, it was a vulnerability in an open-source framework
that was used by Equifax
when they developed their web application.
The third-party code is actually called Apache Struts,
and it was a popular framework used
to develop Java web applications.
On March 7th of 2017,
a major vulnerability was initially disclosed
as CVE-2017-5638 that affected this popular framework.
By March 9th, just two days later,
the Equifax system administrators were informed
that they needed to patch their systems
because of this vulnerability.
By March 15th, a week later,
they still hadn't patched those applications,
and by this time, it was too late
because attackers had already breached the systems using
this well-documented vulnerability from the CVE.
Remember, whenever you
or your vendors are using third-party dependencies
or open-source components,
you're taking responsibility for the code you wrote
and the code you didn't write
that you imported into your code base too.
Now, to identify what libraries and components are used
in a given piece of software,
even when you didn't write it,
you can perform software composition analysis.
There are many different automated ways of doing this,
including using the OWASP dependency-check tool,
which can scan a given piece of software
to identify any publicly disclosed vulnerabilities
in its project or its libraries.
There's also another helpful OWASP tool known
as the dependency-track tool,
which can provide even deeper insights into the source code
and its libraries and components.
I mentioned the Apache Struts framework
earlier in this video
while I discussed the Equifax breach as an example,
but it's not the only framework used
in software development.
Other common frameworks include Microsoft .NET,
Ruby on Rails, and Ramaze,
which are both used for Ruby programming languages.
Hibernate, which is a Java framework
just like Apache Struts,
and Django, Twisted, and web.py,
which are all used with a Python programming language.
These different frameworks are used
to develop great applications
by making things really simple for your developers.
By using these frameworks,
you can have reusable code that your developers can use
instead of having to develop all the code again
from scratch.
This saves us a lot of time and money during development,
but also, remember, you're inheriting any vulnerabilities
from those frameworks into your own code.
So you need to track and patch your own code
whenever a new vulnerability is discovered
in one of those frameworks.
Another vulnerability in terms of software development
is the use of unsafe functions.
For example, if you're coding something
in the C programming language,
there's many well-documented vulnerabilities
in the standard library.
Things like string copy, memory allocate,
gets, string concatenate, and many others.
To find these types of vulnerabilities,
you need to conduct a static code analysis.
And if you're not the original developer
or have access to the original source code,
it can become very difficult for you
to identify these unsafe functions inside of that code.
Now, there's a couple of other common vulnerabilities
and software that we should talk about,
including poor exception handling,
security misconfigurations,
weak cryptography implementations, information disclosures,
End of Support or End of Life,
code injections or malicious changes, and regression issues.
First, we have poor exception handling.
Poor exception handling occurs when a program is not written
to anticipate problems or errors,
and it doesn't safely manage these issues
in order to leave the application in a controlled state.
This can lead to applications that crash or break
in a way that leaves the system unstable or insecure.
This could then be exploited by a threat actor
to access restricted information
or exploit an unprotected system.
Second, we have security misconfigurations.
Now, security misconfigurations are a general term
that talks about any issue
that's related to poorly implemented
or documented security controls.
For example, if a system uses a set
of default configurations, settings or credentials,
this could be considered a security misconfiguration.
Similarly, if there are unpatched vulnerabilities
or unprotected files,
those could be put
into the security misconfiguration category too.
To prevent security misconfigurations,
all systems should be hardened
and all applications should be built using the best
practices and secure coding techniques.
Third, we have weak cryptography implementations.
Now, weak cryptography implementations occur
when an out-of-date algorithm or cipher is being used
in a modern system.
For example, if you find something that's using DES,
the digital encryption standard these days,
this is going to be considered a weak cryptography
implementation because that encryption came out in the 1970s
and it is really weak and should not be used today.
Similarly, if you're using RC4
to encrypt your data in transit,
this is a weak implementation.
Both DES and RC4 are considered extremely weak ciphers
and should never be used in any modern application.
Similarly, you should never try
to create your own proprietary encryption standard
to protect your systems or applications,
and instead, you should always utilize a well-known
and well-documented encryption standard
because it's more likely to be secure
and resistant to attack.
Fourth, we have information disclosure.
Information disclosure describes the active information
being stolen from an application
or during the communications process
between two applications.
Usually, information disclosure occurs
because data is not being protected
by some kind of encryption scheme
or they're using a weak cipher
or it has a weak encryption key.
If sensitive data is able to be read or processed
by an unauthorized user,
this is a form of information disclosure.
Another form of information disclosure would occur
if you have a data breach or a data leak.
Fifth, we have End of Support or End of Life issues.
Now, End of Life indicates the period of time
that a vendor will no longer sell
or upgrade a particular piece of software or equipment.
End of Support instead refers to the period of time
that the vendor will stop creating new patches or updates
for a particular piece of software or hardware.
For example, Microsoft Windows 7 reaches End of Life
in January, 2015.
At that point, Windows 7 stopped receiving new features
and updates,
and mainstream support for the software was stopped,
but it was still not at its End of Support date,
which occurred five years later in January, 2020.
At that point, Microsoft stopped providing all support,
including any security patches.
So if a vulnerability was found in Windows 7 today,
Microsoft has no obligation to create a security patch
and deploy it to any systems that's still used Windows 7
because that software is fully End of Life
and End of Support.
End of Life and End of Support dates are really important
to consider when you're determining
if your software is vulnerable on your network.
If the End of Life and End of Support date has been reached,
you're going to be unable to get vendor support,
and this leaves you very vulnerable.
Before this happens,
you should identify that date
and have plans in place to upgrade your systems
to a software that is well-supported by the vendor.
Sixth, we have code injections or malicious changes.
Now, a code injection is an exploitation technique
that runs malicious code with identification
of a legitimate process.
Code injection attacks allow the adversary
to exploit an application
and inject their own malicious code
into that running application
in order to perform their attack.
Normally, code injections and malicious changes
are the result of poor data handling
or non-existent input, output validation methods.
This is why it's always important
to ensure your applications provide good input validation
and output validation
in order to protect themselves from code injection attacks.
Seven, we have regression issues.
Regression issues occur
when a change the source code is made,
usually in an attempt to add a new feature
or patch a security vulnerability,
and that change can introduce a new vulnerability
or break some existing functionality.
For example, if I'm going to add a new feature to my website
that allows students to retake their practice exams
that only include questions they missed the first time,
this new code could introduce a bunch of other bugs
or break some existing functionality.
This is because anytime you change something
in your source code, you risk breaking something else.
To prevent this, you need to use regression testing.
Regression testing is focused on validating.
Any change to a piece of software
does not produce an unintended consequence
by testing all of your existing features again,
your functionality and your security
in a very methodical way.
Anytime your source code is accessed or changed,
you should also ensure
that it's subject to change management
and integrity controls
to ensure the quality of your code remains high
and security remains intact.