In this lesson,
we're going to discuss the world of application security.
Application security is a critical aspect
of software development that focuses
on building applications that are secure by design.
By utilizing application security,
implement measures to prevent, detect,
and remediate security vulnerabilities.
There are six main areas we need to look at
in terms of application security,
including input validation, secure cookies,
static code analysis, dynamic code analysis,
code signing, and sandboxing.
First, we have input validation.
Input validation is a fundamental aspect
of application security that acts as a gatekeeper
to ensure that applications only act
on well-defined and uncontaminated data.
Input validation is focused
on directly countering various forms of attacks
aimed at exploiting data input vulnerabilities
to preserve the integrity and behavior of the application.
In the vast and complex world of software,
where interactions are multifaceted and unlimited,
the need to authenticate, clean,
and secure data inputs cannot be overstated.
Whether it's a user who fills out a form,
data is transferred from one application to another,
or an internal function calls another within a system,
these are all considered inputs
and must be properly validated
before the application performs any kind of operation
using the user-provided data.
Each of these types of data being input
will represent a point of interaction
as well as potential vulnerability to our systems.
Often, threat actors will attempt to break into a system
by feeding it data that could trigger
an unintended reaction or breach
by conducting a SQL injection, cross-site scripting,
buffer overflow, and other types of attacks.
This is why input validation is important,
because it serves as a kind of quality control for data
to ensure that every piece of information
is valid, secure, and correctly formatted
before it's processed by the application.
This is not just about preventing malicious attacks,
but it also helps to ensure that our systems
behave predictably and can handle errors gracefully.
For example, if a function expects a numerical value
but receives a string instead,
it could cause errors or unpredictable behavior.
Proper input validation catches such issues
before the application attempts to perform an operation
on the wrong type of data.
Implementing input validation
involves establishing specific criteria
known as validation rules.
These rules delineate acceptable and unacceptable inputs.
For instance, if the input field
is expecting a phone number,
and the validation rules might require 10 digits
and no letters, special characters, or additional digits.
Anything outside of this would be flagged and rejected,
or the system might request the user
to input the data again.
These rules can be very simple,
like checking if input is empty,
or more complex, like verifying if the input
matches a regular expression used by an email address.
However, input validation is not just
about setting up boundaries,
but it's also an important security measure
to ensure that data is validated early in the process.
We refer to this as front-end validation,
where any web forms created in an application
will ensure that the data matches the right format
before accepting it.
Conversely, we will also implement
back-end validation as well
to ensure that our servers check the data
prior to allowing an application to utilize that data.
It is important because front-end validation alone
can be bypassed by an attacker,
but using backend validation by itself
could become more expensive or time consuming,
since it relies on your own service to do the validation.
Now, while input validation is critical to perform,
it is important to remember
that it's not a cure-all solution,
and you still need to have a multi-layered approach
to security, known as "defense in depth",
to achieve high levels of security.
This might include using secure communication protocols,
regular security auditing,
and implementing proper error handling
to implement your own defense in depth strategy.
Next, let's discuss the use of secure cookies.
Cookies are small pieces of data stored on a user's computer
by the web browser while browsing a website.
They are used to maintain staple information
between the web server and the client.
However, if not properly secured, cookies can be exploited
to hijack user sessions or steal sensitive data.
Secure cookies are a solution to this problem.
They are transmitted over a secure HTTPS connection
to prevent potential eavesdroppers
from intercepting the cookie data.
For example, a baking website would use secure cookies
to store session information to ensure that,
even if an attacker can intercept network traffic,
they cannot read or modify the cookie data.
There are some practices that you should be aware of
when utilizing cookies.
You should always refrain from utilizing persistent cookies
for session verification.
Instead, you should always generate a fresh cookie
each time the user authenticates again
to prevent session hijacking from occurring.
Also, you should enable the secure attribute on the cookie
to ensure that a cookie is not transmitted
over an insecure HTTP connection accidentally.
To protect your cookies from being reachable
within a document object model or by a client-side script,
you should enable the HttpOnly attribute
in the cookie itself.
If you need to control which origin
can access a given cookie,
you can configure the SameSite attribute on the cookie
so that it reduces the risk
of a cross-site request forgery attack
from being successful.
Next on our list is static code analysis.
Static code analysis,
also known as static application security testing, or SAST,
is a method of debugging and application
by reviewing and examining its source code
before the program is ever run.
Static code analysis is designed to analyze source code
for potential vulnerabilities, such as buffer overflows,
SQL injection, and cross-site scripting attacks,
as well as ensure that the programmers
have implemented proper input validation
into the front-end and back-end of the code.
For example, a static code analysis tool
might flag a piece of code
that concatenates a user provided string into a SQL query.
This could potentially lead
to an SQL injection vulnerability
if the user-provided string
contains a malicious SQL command.
Instead, the program should perform input validation
on the user-entered string
before passing it to the SQL database server.
Alternatively, you could code the program
so that it only utilizes templated queries
instead of allowing for a direct input of a search term
by the user to prevent security issues.
Static code analysis is usually performed
using software analyzers.
The analysis software must support the programming language
used by the source code.
Now, if you perform this code review using a human
instead of a static software analysis tool,
we refer to this as manual code review.
When conducting manual code reviews,
we usually assign a different programmer to review the code
than the person who initially wrote the code.
Also, it helps us find any mistaken assumptions
or uncover any lack of knowledge or experience
that the initial programmer may have had.
Next, we can also utilize dynamic code analysis
to find additional vulnerabilities in our applications.
A dynamic code analysis,
also known as a dynamic application security testing,
or DAST, is a testing method
that analyzes an application while it's running.
Dynamic code analysis is designed to find vulnerabilities
that a static code analysis might miss,
such as runtime errors and memory leaks.
A dynamic code analysis tool
might interact with a web application,
provide various inputs, and observe the related outputs
to identify any potential vulnerabilities.
For example, if the tool inputs a script into a form field
and the application returns the script in its response
without proper encoding, this could indicate
a potential cross-site scripting vulnerability.
When it comes to dynamic code analysis,
the two most common methods
of conducting dynamic code analysis
is fuzzing and stress testing.
Fuzzing, also known as fuzz testing,
is a software testing technique
used to discover coding errors and security loopholes
in software, operating systems, or networks
by inputting massive amounts of random data called fuzz
to the system in an attempt to make it crash.
The process of fuzzing involves the automated injection
of malformed or unexpected data into the system,
and then monitoring for exceptions, such as crashes,
failing built-in code assertions, or potential memory leaks.
Stress testing is a type of software testing
that evaluates the stability and reliability
of a system under extreme conditions.
The goal of stress testing
is to identify the system's weak points
and determine how it behaves under intense loads
and how it recovers from failure.
For example, a website might be stress tested
by simulating thousands or millions of users
accessing the site simultaneously.
This can help identify bottlenecks in the system,
test the effectiveness of load balancing,
and ensure that the system can handle high traffic volumes.
All right, now that we have discussed
some different code analysis techniques,
let's discuss a way that a programmer can attest
to the fact that they wrote a specific application.
To do this, we utilize code signing.
Code signing is a technique used to confirm the identity
of the software author and guarantee
that the code has not been altered or corrupted
since it was signed.
Code signing involves using a digital signature
to authenticate the software source and integrity.
Code signing is the main way to confirm
that a piece of code, like a program or script,
is genuine and hasn't been tampered with
since it was distributed by the developers.
The process works by having the developer make a unique code
called a cryptographic hash of the file
and then encrypting that hash
using the developer's own private key
to create a digital signature of the program's file.
Whenever the program is sent out next,
it will come with a copy
of the developer's code signing certificate.
This certificate has a public key
that the receiving computer uses to check
and confirm that the signature is valid.
Then, the operating system ask the user to decide
if they trust the signature
and want to run and install the given program.
For example, when you download an application
from the Apple App Store, you can be confident
that the application is genuine
and hasn't been tampered with
since it was uploaded by the developer.
This is because Apple requires all applications to be signed
with the developer certificate
before they can publish it to the App Store.
It is crucial to understand that the process
of digital signatures on a file or program
does not guarantee its absolute security
or the absence of vulnerabilities.
However, what it does ensure is that the file or program
has not been tampered with
since the developer originally created and signed it.
In other words, the digital signature confirms
that the file is in the same state
that the developer intended it to be
when they distributed it.
Finally, let's talk about sandboxing.
Sandboxing is a security mechanism
that is used to isolate running programs
by limiting the resources that they can access
and the changes that they can make to a system.
Sandboxing is a method of executing untested
or untrusted programs without risking harm
to the host device or network.
For example, when you open a potential harmful website
in your browser, the browser runs the website's code
in the sandbox.
This means that even if the website tries
to execute malicious code,
it won't be able to affect your entire computer
because it's confined to the web browser sandbox
in most cases.
These sandboxes provide a more comprehensive solution
than a typical anti-malware tool would,
since they allow for testing code under various environments
and not just the current system configuration,
since you can run numerous sandboxes on one system
using different operating systems.
For example, I am running a Mac OS on my MacBook Pro.
I can also run a sandbox that contains Mac OS
as its operating system, as well as sandboxes
with a Linux operating system
or a Windows operating system as well.
So remember, in the world of application security,
we need to consider six key areas, input validation,
secure cookies, static code analysis, dynamic code analysis,
code signing, and sandboxing.
Input validation is designed to act as a vigilant gatekeeper
that ensures that our applications only process well-defined
and untainted data to counteract various forms of attacks.
Secure cookies help to prevent vulnerabilities
like session hijacking through the secure transmission
and using the proper attribute settings on the cookies.
Static code analysis
involves proactive vulnerability detection
through source code review.
Dynamic code analysis is used to uncover any runtime issues.
Code signing provides a means
to verify the software authenticity,
and sandboxing is used to isolate any untrusted code
to mitigate its ability to potentially cause harm.
These multifaceted security measures,
when integrated into software development practices,
help to create a robust defense strategy
against the ever-evolving world of cybersecurity threats.