-: In this lesson we're going to focus on
the different testing methods that you may use
to help your organization's developers secure their code.
Most security analysts are not programmers themselves,
so the Security+ exam isn't focused on
the specific types of code reviews
like pair programming, over-the-shoulder reviews,
and others.
Instead, the Security+ exam focuses on just a handful
of testing methods that an entry-level security analyst
might conduct.
The first type of testing is known as system testing.
This comes in three varieties:
black-box testing, white-box testing, and gray-box testing.
Black-box testing occurs when a tester
is not given any information about the system or program
before beginning their test.
For example, if I create a program
and I wanted you to conduct this type of test,
I might simply hand you a copy
of the executable program on a disk
and then it's up to you to figure out how it functions,
how to bypass any security I may have coded into it,
and if you can crash it by entering in
incorrect information.
Essentially, you're going to begin your testing
without any sense of what the program does
or how it functions.
As a tester, you're essentially blind to start with
and you discover your way around the program or system
through your testing.
White-box testing, on the other hand, is the exact opposite.
In white-box testing, the tester is given the details
of the inner workings of the program or system.
This may even include access to the full source code
of that program, diagrams of the system,
user access credentials, logons, and more.
The third type of testing is called gray-box testing.
This is a mixture of black-box and white-box
where the tester is given some amount of information
about the system
and conducts his testing as if he doesn't have
full access to it.
For example, a gray-box tester might be given
user-level credentials to test a system,
but not given administrative credentials.
If you're testing a network system,
you may be given some information like the IP address
of different devices,
but you're not given the version of the software
that's running on each device.
As a part of these system tests,
you're often attempting to break the system
by attempting to stress that system or create an exception.
It's important that programmers
have coded their applications to fail securely,
and to ensure this happens, you're going to purposely create
error conditions to cause an error to occur
and see how the system is going to react to it.
If the program is running when the error occurs,
the error is known as a runtime error.
If the program fails to run because of a coding error,
this is known as a syntax error.
This is because the most common cause
of this type of error in programming
is when a programmer doesn't put the proper syntax
expected by that programming language,
such as leaving out a closing parentheses
or missing a semicolon inside their code.
As a security analyst, you're much more likely to experience
a runtime error than a syntax error
because you're testing these things on a live environment.
Now, when you create an error,
this is also known as an exception.
You need to be able to have a way to handle this properly
and gather the details of the error and what caused it.
To do this, you should use
a structured exception handling mechanism,
which gives you control over what the application should do
when faced with an error.
This is very helpful during debugging and testing,
especially if you have a background as a programmer.
Now that you know how exceptions are handled,
how do you raise an exception or cause this error to occur?
Well, the most common way is to provide the application
with erroneous input as an end user.
For example, let's pretend you're testing a web application
that's designed to let somebody apply for a credit card.
The application might ask for a lot of different
pieces of information like the person's name,
their birthdate, and their social security number.
Let's say you're testing it and you enter John Smith
for your name and 14/23/1985 for your birthday
and ABCD as your social security number.
Magically, an error happens.
Why?
Well, because there's no 14th month in the calendar.
This is an erroneous input,
and a social security number has to have
nine numerical digits,
not four letters like ABCD.
If entering this type of information
caused an exception or an error,
this means that the programmers
haven't been doing a good job of implementing
proper input validation.
All programs should use input validation
when accepting information from their end users.
After all, end users can make mistakes that cause an error
and attackers can use erroneous inputs
as a method to break a piece of software
in order to gain access to information
that the software application contains.
Input validation simply means that programmers
have written code that validates the information
being received from the user
and ensuring that it matches a specific format
or a range of values.
For example, if I'm asking for a social security number
as part of this web application,
I can create a simple program to help solve this issue
and conduct input validation.
For example, let's use this bit of pseudo code.
Get the variable social security number.
If the social security number is greater than 000-00-0000
and the social security number is less than 999-99-9999,
then I can do some function.
Otherwise, I'm going to print some error and then retry.
This piece of pseudo code validates
whether the social security number being accepted
is in the right format and in the right range of values.
If not, then error handling will have to occur,
like displaying an error message to the user
to say the social security number they entered was invalid
and they need to try again.
Input validation is a key component to good coding,
because attackers often use improper inputs
as part of their attacks,
such as in SQL injections, buffer overflows,
and cross-site scripting attacks.
Another aspect of system testing
is to consider how are you going to test the code itself.
Are you going to do this statically or dynamically?
Static analysis occurs when the source code of a program
is available for analysis.
Static analysis is conducted by somebody
who understands the language the program is written in
and they can analyze the code for errors.
These types of static analysis reviews
can also be aided by the use of automation software
to check for known vulnerabilities
and bring them to the attention of a skilled programmer
or analyst.
During a static analysis,
the software's code is not run
but it's simply read to find those errors.
Think of static analysis as your third-grade English teacher
looking over your essay and marking it up with a red pen
to show you all of your errors.
Dynamic analysis, on the other hand,
is performed on a program while it's being run.
The most common type of dynamic analysis
includes the use of fuzzing.
Fuzzing, also known as a fuzz test,
involves using a software program to insert randomized data
in an attempt to find vulnerabilities.
Fuzzing is used to determine possible system failures,
memory leaks, error handling issues,
and improper input validation as well.
This type of testing works just like the earlier example
where we tried to enter some letters in
as our social security number,
but fuzzing tries to enter lots and lots
of randomized sequences to find any vulnerabilities
or errors that it can.
Fuzzing can occur on more than just a single program,
but it also can be used on an entire network or system.
For example, you could use a network fuzzer
to help you stress test a new network you installed
and determine its maximum capacity.