-: As we move through the seven phases
of the software development lifecycle,
it's important for us not to forget
the fundamentals of good security.
Our developers should always remember
the three tenets of the CIA triad:
confidentiality, integrity, and availability.
Remember, confidentiality ensures that
only authorized users can access the data
being processed by an application.
The most common way of ensuring confidentiality
is to include the use of encryption
to maintain the secrecy of the data being stored.
Integrity is focused on ensuring the data
is not modified or altered without permission.
The two main ways that we do this as developers
is by utilizing hash algorithms
as a method of integrity check for the data
or by using journaling and logging functions
to create audit trail showing the
integrity of the data has not been comprised.
When developers are attempting to ensure availability,
they're focused on ensuring that the data is available
to authorized users when it's needed.
The most common way of doing this is by creating
redundancy in the overall system design,
by ensuring their software code is error-free,
or by ensuring that their software can conduct
error handling appropriately to prevent crashes.
During the testing phase, it's important
to conduct an in-depth code review to ensure
that there are no vulnerabilities
that might affect the confidentiality, integrity,
or availability of the software or the integrated system.
These code reviews are generally performed
by programmers, not by security analysts though.
On the other hand, security analysts
do help during the software development lifecycle
by conducting threat modeling.
Threat modeling helps to prioritize vulnerability
identification and patching throughout the SDLC.
By helping to prioritize the threats,
the security analysts can help with
the identification of applications or systems
that should receive additional protections,
which threats are more likely to affect them,
and which ones have known vulnerabilities that exist.
Based on this, additional effort and funding
can be applied in the most efficient way
to fix the issues before an attack happens
or an attacker can exploit them.
After all, there are a lot of threats out there
and a lot of ways to attack a system
if you want to breach an area of the CIA triad.
To best protect applications, we should ensure
that good security is programmed in
from the beginning, back during the requirements
analysis and implementation phases.
Numerous studies have proven that it's much cheaper
to utilize secure coding practices
and to conduct more thorough testing
before releasing a product than to try
to fix insecure code after releasing the product,
as well as trying to clean up from the mess of an attack.
What secure coding practices
should our programmers use during development?
First, we should ensure that we design our applications
with the concept of least privilege.
Least privilege means that user or processes
should be run using the least amount of access
necessary to perform the given function.
Does your application require
administrative permissions to run?
If so, why?
Developers should always try to use
the lowest permission level
when they're performing a function.
So whenever it's possible, the program should be run
as a user-level person instead of an
administrator or root-level one.
The next practice is to implement defense in depth.
Defense in depth occurs when you layer security controls
to create a more effective and secure application or system
than would be possible if you relied on a single control.
Also, you should never trust user input.
Any input that's received from a user
should always undergo input validation
prior to allowing an application to use it.
Proper input validation can stop
a lot of different types of attack
including SQL injections, buffer overflows, and more.
Next, we want to minimize our attack surface
in our applications and our systems.
This means that we should always reduce
the amount of code used by a program,
we should eliminate unneeded functionality,
and we should also require authentication
prior to running any additional plugins.
Developers should also create secure defaults.
Most of the time, our users are going
to accept the default installation configurations.
This can lead to insecurities in our systems.
Therefore, developers should always ensure
the default installation includes secure configurations
by default and then requires an administrator or a user
to lessen those secure defaults
if they want to remove the security.
Unfortunately though, software is often designed
the exact opposite to this where they have
insecure defaults and then it requires an administrator
or a user to change them to add additional security.
Next, whenever you're deploying your applications,
you should always use code signing to ensure
that the program has not been changed
either inadvertently or maliciously prior
to its delivery to your end users.
By using digital signatures as part of your code signing,
you're enabling the end user to see
that the program was authentic
and it maintains the integrity throughout its lifecycle.
Another key principle that developers should follow
is to ensure their code is developed
so that it will fail securely.
After all, every application is going to fail at some point.
By ensuring that your application is coded
to properly conduct error-free handling exceptions,
they can fail securely instead of crashing
or being exploited by an attacker.
Again, input validation here will go a long way
in helping your programs fail securely
instead of just crashing.
Next, we have fix security issues.
If the vulnerability is identified,
it should quickly be corrected and patched
to remove that vulnerability
from your application or system.
After all, we don't want known vulnerabilities
to remain in our applications or systems
because when they do, this means that vulnerability
can be found by an attacker as well.
Since we know about it,
they're going to be able to find it too.
Finally, developers should only rely
on trusted SDKs and third-party libraries.
What's an SDK?
An SDK is a software development kit
and it allows a programmer to reuse code
from other programmers in order
to save them time and effort.
For example, if you're developing a new Windows application,
there's no reason for you to code your own function
to open a file on the hard drive.
This function exists in almost every program out there.
So, there's a software development toolkit
that provides this function along with many other
file input and output functions.
The same holds true for third-party libraries.
We are reusing somebody else's code
inside your own applications.
Whenever you're utilizing somebody else's code,
you should ensure it comes from a trusted source
to ensure that no malicious code is being added to it.
From my file opening example,
I would want to use the official Windows SDK
or a third-party library and not some random one
that I found on SourceForge or GitHub.