Desenvolvimento Seguro
Desenvolvimento Seguro
DESENVOLVIMENTO SEGURO
Edson Freire Nepomuceno
AGENDA
1. Visão Geral dos Aspectos de Segurança da Informação
2. Superfície de Ataque de uma Aplicação WEB
3. Threat Modeling – STRIDE
4. Estatísticas de Vulnerabilidades
5. OWASP TOP 10 2013
• A1 - Injection
• A2 - Broken Authentication and Session Management
• A3 - Cross-Site Scripting (XSS)
• A4 - Insecure Direct Object References
• A5 - Security Misconfiguration
• A6 - Sensitive Data Exposure
• A7 - Missing Function Level Access Control
• A8 - Cross-Site Request Forgery (CSRF)
• A9 - Using Components with Known Vulnerabilities
• A10 - Unvalidated Redirects and Forwards
6. Wiki de Desenvolvimento Seguro
VISÃO GERAL
ASPECTOS DE SEGURANÇA DA INFORMAÇÃO
VISÃO GERAL DOS ASPECTOS DE SEGURANÇA DA INFORMAÇÃO - PARTE 0
VISÃO GERAL DOS ASPECTOS DE SEGURANÇA DA INFORMAÇÃO - PARTE 1
VISÃO GERAL DOS ASPECTOS DE SEGURANÇA DA INFORMAÇÃO - PARTE 2
VISÃO GERAL DOS ASPECTOS DE SEGURANÇA DA INFORMAÇÃO - PARTE 3
ATTACK PHASES
THREAT MODELING
1) Identificar ativos
2) Criar uma Visão Geral da Arquitetura
3) Decompor a aplicação
4) Identificar ameaças
5) Documentar as ameaças
6) Avaliar as ameaças
S
I
PROCESS FLOW DIAGRAM
END-TO-END DATA FLOW
THREAT MODELING – S.T.R.I.D.E.
A Microsoft (2010) usa o acrônimo STRIDE para classificar os efeitos
que podem ser provocados em decorrência de falhas de segurança
em uma aplicação,sendo:
1. Information Gathering
2. Configuration and Deployment Management Testing
3. Identity Management Testing
4. Authentication Testing
5. Authorization Testing
6. Session Management Testing
7. Input Validation Testing
8. Error Handling
9. Business Logic Testing
10. Client Side Testing
WEB APPLICATION EVALUATION METHODOLOGY
Information Gathering
Um comandante militar deve atacar onde o inimigo está desprevenido e deve utilizar caminhos
que, para o inimigo, são inesperados (Sun Tzu, 496 BC).
Encontre todos os pontos nos quais um usuário envia dados para aplicação:
• GET requests with query strings parameters
• POST requests generated by forms
• HTTP headers
• Cookies
• Hidden parameters
OWASP TOP 10
ATTACK & DEFENSE
A1 – INJECTION
ATTACK & DEFENSE
A1 – CODE INJECTION
• Considered one of the most prevalent software (or application) security weaknesses,
injection flaws occur when the user-supplied data are not validated before being
processed by an interpreter.
• The attacker supplies data that are accepted as they are and interpreted as a command or
part of a command, thus allowing the attacker to execute commands using any injection
vector.
• Almost any data accepting source are a potential injection vector if the data are not
validated before they are processed.
• The consequences of injection flaws are varied and serious. The most common ones
include:
• Disclosed, altered, or destroyed data.
• Compromise of the operating system.
• Discovery of the internal structure (or schema) of the database or data store.
A1 – SQL INJECTION
ATTACK & DEFENSE
A1 – CODE INJECTION
SQL Injection
• This is probably the most well-known form of injection attack, as the databases that store
business data are becoming the prime target for attackers.
• Attackers exploit the way in which database queries are constructed. They supply input
that, if not sanitized or validated, becomes part of the query that the database processes
as a command.
• Upon determining that the application is susceptible to SQL injection, an attacker will
attempt to force the database to respond with messages that potentially disclose internal
database structure and values by passing in SQL commands that cause the database to
error.
SQL INJECTION - CÓDIGO VULNERAVÉL (JAVA)
String email = request.getParameter("email");
String sql = "select * from users where (email ='" + email +"' and password ='" + password + "')";
if (result.next()) {
loggedIn = true;
} else {
}
UNDERSTANDING THE SOURCE CODE
o The string variable sql is then declared, which represents the SQL query used
to authenticate Alice's credentials.
o Note, that email and password values are concatenated to build the final query.
o The SQL query defined in sql string variable is then executed by invoking
the executeQuery method. This method executes our query against the
backend SQL server and returns a ResultSet object which is checked on line 10
through the if/else block.
o Finally, should if the credentials match, the loggedIn variable is set to true and
the user is redirected to their profile page.
A1 – SQL INECTJION - CÓDIGO CORRIGIDO (JAVA)
String email = request.getParameter("email");
String sql = "select * from users where email = ? and password = ? ";
preparedStatement.setString(1, email);
preparedStatement.setString(2, password);
if (result.next()) {
loggedIn = true;
} else {
}
UNDERSTANDING THE SOURCE CODE
In our modified code example, we first declare the authentication query string and assign it to the
sql string variable. Notice that the email and password variable have now been replaced with ?
symbol which act as a place holder for Java's PreparedStatement class.
The sql string variable is then passed as an argument to the prepareStatement() method, which
precompiles the SQL query and creates a PreparedStatement object for sending paramterized SQL
statements to the back end SQL server.
The setString() method is then called to pass the email parameter value to our prepared statement.
This function takes two arguments, the position index of our placeholder denoted by ? and the
parameter value stored in the email variable.
UNDERSTANDING THE SOURCE CODE
o Prepared statements are used to abstract SQL statement syntax from input
parameters. Statement templates are first defined at the application layer,
and the parameters are then passed to them.
o When the software allows the execution of operation system (OS) level commands using the
supplied user input without sanitization or validation, it is said to be susceptible to OS
Command injection.
1) The software accepts arguments from the user to execute a single fixed program
command. In such cases, the injection is contained only to the command that is allowed to
execute,and the attacker can change the input but not the command itself.
2) The software accepts arguments from the user that specify what program command they
would like the system to execute. This is a lot more serious than the previous case, because
now the attacker can chain multiple commands and do some serious damage to the system
by executing their own commands that the system supports.
COMMAND INJECTION – APPLICATION CONTEXT
o The vulnerable application pane loads the TradeADMIN application, a web based
administration and management information reporting portal.
o The development team have recently added a new feature to allow TradeADMIN users
perform statistical analysis on their historical trades.
o To create the analytics reports, the web application's server-side code invokes a custom
C++ application called statlab to perform the computationally intensive statistical
analysis.
o For the web application to invoke statlab the developers have utilized the
java.lang.Runtime.exec() method which accepts a single String command argument.
When the method is called, the specified system command is executed in a separate
process.
COMMAND INJECTION - CÓDIGO VULNERAVÉL (JAVA)
// The following is a code snippet illustrating the use of insecure command
execution function in Java
}catch(Exception e)
{
e.printStackTrace();
}
}
}
UNDERSTANDING THE SOURCE CODE
TradeADMIN's developers have implemented the executeCommand
method which accepts a String userName argument. The method accepts a
valid user name registered on the TradeADMIN portal.
For Alice's profile the resulting string executed by exec() would be:
/usr/bin/statlab -alice
https://tradeadmin.pagseguro.com.br/console/execute?username=alice
https://tradeadmin.pagseguro.uol.com.br/console/execute?username=alice;id
2. See the CODE to understand how your input is interpreted by the exec() function.
try {
String myUid = userName; // The string variable myUid is assigned Alice's query string value alice;id
Runtime rt = Runtime.getRuntime(); // The executeCommand method initializes a runtime environment by
invoking Runtime.getRuntime() method that allows the TradeADMIN application to interface with it's runtime
environment.
rt.exec("/usr/bin/statlab " +”-“ + alice; id); // Call statlab with Alice's username
However, if this requirement is unavoidable, then all user supplied input passed to
Runtime.exec() must be carefully validated for escape characters or any input that allows
injection of malicious commands within the applications execution environment.
For our example, the following solution validates the untrusted user input by permitting only
a small group of white listed characters in the argument that will be passed to
Runtime.exec(), excluding all other characters including the ; (UNIX command separator)
token.
if (!Pattern.matches(
"[0-9A-Za-z]+", myUiD)
) {
// Handle error
}
Let's see how the above fix can be applied to our vulnerable example to remediate the
command injection vulnerability.
A1 – COMMAND INJECTION - CÓDIGO CORRIGIDO (JAVA)
public class CommandExecuter {
public string executeCommand(String userName)
{
try {
String myUid = userName;
if (!Pattern.matches("[0-9A-Za-z]+", myUiD)) {
return false;
}
Runtime rt = Runtime.getRuntime();
rt.exec("/usr/bin/statlab " + ”-“ + myUid); // Call statlab with
Alice's username
}catch(Exception e)
{
e.printStackTrace();
}
}
}
UNDERSTAND THE SOURCECODE
In our modified code example, an additional check is introduced which performs input
validation against the myUiD string variable. To accomplish this, we make use of Java's
Pattern.matches() method to run a regular expression search on myUiD variable, identifying
non alphanumeric characters e.g. ; , < , > , " , ' , & .
Should any non alphanumeric characters be encountered, the if check will fail and return,
thus preventing malicious control shell characters from being passed to the statlib program.
Note: Although the proposed fix is sufficient to remediate our vulnerable example, the
overall logic and security design for executeCommand() method can be significantly
improved by not accepting user supplied myUiD value through the username parameter.
A better approach would be to extract Alice's username from a database record or a static
index variable that is set during Alice's account creation process, which can then be passed
as an argument to the statlab program for execution.
A1 – CODE INJECTION CONTROLS
1) Consider all input to be untrusted and validate all user input.
2) Consider where the data go. Consider where the data might go later. Sanitize and filter
input using a whitelist of allowable characters and their noncanonical forms. Sanitize early,
sanitize late, sanitize often.
3) Validation must be performed on both the client and server side, or at least on the server
side, so that attackers cannot simply bypass client-side validation checks and still perform
injection attacks.
A1 – CODE INJECTION CONTROLS
5) User input must be validated for data type, range, length, format,
values, and canonical representations.
o One of the primary technical artifacts that we use for input validation is a
regular expression. Regular expressions consist of commands that contain
sequences of metacharacters. These commands are used in string matching
operations and are the most commonly used input validation technique.
o Blacklist validation could be one piece of the puzzle for securing your
application, do not depend on it.
Example:
• Original username:
august<script>alert("w00t");</script>
• Another precaution is you don't ever want to remove or correct invalid data. You want to stick
to encoding and escaping. Because if you start removing data, it becomes a game of cat and
mouse.
A1 – CODE INJECTION
• SQL Injection (Login Form/Hero)
• SQL Injection (GET/Search)
• PHP Code Injection
• OS Command Injection
• HTML Injection - Stored (Blog)
• iFrame Injection
• Server-Side Includes (SSI) Injection
A2 – BROKEN AUTHENTICATION
AND SESSION MANAGEMENT
ATTACK & DEFENSE
A2 – BROKEN AUTHENTICATION AND SESSION MANAGEMENT
• Authentication and session management includes all aspects of handling user authentication
and managing active sessions.
• Areas susceptible to these flaws are usually found in secondary functions that deal with
logout, password management, time outs, remember me, secret questions, and account
updates.
• All known web servers, application servers, and web application environments are
susceptible to broken authentication and session management issues.
A2 – BROKEN AUTHENTICATION AND SESSION MANAGEMENT
Some of the common software programming failures that end up resulting in broken
authentication and broken session management include,but are not limited to, the following:
• Allowing more than one set of authentication or session management controls that allow
access to critical resources via multiple communication channels or paths.
• Transmitting authentication credentials and session IDs over the network in cleartext.
• Implementing weak account management functions that deal with account creation,
changing passwords, or password recovery.
Regular user:
• https://tradesupport.pagseguro.uol.com.br/trade_support/log-
in?app_session_id=d397e2cc5108d09776bd6ce9f79fdbd8
Let's analyze the URL returned by the server. The web application has assigned Alice a unique
session identifier also known as a session token. In this example, Alice's session identifier is set
to:
• d397e2cc5108d09776bd6ce9f79fdbd8
Malicius User:
https://tradesupport.pagseguro.uol.com.br/trade_support/log-
in?app_session_id=4577bbf182eeccc09bba0918e90a0726
A2 – BROKEN AUTHENTICATION AND SESSION MANAGEMENT
ATTACKING
First, Bob copies the login URL along with the session identifier returned by the TradeSUPPORT
application.
Bob then crafts a malicious email to Alice, asking her to check out a new feature in the
TradeSUPPORT portal. To help Alice access the TradeSUPPORT website, he adds the URL he
previously copied in the email body below.
Hi Alice,
We have updated TradeSUPPORT recently with additional features you may find useful. You can check these out
by logging with your credentials at
https://tradesupport.pagseguro.uol.com.br/trade_support/log-
in?app_session_id=4577bbf182eeccc09bba0918e90a0726
Kind Regards,
Bob
SESSION FIXATION - CÓDIGO VULNERAVÉL (JAVA)
private Boolean authenticate(HttpServletRequest request,String credential,String password) {
try {
request.getSession(true);
if (request.getUserPrincipal() == null) {
request.login(credential,password);
return true;
return false;
}
UNDERSTANDING THE SOURCE CODE
• The authenticate function is called for authenticating users and accepts two String parameters
as it's function arguments, credential and password.
• The authenticate() function calls login() which verifies Alice's credentials. However her
existing session is not invalidated before invoking the login() method.
• This means her pre-login session identifier would remain unchanged post login.
• Given that Bob knows Alice's pre-authentication session value, he can successfully
impersonate her authenticated session once Alice has logged onto the TradeSUPPORT
application.
SESSION FIXATION - REMEDIATION
The principle of defense in depth (combining multiple best practices) is necessary for
defending against Session Fixation attacks.These include to:
1. Ensure that only server generated session values are accepted by the application.
2. Upon a successful login, invalidate the original session value, and re-issue a new session value
via HttpSession.invalidate() method.
3. Prevent the application from accepting session values via GET or POST requests and instead
store session values within HTTP Cookies only.
SESSION FIXATION - CÓDIGO CORRIGIDO (JAVA)
private Boolean authenticate(HttpServletRequest request, String credential, String password) {
// Prevent Session Fixation https://en.wikipedia.org/wiki/Session_fixation
HttpSession session = request.getSession(false);
if (session != null){
session.invalidate();
}
try {
}
request.getSession(true);
if (request.getUserPrincipal() == null) {
request.login(credential, password);
}
return true;
• Should Bob now attempt a session fixation attack against Alice, if would fail because the
session identifier has changed from it's original value that was known previously to Bob, thus
preventing the hijacking of Alice's session.
A2 – USE OF INSUFFICIENTLY
RANDOM VALUES
ATTACK & DEFENSE
USE OF INSUFFICIENTLY RANDOM VALUES
• The vulnerable application pane loads the TradeHUB application, an online brokerage
platform.
https://tradehub.pagseguro.uol.com.br/back_office/log-in?app_session_id=1509327842
• Notice that the URL returned by the application contains the session identifier (also known as
a session token).
• Let's analyze the URL returned by the server. The web application has assigned Alice a unique
session identifier.
• Unless of course a trivially simple generator is being used such as: newRND = oldRND + 1;
• Typically identification requires capturing many values and then looking for patterns in how
those values are being generated.
• The developers have created a bespoke session management API to generate web session
tokens for the TradeHUB application. The core logic for generating the underlying session
token values is implemented within the newSession method which returns a session string
variable,that is used by the high level session management code.
• Unfortunately, the developers have not considered using a random number generator to
generate their session identifier values and naively relied on using
System.currentTimeMillis() method to ensure session uniqueness. The currentTimeMillis()
returns the current time in milliseconds which is then passed to a string encoding function
encode().
• Once encoded, the returned session identifier is used by TradeHUB's session management
API which leads to weak session identifiers being assigned for end users.
USE OF INSUFFICIENTLY RANDOM VALUES - REMEDIATION
• Let's see how the above recommendations can be applied to our vulnerable
example to improve our session generator.
USE OF INSUFFICIENTLY RANDOM VALUES - CÓDIGO CORRIGIDO (JAVA)
// Generate and return a new session identifier.
// return encode(now);
}
• We then initialize a 20 byte array to store our random number values generated by
SecureRandom.
• Finally, we call rand.nextBytes() method that generates 20 bytes of random data which is hex
encoded using the encodeHex() method on line 11 and assigned to the string variable
cookie.
• Thus, by using SecureRandom we can ensure that the returned cookie value is sufficiently
random to not allow prediction of session identifiers by potential attackers, thereby ensuring
session integrity and confidentiality.
BROKEN AUTHENTICATION AND SESSION MANAGEMENT CONTROLS
Mitigation and prevention of authentication and session management flaws require
careful planning and design. Some of the most important design considerations
include:
• Do not hard code database connection strings, passwords, or cryptographic keys in cleartext
in the code or configuration files.
BROKEN AUTHENTICATION AND SESSION MANAGEMENT CONTROLS
o Ensure that all pages have a logout link. When the user closes the
browser window, explicitly prompt the user to log off before
closing the browser window.
BROKEN AUTHENTICATION AND SESSION MANAGEMENT CONTROLS
• Explicitly set a timeout, and design the software to log out of an inactive
session automatically. The length of the timeout setting must be inversely
proportional to the value of the data being protected.
• An attacker will provide a script (hence the scripting part) instead of a legitimate value, and
that script, if not escaped before being sent to the client, gets executed. Any input source can
be the attack vector, and the threat agents include anyone who has access to supplying input.
You should identifying which kind of XSS you are reporting, as there’s more than one:
• Reflective XSS: These attacks are not persisted, meaning the XSS is delivered and executed
via a single request and response.
• Stored XSS: These attacks are persisted, or saved, and then executed when a page is loaded
to unsuspecting users.
• Self XSS: These attacks are also not persisted and are usually used as part of tricking a person
into running the XSS themselves.
A3 - REFLECTED CROSS
SITE SCRIPTING
ATTACK & DEFENSE
A3 - CROSS-SITE SCRIPTING (XSS) - CÓDIGO VULNERAVÉL (JAVA)
// Pseudocode for Project Search JSP webpage
// Reflected Cross Site Scripting
<jsp:include page="searchResults.jsp"/>
</c:when>
<c:otherwise>
</c:otherwise>
UNDERSTANDING THE SOURCECODE
• In order to generate the search results web page, TradeSEARCH developers have used the JSP
Standard Templating Library (JSTL) which provides standard actions and methods for
formatting and rendering HTML pages.
• When rendering a user's search result web page, the c:when conditional tag is called to check
if any search results were returned by the server, which are then formatted and rendered by
searchResults.jsp on line 6
• However, should no matching results be found for a specified keyword, the c:otherwise
conditional tag will render the HTML markup on line 9 and 10 that renders a No results found
for: message followed by the user supplied search phrase.
UNDERSTANDING THE SOURCECODE
• To render the No results found for: error message followed by our
search phrase string, request.getParameter() method is called to extract
the search parameter from the URL which then gets directly rendered as
a JSP expression.
• To help defend against Reflected Cross Site Scripting (XSS) attacks it is important to ensure
that user-supplied data is output encoded before being served by the application to other
users.
• By correctly escaping the data, when it is served to the user for display in their browser, the
browser does not interpret it as code and instead interprets it as data, thus ensuring it does
not get executed.
• For example the string: <script> is converted to: <script> when properly escaped and
simply render as text in the user's browser window,rather than being interpreted as code.
• In our example <c:out> can be used to perform output encoding as it escapes HTML
characters, helping defend against XSS attacks.
REFLECTED XSS - CÓDIGO CORRIGIDO (JAVA)
<jsp:include page="searchResults.jsp"/>
</c:when>
<c:otherwise>
</c:otherwise>
UNDERSTANDING THE SOURCECODE
• The most effective method to protect against XSS attacks is by using JSTL's c:out tag or
fn:escapeXml() EL function when displaying user-controlled input. These tags will
automatically escape and encode HTML characters within the rendered HTML including < , > ,
" , ' and & thereby preventing injection of potentially malicious HTML code.
• Finally, we learned that the <c:out> function escapes HTML characters to help prevent against
XSS.
A3 - PERSISTENT CROSS SITE SCRIPTING
• Bob is an authorized user of the TradeDIRECTORY application, and has loaded it in his
browser. Although user Bob is a legitimate user of the application, but he plans to attack other
users of the application.
• As Bob click the "New Contact" button to access the application's functionality that allows for
the adding of new contact records by users.
A3 - PERSISTENT CROSS SITE SCRIPTING - ATTACK
//
// The following is a code snippet illustrating the use of insecure encoding/decoding in Java
//
<table>
<c:forEach var="contact" items="${contacts}">
<tr>
<td>${contact.name}</td>
<td>${contact.title}</td>
<td>${contact.number}</td>
</tr>
</c:forEach>
</table>
A3 - PERSISTENT CROSS SITE SCRIPTING – UNDERSTADING THE SOURCECODE
• In order to generate the TradeDIRECTORY contact listing web page, the application
developers have used the JSP Standard Templating Library (JSTL) which provides
standard actions and methods for formatting HTML.
• To populate the table tag with user contact rows, the c:forEach tag is called to iterate
over the collection of contact objects returned by the TradeDIRECTORY database.
• Finally each contact object is rendered within the td tags using Java's JSP expression
language (EL) syntax ${}. This feature allows outputting the result of a contact object
by first evaluating the object expression.
• Unfortunately, JSP's EL function does not escape expression values, so if Bob saved a
contact card, whose name , title or number field contained HTML formatted data,
Java's EL expression will simply render the input without escaping or encoding it
first. Finally when the web page is loaded by Alice, Bob's malicious HTML will get
rendered in Alice's browser.
A3 - PERSISTENT CROSS SITE SCRIPTING - REMEDIATION
• To help defend against Stored Cross Site Scripting (XSS) attacks it is important to
ensure that user-supplied data is output encoded before being served by the
application to other users.
• By correctly escaping the data, when it is served to the user for display in their
browser, the browser does not interpret it as code and instead interprets it as data,
thus ensuring it does not get executed.
• For example the string: <script> is converted to: <script> when properly
escaped and is simply rendered as text in the user's browser window, rather than
being interpreted as code.
//
// The following is a code snippet illustrating the use of insecure encoding/decoding in Java
//
<table>
<c:forEach var="contact" items="${contacts}">
<tr>
// <td>${contact.name}</td>
// <td>${contact.title}</td>
// <td>${contact.number}</td>
<td><c:out value="${contact.name}"/></td>
<td><c:out value="${contact.title}"/></td>
<td><c:out value="${contact.number}"/></td>
</tr>
</c:forEach>
</table>
A3 - PERSISTENT CROSS SITE SCRIPTING - REMEDIATION
• The most effective method to protect against XSS attacks is by using JSTL's c:out tag
or fn:escapeXml() EL function when displaying user-controlled input. These tags will
automatically escape and encode HTML characters within the rendered HTML
including < , > , " , ' and & thereby preventing injection of potentially malicious HTML code.
A3 – CROSS SITE SCRIPTING - CONTROLS
• Handle the output to the client by either using escaping sequences or encoding. This can be
considered as the best way to protect against XSS attacks in conjunction with input validation.
Escaping all untrusted data based on the HTML context (body, attribute, JavaScript, CSS, or
URL) is the preferred option.
• Validating user-supplied input with a whitelist also provides additional protection against XSS.
All headers, cookies, URL querystring values, form fields, and hidden fields must be validated.
This validation should decode any encoded input and then validate the length, characters,
format, and any business rules on the data before accepting the input.
• Use the innerText properties of HTML controls instead of the innetHtml property when storing
the input supplied, so that when this information is reflected back on the browser client, the
data renders the output to be processed by the browser as literal and as nonexecutable
content instead of executable scripts.
A3 –CROSS SITE SCRIPTING - CONTROLS
• Use secure libraries and encoding frameworks that provide protection against XSS issues. The
Microsoft Anti-Cross-Site Scripting, OWASP ESAPI Encoding module, Apache Wicket, and SAP
Output Encoding framework are well-known examples.
• The client can be secured by disabling the active scripting option in the browser so that
scripts are not automatically executed on the browser.
• Use the HTTPOnly flag on the session or any custom cookie so that the cookie cannot be
accessed by any client-side code or script (if the browser supports it), which mitigates XSS
attacks.
• An insecure direct object reference (IDOR) vulnerability occurs when an attacker can access
or modify some reference to an object, such as a file, database record, account, etc. which
should actually be inaccessible to them. For example, when viewing your account on a
website with private profiles, you might visit www.site.com/user=123.
• However, if you tried www.site.com/user=124 and were granted access, that site would be
considered vulnerable to an IDOR bug.
• Identifying this type of vulnerability ranges from easy to hard. The most basic is similar to the
example above where the ID provided is a simple integer, auto incremented as new records
(or users in the example above) are added to the site.
• So testing for this would involve adding or subtracting 1 from the ID to check for results. If you
are using Burp, you can automate this by sending the request to Burp Intruder, set a payload
on the ID and then use a numeric list with start and stop values, stepping by one.
A4 – DIRECTORY
TRAVERSAL
ATTACK & DEFENSE
A4 - DIRECTORY TRAVERSAL
• For instance an attacker can gain access to the contents of sensitive system files (such as
password stores, ssh keys, encryptions keys etc) or to download source code repositories,
etc.
• Consider also that retrieval of sensitive files is not a direct path to code-execution, it can be an
indirect path (for instance consider the impact of the theft of an ssh authorized_keys file).
A4 – DIRECTORY TRAVERSAL
• The vulnerable application pane loads the TradeRESEARCH application, an online financial
research application for traders to view the latest news and research articles related to their
portfolio and trading strategies.
• Alice is an authorized trader and user of the TradeRESEARCH system, and has loaded the
application in her web browser.
• Let's further analyze the URL returned by the server. The URL end's with the following query
string:
file=5543
A4 - DIRECTORY TRAVERSAL - CÓDIGO VULNERAVÉL (JAVA)
// The following is a code snippet illustrating the use of insecure file canonical paths in Java
String result;
String filename = request.getParameter("file");
try {
File file = new File("/tmp/" + filename);
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = null;
while((line = reader.readLine()) != null) {
result = line;
}
} catch (Exception e) {
e.printStackTrace();
}
try {
response.getWriter().write(result);
} catch (IOException e) {
e.printStackTrace();
}
}
A4 - DIRECTORY TRAVERSAL - UNDERSTANDING THE SOURCECODE
• To load the contents of a research report, the request.getParameter() method is first called to
extract file value (from the HTTP request parameter) which is then assigned to
the filename variable.
• The filename variable is then passed to Java's File() method, which creates a File instance
represented by the file pathname. In Alice's example the path name is set dynamically by
appending the filename to our directory path /tmp/ which translates to /tmp/filename.
Note that the research analysts save their research as HTML flat files in the /tmp directory with
a standardized file naming convention e.g. 5543 , 5544 , 5545 etc.
• The contents of this file are then read by the while() loop and stored in the string
variable result.
• Finally, the result string is sent back as a response via the response.getWriter().write(result)
code block which finally gets rendered within Alice's browser.
A4 - DIRECTORY TRAVERSAL - EXPLOITATION
https://traderesearch.pagseguro.uol.com.br/article/show_file?
file=../etc/passwd
String result;
String filename = request.getParameter("file");
try {
File file = new File("/tmp/" + filename);
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = null;
while((line = reader.readLine()) != null) {
result = line;
}
} catch (Exception e) {
e.printStackTrace();
}
try {
response.getWriter().write(result);
} catch (IOException e) {
e.printStackTrace();
}
}
A4 - DIRECTORY TRAVERSAL - UNDERSTANDING THE SOURCECODE
• To quickly recap, the request.getParameter() method is first called to extract the file value
(from the HTTP request parameter) which is then assigned to the filename variable.
• However, note that no input validation is performed on the filename variable, which is directly
concatenated with the /tmp path.
• Therefore, by injecting the dot dot slash ( ../ ) characters within the filename variable, Alice is
able to traverse the web server's directory structure and access files outside the
original /tmp folder path. This type of directory/folder subversion is also know as a directory
traversal attack.
A4 - DIRECTORY TRAVERSAL - REMEDIATION
• As with any user supplied input, it is important to ensure there is a context specific input
validation strategy in place.
• Alternatively, using Java Security Manager it is possible to grant Java permission to a specific
directory using java.io.FilePermission in the following manner.
• Note a more elegant and secure solution in this specific case would be for the application to
maintain a look-up table of index values mapped to local files on the file system.
A4 - A4 - DIRECTORY TRAVERSAL - CÓDIGO CORRIGIDO (JAVA)
// The following is a code snippet illustrating the use of insecure file canonical paths in Java
String result;
String filename = request.getParameter("file");
try {
File file = new File("/tmp/" + filename);
String canonicalPath = file.getCanonicalPath();
if(!canonicalPath.startsWith("/tmp/")) {
throw new GenericException("Unauthorized access");
}
} catch (Exception e) {
e.printStackTrace();
}
try {
response.getWriter().write(result);
} catch (IOException e) {
e.printStackTrace();
}
}
A4 - DIRECTORY TRAVERSAL - REMEDIATION
• In our updated code fix, we make use of Java's getCanonicalPath() method which gets the full
path string of Alice's file parameter by resolving the files relative path against the current
directory, and further removes any relative pathing characters such as ./ and ../
• The system could be completely compromised without you knowing it. All
of your data could be stolen or modified slowly over time. Recovery costs
could be expensive.
<div class="loginInput">
<input type="text" class="variable" name="email" id="variable1"/>
</div>
<div class="loginInput">
<input type="password" class="variable" name="password" id="variable2"/>
</div>
// <!-- FIXME - For QA/Testing environment,append ?debug=1 flag within the URL to access
the application without authentication. -->
<div class="loginControl">
<input type="submit" value="Log Me In" class="dredB logMeIn" id="btnStatus"/>
</div>
A5 - LEFTOVER DEBUG CODE – UNDERSTAND THE SOURCE CODE
• Notices that the login web page contains an HTML comment that was unintentionally shipped
into the production instance of the TradeTECH web application.
• Upon further inspection of this comment, it appears that TradeTECH developers have
implemented functionality to bypass the authentication mechanism, in order to help QA teams
run their test cases unobtrusively and without the additional overhead of authenticating each
time.
• By simply appending the query string ?debug=1 , a user can completely bypass the
authentication mechanism and obtain access to the TradeTECH application!
• Now that Bob has discovered the hidden debugging parameter, he attempts to exploit this
hidden application functionality by appending the query string ?debug=1 to TradeTECH's
default login URL.
https://tradetech.pagseguro.uol.com.br/?debug=1
A5 - LEFTOVER DEBUG CODE – CÓDIGO VULNERAVÉL (JAVA)
• Should the previous if block condition return true the setAttribute method is called on
line 9 and 10 to update the users session (in this case Bob) , specifically username is set
to admin and isAdmin is set to true.
• Finally, the boolean variable isAuthenticated is set to true which indicates that the current
session is authenticated, thus allowing a legitimate QA / Tester to bypass TradeTECH's
authentication logic.
• Unfortunately, no configuration checks are implemented to ensure that this code block is
automatically disabled for non QA / Test environments, thereby allowing unauthorized users
like Bob to bypass authentication within TradeTECH's "Production" instance.
A5 - LEFTOVER DEBUG CODE - REMEDIATION
• In web-based applications, debug code is helper functionality, used for conveniently testing
and modifying web application properties, configuration information, and functions. If debug
functionality is left on a production system, this oversight during the "software process" allows
attackers access to debug functionality.
• Do not leave debug statements that could be executed in the source code. Ensure that all
debug functionality and information is removed as part of the production build process.
Remove debug code before deploying the application.
• Further, leftover comments from the development process can reveal potentially useful
information to would be attackers about the application's architecture, its configuration,
version numbers,and so on, ensure these are removed too.
A5 - SECURITY MISCONFIGURATION - CONTROLS
1. A repeatable hardening process that makes it fast and easy to deploy another environment that is
properly locked down. This process should be automated to minimize the effort required to setup a new
secure environment.
2. Development, QA, and production environments should all be configured identically (with different
passwords used in each environment).
3. A process for keeping abreast of and deploying all new software updates and patches in a timely manner
to each deployed environment. This needs to include all code libraries as well (see new A9).
4. A strong application architecture that provides effective, secure separation between components.
5. Consider running scans and doing audits periodically to help detect future misconfigurations or missing
patches.
6. We should use a localized description string in every exception, a friendly error reason such as “System
Error – Please try again later”.
A5 - SECURITY MISCONFIGURATION
• Bob doesn't know the username or password of any valid users and decides to explore the
forgotten password function.
A6 - USER ENUMERATION
• Interesting. The last email, belonging to Alice, resulted in a success message, whilst the (non-
existent users, Jim and Bob) resulted in a failure message.
• NB: 'Username Enumeration' can exist in other areas of an application, not just within a
'Forgotten Password' function.
A6 - USER ENUMERATION - CÓDIGO VULNERAVÉL (JAVA)
<c:choose>
<c:when test="${statusCode == 'emailNotFound'}">
<div id="reminder-message">We are unable to find an account matching the email address
you entered. Please contact an administrator.</div>
</c:when>
<c:when test="${statusCode == 'emailFound'}">
<div id="reminder-message">A reminder email has been sent to this user.</div>
</c:when>
</c:choose>
A6 - USER ENUMERATION – UNDERSTANDING THE SOURCECODE
• Addressing this specific issue is straightforward, a simple change to the application to return
the following message (whether or not the user exists) would suffice:
"A forgotten password reminder email has been sent to the address on file (if the username is
valid). Please check your emails."
<c:choose>
<c:when test="${statusCode == 'emailNotFound'}">
<div id="reminder-message">A reminder email has been sent to this user.</div>
// <div id="reminder-message">We are unable to find an account matching the email
address you entered. Please contact an administrator.</div>
</c:when>
<c:when test="${statusCode == 'emailFound'}">
<div id="reminder-message">A reminder email has been sent to this user.</div>
</c:when>
</c:choose>
A6 - USER ENUMERATION – UNDERSTANDING THE SOURCECODE
o Alice's try logging in to the application a few times, try and guess her
password a few times.
o Keep your eye on the Live Log window, which is showing the backend web
server’s log file in real time with the tail –f webserver.log command. You
will notice that the GET requests are being logged here.
• Transmitting login credentials via GET requests is never a good idea, because URLs are
inevitably stored in multiple places that an application developer has no control over. When
the Login Credentials are present within the URL, and that URL is stored, it increases the
likelihood of inadvertent login credential exposure. For instance, URLS are commonly stored
in:
• Browser history
• Browser bookmarks
• Referrer headers when resources are linked
• Upstream proxy logs
• Web application logs
• Note also that to further protect sensitive user-supplied data, the application should only
accept communication from a logged-in user over HTTPS, and never over HTTP.
A6 -SESSION EXPOSURE WITHIN URL
Username: [email protected]
Password: alice123
• https://tradelogic.codebashing.com/tradelogic/log-
in?app_session_id=ad31adf9682d42ecd27c04e931b26d61
• Let's analyze the URL returned by the server. The web application has assigned Alice a unique
session identified also known as a session cookie. In this example, Alice's session cookie
is ad31adf9682d42ecd27c04e931b26d61.
A6 -SESSION EXPOSURE WITHIN URL
A6 -SESSION EXPOSURE WITHIN URL - ANALISYS
• A further reason why transmitting Session Identifiers via GET requests is not a good idea is
because URLs are inevitably stored in multiple places that an application developer has no
control over.
• When the Session Identifier is present within the URL, and that URL is stored, it increases the
likelihood of inadvertent session identifier exposure, a precursor to session hijacking. For
instance,URLS are commonly stored in:
1. Browser history
2. Browser bookmarks
3. Referrer headers
4. Upstream proxy logs
5. Web application logs
6. Wireless Access Points
A6 -SESSION EXPOSURE WITHIN URL - REMEDIATION
• Ensure that Session Identifiers are not transmitted to the application via GET request, only via
POST requests.
• Note also that to further protect the Session Identifier the application should only accept
communication from a logged-in user over HTTPS, and never over HTTP.
A6- SENSITIVE DATA EXPOSURE - CONTROLS
The full perils of unsafe cryptography, SSL/TLS usage, and data protection are well beyond the
scope of the Top 10. That said, for all sensitive data, do the following, at a minimum:
1. Considering the threats you plan to protect this data from (e.g., insider attack, external user),
make sure you encrypt all sensitive data at rest and in transit in a manner that defends against
these threats.
2. Don’t store sensitive data unnecessarily. Discard it as soon as possible. Data you don’t retain
can’t be stolen.
3. Ensure strong standard algorithms and strong keys are used, and proper key management is
in place.Consider using FIPS 140 validated cryptographic modules.
4. Ensure passwords are stored with an algorithm specifically designed for password
protection, such as bcrypt, PBKDF2, or scrypt.
5. Disable autocomplete on forms requesting sensitive data and disable caching for pages that
contain sensitive data.
A6 - SENSITIVE DATA EXPOSURE
• Consider the business value of the exposed functions and the data they process.
• Detecting such flaws is easy. The hardest part is identifying which pages (URLs) or functions
exist to attack.
A7 - HORIZONTAL ESCALATION
ATTACKS
• In the general case, when exploited, one user of the system can
gain unauthorized access to Create, Read, Update and/or Delete
operations for different users (with the same role) of the
application.
The TradeJOB developers have implemented the Edit Profile feature, allowing users to
customize and update their user profile information. Bob, decides to update his user profile by
clicking the Edit Profile button.
Let's analyze the URL returned by the TradeJOB application for updating Bob's user profile:
https://tradejob.codebashing.com/trade_job/edit_profile?uid=1000750
qUser=conn.prepareStatement(qString);
qUser.setString(1,uid);
ResultSet user = qUser.executeQuery();
while(user.next())
{
request.setAttribute("name",user.getString("name"));
request.setAttribute("email",user.getString("email"));
request.setAttribute("phone",user.getString("phone"));
request.setAttribute("institute",user.getString("department"));
}
request.getRequestDispatcher("/WEB-INF/templates/edit_profile.jsp").forward(request, response);
}
A7 - HORIZONTAL ESCALATION ATTACKS – UNDERSTANDING THE SOURCE CODE
• To implement the "Edit User" functionality, the doGet() method
extracts a logged-in user's uid value by
invoking request.getParameter() method, which is then assigned to
the uid string variable.
1. uid=1000775
2. uid=1000800
qUser=conn.prepareStatement(qString);
qUser.setString(1,uid);
ResultSet user = qUser.executeQuery();
while(user.next())
{
request.setAttribute("name",user.getString("name"));
request.setAttribute("email",user.getString("email"));
request.setAttribute("phone",user.getString("phone"));
request.setAttribute("institute",user.getString("department"));
}
request.getRequestDispatcher("/WEB-INF/templates/edit_profile.jsp").forward(request, response);
}
A7 - HORIZONTAL ESCALATION ATTACKS – UNDERSTANDING THE
SOURCE CODE
• To quickly recap, the request.getParameter() method is first
called to extract Bob's uid value which is assigned to the String
uid variable.
o For the general case it is imperative to consistently check that any user CRUD
operation is authorized, inline with a well defined access control model.
qUser=conn.prepareStatement(qString);
qUser.setString(1,uid);
qUser.setString(2,currentUser);
ResultSet user = qUser.executeQuery();
while(user.next())
{
request.setAttribute("name",user.getString("name"));
request.setAttribute("email",user.getString("email"));
request.setAttribute("phone",user.getString("phone"));
request.setAttribute("institute",user.getString("department"));
}
request.getRequestDispatcher("/WEB-INF/templates/edit_profile.jsp").forward(request,response);
}
A7 - HORIZONTAL ESCALATION ATTACKS – REMEDATION
Let's analyze the URL returned by the TradeSOCIAL application for updating Bob's user profile:
• https://tradesocial.pagseguro.uol.com.br/trade_social/user/show
Bob decides to tamper this URL, hoping to access potentially restricted features within the
TradeSOCIAL application. He does this by replacing the keyword user with admin resulting in
the following URL:
• https://tradesocial.pagseguro.uol.com.br/trade_social/admin/show
Interesting! Bob managed to get (read) access TradeSOCIAL's administrator web page by simply
changing the user keyword to admin in the URL!
A7 - VERTICAL ESCALATION ATTACKS - CÓDIGO VULNERAVÉL (JAVA)
public class GetAllUsers extends HttpServlet implements Servlet
{
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException
{
Subject currentUser = SecurityUtils.getSubject();
String url = "/login.jsp";
// Return full list of users
if (currentUser.isAuthenticated())
{
url = "/admin/show.jsp";
List<User> userList = UserDAO.getAllUsers();
request.setAttribute("userList", userList);
}
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(url);
dispatcher.forward(request,response);
}
}
A7 - VERTICAL ESCALATION ATTACKS – UNDERSTADING THE SOURCECODE
However, consider that the larger and more complex an application is, the greater the
potential for even a single missed authorization check. It is for this reason that a
consistently applied, pattern based approach to ensuring authorization across any application
is applied.
To make life easier, many frameworks provide built in functionality to assist with this. For
instance, Java Spring Framework provides support for Expression-Based Access Control of
the format hasRole([role]).
Furthermore, Spring Security 3.0 added Method Security Expressions, which introduced
additional annotations, including @Pre and @Post annotations. A simple example of which
follows, that means access to the method will only be allowed for users with the role
"ROLE_USER”:
@PreAuthorize("hasRole('ROLE_USER')")
public void create(Contact contact);
A7 - VERTICAL ESCALATION ATTACKS – CÓDIGO CORRIGIDO
public class GetAllUsers extends HttpServlet implements Servlet
{
• Consider also that there are many areas of an application where such a
vulnerability could occur. As such it is critical to ensure that a strong
authorization model is well-defined and further more a consistent pattern
for authorization checking prior to any CRUD operations.
A7 – XML EXTERNAL ENTITY INJECTION
<trades>
<metadata>
<name>Apple Inc</name>
<stock>APPL</stock>
<trader>
<name>C.K Frode</name>
</trader>
<units>1500</units>
<price>106</price>
<name>Microsoft Corp</name>
<stock>MSFT</stock>
<trader>
<name>C.K Frode</name>
</trader>
<units>5000</units>
<price>45</price>
<name>Amazon Inc</name>
<stock>AMZN</stock>
<trader>
<name>C.K Frode</name>
</trader>
<units>4500</units>
<price>195</price>
</metadata>
</trades>
A7 – MALICIUS XXE INPUT
• An XXE attack works by taking advantage of a feature in XML, namely XML eXternal entities
(XXE) that allows external XML resources to be loaded within an XML document.
• By submitting an XML file that defines an external entity with a file:// URI, an attacker can
effectively trick the application's SAX parser into reading the contents of arbitrary file(s) that
reside on the server-side filesystem.
A7 – XML EXTERNAL ENTITY INJECTION – ATTACK SOURCECODE
<?xml version="1.0" encoding="UTF-8"?>
<trades>
<metadata>
<name>Apple Inc</name>
<stock>APPL</stock>
<trader>
<foo>&bar;</foo>
<name>C.K Frode</name>
</trader>
<units>1500</units>
<price>106</price>
<name>Microsoft Corp</name>
<stock>MSFT</stock>
...
A7 – UNDERSTAING THE SOURCECODE
o The DOCTYPE foo declaration references an external Document Type
Definition (DTD) file, which we have named foo.
o The XML declaration ELEMENT foo ANY declares that foo DTD can
contain any combination of parsable data.
o Finally we use the XML declaration ENTITY to load additional data from
an external resource. The syntax for the ENTITY declaration is ENTITY
name SYSTEM URI where URI is the full path to a remote URL or local file.
In our example we define the ENTITY tag to load the contents of
"file:///etc/passwd".
o The following line maps our tag foo to the external entity &bar; that
points to "file:///etc/passwd" .
o Simply put the XML parser was tricked into accessing a resource that the
application developer's did not intend to be accessible, in this case a file on the
local file system of the remote server.
o In this example, the following XML code fetched the /etc/passwd file present on
BatchTRADER's web server and displayed it to the user of the application.
o Because of this vulnerability any file on the remote server (or more precisely, any
file that the web server has read access to) could be obtained.
o A malicious attacker could easily use this to gain access to arbitrary files such as
system files, or files containing sensitive data such as passwords or user data.
A7 – XML EXTERNAL ENTITY INJECTION – VULNERABLE CODE
• Java web applications using XML libraries are particularly vulnerable to external entity (XXE)
injection attacks because the default settings for most Java XML SAX parsers is to have XXE
enabled by default.
• To use these parsers safely, you have to explicitly disable referencing of external entities in the
SAX parser implementation you use.We'll revisit this in the remediation section later.
• Let's now take a look at how BatchTRADE's server side SAX parser is configured to process
incoming XML files.
A7 – XML EXTERNAL ENTITY INJECTION – VULNERABLE CODE
}
A7 – XML EXTERNAL ENTITY INJECTION – UNDERSTANDING THE
SOURCECODE.
o The BatchTRADER's server side SAX parser is developed using the DocumentBuilderFactory
class, part of the Java API for XML Processing, or JAXP for short, that enables applications to
parse and transform XML documents.
o In order to parse the trade.xml file a new instance of JAXP DocumentBuilderFactory is created
using the static method newInstance() .
o In this example the developers have configured the SAX parser using the setFeature method to
enable loading of external-general-entities by setting it's value to true .
o Similarly, the SAX parser has also been configured to process external-parameter-entities
entities. Both of these options allow the SAX parser to load external entities, which when
specified within our trade.xml file can be abused by an attacker to read arbitrary system files.
Were these set to false the SAX parser would automatically reject the referencing of external
entities.
A7 – XML EXTERNAL ENTITY INJECTION - REMEDIATION
• Because user supplied XML input comes from an "untrusted source" it is very difficult to
properly validate the XML document in a manner to prevent against this type of attack.
• Instead the XML processor should be configured to use only a locally defined Document Type
Definition (DTD) and disallow any inline DTD that is specified within user supplied XML
document(s).
• Due to the fact that there are numerous XML parsing engines available for Java, each has its
own mechanism for disabling inline DTD to prevent XXE. You may need to search your XML
parser's documentation for how to "disable inline DTD" specifically.
xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD,false);
• Let's see how the above fix can be applied to our vulnerable example to remediate the XXE
vulnerability.
A7 – XML EXTERNAL ENTITY INJECTION – CÓDIGO CORRIGIDO (JAVA)
public class TradeDocumentBuilderFactory {
documentBuilderFactory.setFeature("https://apache.org/xml/features/disallow-doctype-decl", true);
documentBuilderFactory.setFeature("https://xml.org/sax/features/external-general-entities", false);
documentBuilderFactory.setFeature("https://xml.org/sax/features/external-parameter-entities", false);
} catch(ParserConfigurationException e) {
throw new RuntimeException(e);
}
return documentBuilderFactory;
}
}
A7 – XML EXTERNAL ENTITY INJECTION - REMEDIATION
• The most robust method to protect against XXE attacks is to configure the applications XML
parser to not allow DOCTYPE declarations. This is done by setting the parsers disallow-
doctype-decl parameter to true. With this set, an exception occurs if our trade.xml contains a
DOCTYPE declaration and parsing stops, preventing the vulnerability from exposing sensitive
information.
o RBAC of URLs that denies access by default, requiring explicit grants to users and roles, provides
some degree of mitigation against the failure to restrict URL access attacks.
o Obfuscation of URLs provides some defense against attackers who attempt forced browsing by
guessing the URL.
o Do not cache Web pages containing sensitive information, and when these pages are requested,
make sure to check that the authentication credentials and access rights of the user requesting
access are checked and validated before serving the Web page.
o Authorization frameworks, such as the JAAS authorization framework and the OWASP ESAPI, can be
leveraged.
A7 - MISSING FUNCTION LEVEL ACCESS CONTROL
• (CSRF) attack is unique in the sense that it requires a user to be already authenticated to a site
and possess the authentication token.
• In CSRF, an attacker masquerades (forges) a malicious HTTP request as a legitimate one and
tricks the victim into submitting that request.
• These forged requests can be submitted using email links, zero-byte image tags (images whose
height and width are both 0 pixel each so that the image is invisible to the human eye), tags
stored in an iFrames (stored CSRF), URLs susceptible to clickjacking (where the URL is hijacked,
and clicking on an URL that seems innocuous and legitimate actually results in clicking on the
malicious URL that is hidden beneath), and XSS redirects.
• CSRF is also known by a number of other names, including XSRF, Session riding attack, sea surf
attack, hostile linking, and automation attack.
A8 - CROSS-SITE REQUEST FORGERY (CSRF) - ATTACK
A8 - CROSS-SITE REQUEST FORGERY (CSRF) - ATTACK
2. User is tricked into clicking a link that has a forged malicious HTTP
request to be performed against the site to which the user is
already authenticated.
• The Delete All action is defined as an HTML form tag, which submits a POST HTTP request to
TradeIDEA's /ideas/delete_all URL resource.
• An additional input tag is declared to pass the query parameter scope with the value all as
part of this POST request.
• Finally an HTML button tag is declared to submit the Delete All form with the query
parameter scope=all.
A8 - CSRF (POST) - ATTACK
<html>
<body>
<p>We are experiencing some technical problems. Our website is expected to be back online
shortly.We apologize for the inconvenience.</p>
</body>
</html>
A8 - CSRF (POST) - UNDERSTADING THE SOURCECODE
• Browsing through Bob's malicious HTML, we notice that the web page is programmed to display
a fake "Server Downtime" message, which an unsuspecting victim will believe to be a genuine
website issue.
• Bob has also declared an iframe within his malicious web page that has been styled using the
CSS property display: none to ensure that the iframe is not visible once Alice has
loaded Bob's malicious web page.
Note:We will learn later in the exercise why this iframe is needed for Bob's CSRF attack to work.
• Finally Bob has declared an HTML form tag that submits a POST HTTP request to
TradeIDEA's delete_all method.
• Notice the javascript code on line 10. Any guesses on what this code might do ?
When Bob's malicious web page is loaded by Alice, the javascript method submit() is run against
the HTML form declared on line 7
A8 - CSRF (POST) - UNDERSTADING THE SOURCECODE
Note that the submit() method performs the same action as clicking the "Submit" button within an
HTML form.
• Upon submitting this form, Alice's browser generates an HTTP POST request to
TradeIDEA's /ideas/delete_all resource.
• Given that Alice has already been authenticated to TradeIDEA, the Delete All action invoked
by Bob's web page is seen as a legitimate request made by Alice, thus deleting all her saved
trade ideas.
• This is where the iframe tag comes handy. By creating a hidden iframe, Bob's submit() method
will post the form against this static iframe , thereby ensuring Alice never gets redirected to
TradeIDEA. Instead, she will only see the "Server Downtime" message.
A8 - CSRF (POST) - REMEDIATION
o Defending against CSRF attacks isn't as simple as defending against
XSS attacks. A Synchronizer Token Pattern is required to defend
against CSRF attacks. A Synchronizer Token is also referred to as Anti-
CSRF Tokens, CSRF Tokens, Challenge Tokens, or Nonces.
//
// HTML codebehind for "Delete All" button
//
• Then, when the Delete All form is submitted by Alice, this random token value is checked by
the TradeIDEA application, on the server side.
• Given that Bob's malicious web page cannot guess or know this value beforehand, his
malicious POST request would fail, thereby preventing the CSRF attack against Alice.
• This technique of programmatically inserting random token values in every web page is
known as the synchronizer token pattern.
• The pattern implements the generating of random "challenge" tokens that are associated with
the user's current session, which are then verified for the existence and correctness of this
token on the server side.
A8 - CSRF (POST) - REMEDIATION
Many common development frameworks provide relatively easy to
integrate mechanisms for implementing the protections described in
this tutorial. Rather than re-inventing the wheel it is advisable to use
native features within the existing development framework.
References are provided below:
o Apache Struts
https://struts.apache.org/docs/token-session-interceptor.html
A8 - CSRF (GET)
ATTACK & DEFENSE
A8 - CSRF (GET)
The developers of TradeIDEA2 have recently enabled a new "Delete All" feature that allows bulk
deletion of trade ideas. Before we continue with the exercise, let's analyze this feature in more
detail.
A8 - CSRF (GET) - CÓDIGO VULNERAVÉL
//
// HTML codebehind for "Delete All" button
//
The Delete All action is defined as an HTML a tag, which when clicked by Alice, submits
a GET HTTP request to TradeIDEA2's /ideas2/delete_all URL resource, passing
the querystring scope=all as an argument.
A8 - CSRF (GET) - ATTACK
• Browsing through Bob's malicious HTML, we notice that the web page is programmed to
display a fake "Server Downtime" message, which an unsuspecting victim will notice as a
genuine website issue.
• Bob has also declared an img tag within his malicious web page whose width
height and border properties have been set to 0 thereby ensuring that the img is not visible
once Alice has loaded Bob's malicious web page. Note that the image src is set to
TradeIDEA2's "Delete All" URL.
<html>
<body>
<p>We are experiencing some technical problems. Our website is expected to be back online
shortly.We apologize for the inconvenience.</p>
</body>
</html>
A8 - CSRF (GET) - UNDERSTADING THE SOURCECODE
When Bob's malicious web page is loaded by Alice, her browser will render the HTML markup
of this web page including the hidden img tag.
Notice that within Bob's malicious webapge, the img tag's src parameter is set to TradeIDEA's
"Delete All" URL, which upon successfully loading tricks Alice's browser into generating an
HTTP GET request to TradeIDEA2's /ideas/delete_all resource.
Given that Alice has already been authenticated to TradeIDEA2, the Delete All action invoked
by Bob's web page is seen as a legitimate request made by Alice , thus deleting all her saved
trade ideas.
A8 - CSRF (GET) - REMEDIATION
• It is bad practice to implement Update, Create and Delete operations that rely on
user supplied input via HTTP GET requests, this is an example of misuse of HTTP
Verbs.
• Further, many Java web development frameworks enforce the use of assigning
correct HTTP verbs by default. In general, for a framework agnostic approach, the
following model approach is in line with best practice for CRUD operations in a
database-centric application:
• Do not use the same browser to surf the Internet and access sensitive Web sites at the same
time, if you are accessing both from the same machine.
• Read standard emails in plain text. Viewing emails in plain text format shows the user the
actual link that the user is being tricked to click on by rendering the embedded malicious
HTML links into the actual textual link.
• Use client-side browser extensions that mitigate CSRF attacks. An example of this is the CSRF
Protector, which is a client-side add-on extension for the Mozilla Firefox browser.
A8 - CROSS-SITE REQUEST FORGERY (CSRF) - CONTROLS
Server-side
• The most effective developer defensive control against CSRF is to implement the software to
use a unique session-specific token (called a nonce) that is generated in a random,
nonpredictable, nonguessable, and/or sequential manner. Such tokens need to be unique by
function, page,or overall session.
• CAPTCHAs (Completely Automated Public Turing Test to Tell Computers and Humans Apart)
can be used to establish specific token identifiers per session. CAPTCHAs do not provide a
foolproof defense, but they increase the work factor of an attacker and prevent automated
execution of scripts that can exploit CSRF vulnerabilities.
• The uniqueness of session tokens is to be validated on the server side and not be solely
dependent on client-based validation.
• Use POST methods instead of GET requests for sensitive data transactions and privileged and
state change transactions, along with randomized session identifier generation and usage.
A8 - CROSS-SITE REQUEST FORGERY (CSRF) - CONTROLS
Server-side
• For sensitive transactions, reauthenticate each and every time (as per the
principle of complete mediation).
• Check the URL referrer tag for the origin of request before processing the
request.
• Leverage industry tools that aid with CSRF defense. OWASP CSRF Guard
and the OWASP ESAPI session management control provide anti-CSRF
packages that can be used for generating, passing, and using a unique
token per session.
A8 - CROSS-SITE REQUEST FORGERY (CSRF)
• Web application implies the use of third-party components, such as programming libraries,
APIs to external services (Facebook, Google, Twitter), development frameworks, and many
other components in which programming, testing, and patching have very little or nothing to
do.
• Some vulnerable components (e.g., framework libraries) can be identified and exploited.
• Many applications and APIs have these issues because their development teams don’t focus
on ensuring their components and libraries are up to date.
• The full range of weaknesses is possible,including injection, broken access control, XSS, etc.
• The impact could range from minimal to complete host takeover and data compromise.
• Determining if you are vulnerable requires searching these databases, as well as keeping
abreast of project mailing lists and announcements for anything that might be a vulnerability.
A9 - USING COMPONENTS WITH KNOWN VULNERABILITIES
A9 - USING COMPONENTS WITH KNOWN VULNERABILITIES - CONTROLS
1. As a first suggestion, prefer a known software which is
supported and widely used.
2. Stay updated about security updates and patches released
for the third-party components your application uses.
• SQLiteManager XSS
• Shellshock Vulnerability (CGI)
A10 - UNVALIDATED REDIRECTS
AND FORWARDS
ATTACK & DEFENSE
A10 - UNVALIDATED REDIRECTS AND FORWARDS
• An open redirect occurs when an application takes a parameter and redirects a user to that
parameter value without any conducting any validation on the value.
• This vulnerability is used in phishing attacks to get users to visit malicious sites without
realizing it, abusing the trust of a given domain to lead users to another. The malicious website
serving as the redirect destination could be prepared to look like a legitimate site and try to
collect personal / sensitive information.
• A key to this is a user just needing to visit a URL and be redirected elsewhere. In other words,
you’re looking for a GET request with no user interaction other than visiting a link.
A10 - UNVALIDATED REDIRECTS AND FORWARDS
response.sendRedirect(request.getParameter("url"));
The above code is vulnerable to an attack if no validation or extra method controls are applied to
verify the certainty of the URL. This vulnerability could be used as part of a phishing scam by
redirecting users to a malicious site. If no validation is applied, a malicious user could create a
hyperlink to redirect your users to an unvalidated malicious website, for example:
http://example.com/example.php?url=http://malicious.example.com
A10 - INSECURE URL REDIRECT
ATTACK & DEFENSE
A10 - INSECURE URL REDIRECT
• The vulnerable application pane loads a single sign-on launch page, which users must
click in order to access the Backoffice SSO authentication portal.
• Alice who is an authorized user of TraderWORX web portal has loaded the SSO application in
her web browser.
• Before we demonstrate how URL redirection attacks work, let's start by analyzing
TraderWORX's HTML code, specifically the "Backoffice SSO Login" button.
A10 - INSECURE URL REDIRECT
// HTML codebehind for Backoffice SSO Login button
href="/redirect?url=https://sso.pagseguro.uol.com.br">
</a>
// The "Backoffice SSO Login" button is defined as an anchor link tag, which when clicked
redirect's users to the TraderWORX SSO Login web page.
// The href attribute specifies the TraderWORX SSO Login page destination link as:
redirect?url=https://sso.pagseguro.uol.com.br Note that the URL sso.pagseguro.uol.com.br is
assigned to url parameter, which gets passed as a querystring to TraderWORX's redirect servlet.
A10 - INSECURE URL REDIRECT - CÓDIGO VULNERAVÉL (JAVA)
// The following is a code snippet illustrating the use of insecure URL redirects in Java
In our modified code example, we first call request.getParameter() method to extract Alice's url
parameter value which is then assigned to the url variable.
Finally, an additional input validation check is performed by calling Java's equals() method to
ensure that the url parameter string returned by request.getParameter() matches the URL string
https://sso.pagseguro.uol.com.br
Should the if condition test fail, the doGet method will halt execution and return, without passing
the url parameter to response.sendRedirect.
A10 - INSECURE URL REDIRECT - CONTROLS
• Don't want to be vulnerable? Don't use it. Whenever it's possible, avoid
the use of redirects and forwards.
• If it is necessary to make a redirection, try not to use user-provided
parameters (request variables) to calculate the destination. When the
parameter is not correctly validated, an attacker could abuse it making
it to redirect to a malicious Web site.
https://secdev.wiki.intranet