-: Finding security flaws.
So when we look at our code,
there's always gonna be some flaws that occur.
This is gonna happen based on programming or syntax errors.
This is gonna happen based on a failure of the logic
that was being used, or the processes.
This can happen because of the way you're handling
your errors, or incorrect integration with other services.
So how do you find all of these security flaws?
Well, you can do a static analysis,
and a static analysis is reviewing the code manually
or with an automated tool.
And it actually has access to the code itself.
The code is not run, that's why it's called static.
It is not being run, it is not being compiled,
it is just analyzed in its raw form.
This is a form of white-box testing,
'cause you know exactly what that program is doing
based on every input, every output,
and exactly how it's coded.
Now this is very time-consuming,
and it can be very expensive,
and you have to be able to look through miles,
and miles, and miles of code, right?
And so static analysis is good when you can do it,
but you're not always gonna have access
to the source code in your testing,
and if you don't have access to the source code,
you can't conduct static analysis.
And that brings us to dynamic analysis,
which is when code is executed
while providing its specific input.
You can use automated tools to do this,
which is the preferred method, or give it manual input.
I'll give you a good example of this.
In one of my security classes,
we have students create a very simple Java program.
And they created the code of the program,
it's about 50 or 100 lines,
and it's gonna take some inputs in,
and it's gonna provide an output and display to the screen.
They'll take in a length and a width
and they'll calculate what the rectangle's area would be
and its perimeter, right?
Very simple program.
Well, instead of me looking at every single line
of their code, that would be a static analysis,
I can do a dynamic analysis.
I run their program,
I input 10 feet and 20 feet as the length and width,
and if I get out that the area is 200 feet,
and that is gonna give me the right answer.
Then I know that they did the program correctly
based on the specific input I gave it, right?
That's a dynamic analysis.
So there's many different ways to do it.
There's five that we're gonna talk about in this lesson.
There's fuzzing, fault injection, mutation testing,
stress testing, also known as load testing,
and security regression testing.
So fuzzing is the first one.
What is fuzzing?
Well, it sends invalid or random data
to an application to test its ability
to handle the unexpected data.
For example, if I'm calculating the length and the width
to give me the area of a rectangle,
I'm not expecting a negative number.
So if I give them a negative number,
is it gonna handle that properly?
Is there an error check that says,
hey, you can't have a negative length.
Length has to be zero or above.
This is usually done using automated tools,
because you wanna be able to test it with very, very large
data sets with all sorts of different combinations.
This is used to detect the input validation
if it's done right, logic errors,
memory leaks, or error handling issues.
Fuzzing is a big concept.
I guarantee you're probably gonna see
at least one question on your exam on fuzzing
where you're providing large sets of random data
to find out if the program is working
or not inside software testing.
Now the next one we have is what's called fault injection.
And this is gonna directly insert faults
into an error program, into a program
to the error handling parts of the program to test them.
For example, there's three methods of doing this.
You can do it through compile-time injection.
I compile the program, and I inject a fault
by modifying the source code just slightly
before I compile it and see if it fails.
There's also protocol software injection
where I use fuzzing techniques
to send information of noncompliant data to a protocol.
For example, if I am writing a program
that's supposed to be web-based, and use the HTTP protocol,
it's expecting HTTP type data.
What would happen if I started sending it
some other sort of data, like FTP data, right?
Will it be able to handle it,
or Telnet data, or PopData, right?
That's the kind of things we're talking about here.
Runtime injection.
Runtime injection is when you're gonna insert data
into the running memory of the program space,
or by sending a fault to the program
that it's gonna have to deal with it.
Now for the CSA+ exam,
you should know what a fault injection is.
You don't necessarily need to know the three methods
or examples here I provided you, though.
Now we talk about mutation testing.
This is gonna make small changes to the program itself,
and determine if it will cause a failure.
If they cause a failure,
those parts of the code will be rejected.
If you can use this to test code
when you're testing it to see if it's possible
to create new issues with unexpected input.
This is a form to see what can the bad guys do to my code.
Is there ways for them to inject some stuff
and modify my code to cause issues, right?
Because if you get a virus or malware,
it's gonna mess up your code a little bit,
but will the program still run?
That's what we're trying to find out here
with mutation testing.
Next one we have is stress testing,
also known as load testing.
This is gonna ensure your applications
can support the expected production load.
So if I've created a program,
and I designed it for me and my five friends to use,
that's fine, right?
But if I start putting it on the App Store,
and now I got 5,000 friends using it,
or five million friends using it, right,
all my new friends that have found it,
is it gonna crash the program?
Well, it might.
You wanna use automated tools to stress your expected load,
so my case, five, or 5,000, or five million,
and determine if it can handle it properly.
Because some things just don't scale well, right?
I'll give you a good example of this.
The old Microsoft Outlook client, Microsoft Outlook 2003,
if you had a PST file that was over one gigabyte in size,
it pretty much crashed the program,
because they never expected you to have that much email.
And so that was a load or a stress test.
When you got too big, it crashed the program.
You wanna test for the worse case scenario,
how big, how many users, how much data,
how much bandwidth, all those type of things.
This can be conducted against the entire system,
or against just single components of the program.
But normally this is done
as part of the user acceptance testing,
and the end testing to verify that the program is ready,
and doing it from an end-to-end component on the system.
Now the last one I wanna talk about
is security regression testing.
This is gonna ensure that any changes made
do not create new problems or new issues in the application.
This is most commonly used when you get
a new patch created, or a new update.
So for example, we have Microsoft Windows
as an operating system.
They get patches all the time, right?
Because bugs are discovered in the code,
because there's billions of lines of code.
Well, when they go and say,
oh, there was a security bug, let's create a patch for it,
they then need to test to make sure that patch
didn't create new problems, because guess what,
sometimes when they put a security patch out,
it breaks the system even further.
And so they wanna verify
that no new vulnerabilities are being added,
and no new misconfigurations have been added in that.
This is part of that whole scan patch scan,
scan patch scan as you kinda go
in this big cycle of what you're doing,
and trying to make sure that the code you're entering
is not gonna give you more problems.