0% found this document useful (0 votes)
16 views10 pages

OWASP Code Review Guide v2-41-50

Uploaded by

syedsalarsabir
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views10 pages

OWASP Code Review Guide v2-41-50

Uploaded by

syedsalarsabir
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

40 Methodology

Figure 5: Example process diagram for identifying input paths

The Use of Metrics


Throughout The CODE
CODE
Code Review RESUBMITED TREND
SUBMITED
FOR ANALYSIS
Process FOR SCR
RE-REVIEW

RECOMENDED HAS CONTEXT DEFINE CRITERIA


CODE TRIAGE NO OF CODE BEEN PROJECT OR
MEETING DEFINED VULNERABILITY
BASED

YES

STANDARDS POLICIES

PERFORM
REVIEW

COMMUNICATE
GUIDELINES
RESULTS TO TEAM

CODE REVIEW
DATABASE
RECORD
FINDINGS

DEVELOP PREVIOUS
METRICS FINDINGS

PERSIST METRICS
Methodology 41

Cyclomatic complexity (CC):


A static analysis metric used to assist in the establishment of risk and stability estimations on an item of code,
such as a class, method, or even a complete system. It was defined by Thomas McCabe in the 70’s and it is easy
to calculate and apply, hence its usefulness.

The McCabe cyclomatic complexity metric is designed to indicate a program’s testability, understandability
and maintainability. This is accomplished by measuring the control flow structure, in order to predict the diffi-
culty of understanding, testing, maintaining, etc. Once the control flow structure is understood one can gain a
realization of the extent to which the program is likely to contain defects. The cyclomatic complexity metric is
intended to be independent of language and language format that measures the number of linearly indepen-
dent paths through a program module. It is also the minimum number of paths that should be tested.

By knowing the cyclomatic complexity of the product, one can focus on the module with the highest com-
plexity. This will most likely be one of the paths data will take, thus able to guide one to a potentially high risk
location for vulnerabilities. The higher the complexity the greater potential for more bugs. The more bugs the
higher the probability for more security flaws.

Does cyclomatic complexity reveal security risk? One will not know until after a review of the security posture
of the module. The cyclomatic complexity metric provides a risk-based approach on where to begin to review
and analyze the code. Securing an application is a complex task and in many ways complexity an enemy of
security as software complexity can make software bugs hard to detect. Complexity of software increases over
time as the product is updated or maintained.

Cyclomatic complexity can be calculated as:


CC = Number of decisions +1
… where a decision would be considered as commands where execution is branched with if/else, switch, case,
catch, while, do, templated class calls, etc.,

As the decision count increases, so do the complexity and the number of paths. Complex code leads to less
stability and maintainability.

The more complex the code, the higher risk of defects. A company can establish thresholds for cyclomatic
complexity for a module:
0-10: Stable code, acceptable complexity
11-15: Medium Risk, more complex
16-20: High Risk code, too many decisions for a unit of code.

Modules with a very high cyclomatic complexity are extremely complex and could be refactored into smaller
methods.

Bad Fix Probability:


This is the probability of an error accidentally inserted into a program while trying to fix a previous error,
known in some companies as a regression.
Cyclomatic Complexity: 1 – 10 == Bad Fix Probability: 5%
Cyclomatic Complexity: 20 –30 == Bad Fix Probability: 20%
Cyclomatic Complexity: > 50 == Bad Fix Probability: 40%
Cyclomatic Complexity: Approaching 100 == Bad Fix Probability: 60%

As the complexity of software increase so does the probability to introduce new errors.
42 Methodology

Inspection Rate:
This metric can be used to get a rough idea of the required duration to perform a code review. The inspection
rate is the rate of coverage a code reviewer can cover per unit of time. For example, a rate of 250 lines per hour
could be a baseline. This rate should not be used as part of a measure of review quality, but simply to deter-
mine duration of the task.

Defect Detection Rate:


This metric measure the defects found per unit of time. Again, can be used to measure performance of the
code review team, but not to be used as a quality measure. Defect detection rate would normally increase as
the inspection rate (above) decreases.

Re-inspection Defect Rate:


The rate at which upon re-inspection of the code more defects exist, some defects still exist, or other defects
manifest through an attempt to address previously discovered defects (regressions).

6.11 Crawling Code


Crawling code is the practice of scanning a code base of the review target and interface entry points, looking
for key code pointers wherein possible security vulnerability might reside. Certain APIs are related to inter-
facing to the external world or file IO or user management, which are key areas for an attacker to focus on. In
crawling code we look for APIs relating to these areas. We also need to look for business logic areas which may
cause security issues, but generally these are bespoke methods which have bespoke names and cannot be de-
tected directly, even though we may touch on certain methods due to their relationship with a certain key API.

We also need to look for common issues relating to a specific language; issues that may not be security related
but which may affect the stability/availability of the application in the case of extraordinary circumstances.
Other issues when performing a code review are areas such a simple copyright notice in order to protect one’s
intellectual property. Generally these issues should be part of a companies Coding Guidelines (or Standard),
and should be enforceable during a code review. For example a reviewer can reject a code review because
the code violates something in the Coding Guidelines, regardless of whether or not the code would work in
its current state.

Crawling code can be done manually or in an automated fashion using automated tools. However working
manually is probably not effective, as (as can be seen below) there are plenty of indicators, which can apply to
a language. Tools as simple as grep or wingrep can be used. Other tools are available which would search for
keywords relating to a specific programming language. If a team is using a particular review tool that allows
it to specify strings to be highlighted in a review (e.g. Python based review tools using pygments syntax high-
lighter, or an in-house tool for which the team can change the source code) then they could add the relevant
string indicators from the lists below and have them highlighted to reviewers automatically.

The basis of the code review is to locate and analyze areas of code, which may have application security impli-
cations. Assuming the code reviewer has a thorough understanding of the code, what it is intended to do, and
the context in which it is to be used, firstly one needs to sweep the code base for areas of interest.

Appendix C gives practical examples of how to carry out code crawling in the following programming lan-
guages:
• .Net
• Java
• ASP
• C++/Apache
43

A1
44 A1 - Injection

A1 INJECTION

7.1 Overview
What is Injection?
Injection attacks allow a malicious user to add or inject content and commands into an application in order to
modify its behaviour. These types of attacks are common, widespread, an easy for a hacker to test if a web site
is vulnerable and easy and quick for the attacker to take advantage of. Today they are very common in legacy
applications that haven’t been updated.

7.2 SQL Injection


The most common injection vulnerability is SQL injection. Injection vulnerability is also easy to remediate and
protect against. This vulnerability covers SQL, LDAP, Xpath, OS commands, XML parsers.

Injection vulnerability can lead to…


1. Disclosure/leaking of sensitive information.
2. Data integrity issues. SQL injection may modify data, add new data, or delete data.
3. Elevation of privileges.
4. Gaining access to back-end network.

SQL commands are not protected from the untrusted input. SQL parser is not able to distinguish between
code and data.

String custQuery = SELECT custName, address1 FROM cust_table WHERE custID= ‘“ + request.GetParameter(“id”) + ““

Code Data

Using string concatenation to generate a SQL statement is very common in legacy applications where de-
velopers were not considering security. The issue is this coding technique does not tell the parser which part
of the statement is code and which part is data. In situations where user input is concatenated into the SQL
statement, an attacker can modify the SQL statement by adding SQL code to the input data.

1. Untrusted input is acceptable by the application. There are several ways to mitigate injection vulnerability,
whitelisting, regex, etc. The five best ways are. All five should be used together for a defense in depth approach.

1. HtmlEncode all user input.

2. Using static analysis tools. Most static analysis for languages like .Net, Java, python are accurate. However
static analysis can become an issue when injection comes from JavaScript and CSS.

3. Parameterize SQL queries. Use SQL methods provided by the programming language or framework that
parameterize the statements, so that the SQL parser can distinguish between code and data.
A1 - Injection 45

4. Use Stored Procedures. Stored procedures will generally help the SQL parser differentiate code and data.
However Stored Procedures can be used to build dynamic SQL statements allowing the code and data to be-
come blended together causing the it to become vulnerable to injection.

5. Provide developer training for best practices for secure coding.

Blind SQL Injection


Typically SQL queries return search results that are presented to a user. However, there are cases where SQL
queries are happening behind the scenes that influence how the page is rendered, and unfortunately attack-
ers can still glean information based on the error responses from various UI elements. Blind SQL injection is a
type of attack that asks the database true or false questions and determines the answer based on the applica-
tions response.

Effectively the attacker uses SQL queries to determine what error responses are returned for valid SQL, and
which responses are returned for invalid SQL. Then the attacker can probe; for example check if a table called
“user_password_table” exists. Once they have that information, they could use an attack like the one described
above to maliciously delete the table, or attempt to return information from the table (does the username
“john” exist?). Blind SQL injections can also use timings instead of error messages, e.g. if invalid SQL takes 2
seconds to respond, but valid SQL returns in 0.5 seconds, the attacker can use this information.

Parameterized SQL Queries


Parameterized SQL queries (sometimes called prepared statements) allow the SQL query string to be defined
in such a way that the client input can’t be treated as part of the SQL syntax.
Take the example in sample 7.1:

Sample 7.1

1 String query = “SELECT id, firstname, lastname FROM authors WHERE forename = ? and surname = ?”;
2 PreparedStatement pstmt = connection.prepareStatement( query );
3 pstmt.setString( 1, firstname );
4 pstmt.setString( 2, lastname );

In this example the string ‘query’ is constructed in a way that it does not rely on any client input, and the
‘PreparedStatement’ is constructed from that string. When the client input is to be entered into the SQl, the
‘setString’ function is used and the first question mark “?” is replaced by the string value of ‘firstname’, the sec-
ond question mark is replaced by the value of ‘lastname’. When the ‘setString’ function is called, this function
automatically checks that no SQL syntax is contained within the string value. Most prepared statement APIs
allow you to specify the type that should be entered, e.g. ‘setInt’, or ‘setBinary’, etc.

Safe String Concatenation?


So does this mean you can’t use string concatenation at all in your DB handling code? It is possible to use string
concatenation safely, but it does increase the risk of an error, even without an attacker attempting to inject
SQL syntax into your application.

You should never use string concatenation in combination with the client input value. Take an example where
the existence (not the value) of a client input variable “surname” is used to construct the SQL query of the
prepared statement;
46 A1 - Injection

Sample 7.2

1 String query = “Select id, firstname, lastname FROM authors WHERE forename = ?”;
2 if (lastname!= NULL && lastname.length != 0) {
3 query += “ and surname = ?”;
4 }
5 query += “;”;
6
7 PreparedStatement pstmt = connection.prepareStatement( query );
8 pstmt.setString( 1, firstname);
9
10 if (lastname!= NULL && lastname.length != 0) { pstmt.setString( 2, lastname ); }

Here the value of ‘lastname’ is not being used, but the existance of it is being evaluated. However there is still a risk
when the SQL statement is larger and has more complex business logic involved in creating it. Take the following
example where the function will search based on firstname or lastname:

Sample 7.3

1 String query = “select id, firstname, lastname FROM authors”;


2
3 if (( firstname != NULL && firstname.length != 0 ) && ( lastname != NULL && lastname.length != 0 )) {
4 query += “WHERE forename = ? AND surname = ?”;
5}
6 else if ( firstname != NULL && firstname.length != 0 ) {
7 query += “WHERE forename = ?”;
8}
9 else if ( lastname!= NULL && lastname.length != 0 ) {
10 query += “WHERE surname = ?”;
11 }
12
13 query += “;”;
14
15 PreparedStatement pstmt = connection.prepareStatement( query )

This logic will be fine when either firstname, or lastname is given, however if neither were given then the SQL state-
ment would not have any WHERE clause, and the entire table would be returned. This is not an SQL injection (the
attacker has done nothing to cause this situation, except not passing two values) however the end result is the same,
information has been leaked from the database, despite the fact that a parameterized query was used.

For this reason, the advice is to avoid using string concatenation to create SQL query strings, even when using param-
eterized queries, especially if the concatenation involves building any items in the where clause.

Using Flexible Parameterized Statements


Functional requirements often need the SQL query being executed to be flexible based on the user input, e.g. if the
end user specifies a time span for their transaction search then this should be used, or they might wish to query based
on either surname or forename, or both. In this case the safe string concatenation above could be used, however from
A1 - Injection 47

a maintenance point of view this could invite future programmers to misunderstand the difference between safe
concatenation and the unsafe version (using input string values directly).

One option for flexible parameterized statements is to use ‘if’ statements to select the correct query based on the
input values provided, for example:

Sample 7.4

1 String query;
2 PreparedStatement pstmt;
3
4 if ( (firstname!= NULL && firstname.length != 0) &&
5 lastname!= NULL && lastname.length != 0) ) {
6 query = “Select id, firstname, lastname FROM authors WHERE forename = ? and surname = ?”
7 pstmt = connection.prepareStatement( query );
8 pstmt.setString( 1, firstname );
9 pstmt.setString( 2, lastname );
10 }
11 else if (firstname != NULL && firstname.length != 0) {
12 query = “Select id, firstname, lastname FROM authors WHERE forename = ?”;
13 pstmt = connection.prepareStatement( query );
14 pstmt.setString( 1, firstname );
15 }
16 else if (lastname != NULL && lastname.length != 0){
17 query = “Select id, firstname, lastname FROM authors WHERE surname= ?”;
18 pstmt = connection.prepareStatement( query );
19 pstmt.setString( 1, lastname);
20 }
21 else{
22 throw NameNotSpecifiedException(); }

PHP SQL Injection


An SQL injection attack consists of injecting SQL query portions in the back-end database system via the client
interface in the web application. The consequence of a successful exploitation of an SQL injection varies from
just reading data to modifying data or executing system commands. SQL Injection in PHP remains the number
one attack vector, and also the number one reason for data compromises as shown in sample 7.5.
Example 1 :

Sample 7.5

1 <?php
1 $pass=$_GET[“pass”];
2 $con = mysql_connect(‘localhost’, ‘owasp’, ‘abc123’);
3 mysql_select_db(“owasp_php”, $con);
4 $sql=”SELECT card FROM users WHERE password = ‘”.$pass.”’”;
5 $result = mysql_query($sql);
6 ?>
48 A1 - Injection

The most common ways to prevent SQL Injection in PHP are using functions such as addslashes() and mysql_
real_escape_string() but those function can always cause SQL Injections in some cases.

Addslashes :
You will avoid Sql injection using addslashes() only in the case when you wrap the query string with quotes.
The following example would still be vulnerable

Sample 7.6

1 $id = addslashes( $_GET[‘id’] );


2 $query = ‘SELECT title FROM books WHERE id = ‘ . $id;

mysql_real_escape_string():
mysql_real_escape_string() is a little bit more powerful than addslashes() as it calls MySQL’s library function
mysql_real_escape_string, which prepends backslashes to the following characters: \x00, \n, \r, \, ‘, “ and \x1a.

As with addslashes(), mysql_real_escape_string() will only work if the query string is wrapped in quotes. A
string such as the following would still be vulnerable to an SQL injection:

SQL injections occur when input to a web application is not controlled or sanitized before executing to the
back-end database.

The attacker tries to exploit this vulnerability by passing SQL commands in her/his input and therefore will
create a undesired response from the database such as providing information that bypasses the authorization
and authentication programmed in the web application. An example of vulnerable java code is shown in
sample 7.7

Sample 7.7

1 HttpServletRequest request = ...;


2 String userName = request.getParameter(“name”);
3 Connection con = ...
4 String query = “SELECT * FROM Users WHERE name = ‘” + userName + “’”;
5 con.execute(query);

An example of a vulnerable java code


The input parameter “name” is passed to the String query without any proper validation or verification. The
query ‘SELECT* FROM users where name” is equal to the string ‘username’ can be easily misused to bypass
something different that just the ‘name’. For example, the attacker can attempt to pass instead in this way ac-
cessing all user records and not only the one entitled to the specific user

“ OR 1=1.
A1 - Injection 49

.NET Sql Injection


Framework 1.0 & 2.0 might be more vulnerable to SQL injections than the later versions of .NET. Thanks to the
proper implementation and use of design patters already embedded in ASP.NET such as MVC(also depending
on the version), it is possible to create applications free from SQL injections, however, there might be times
where a developer might prefer to use SQL code directly in the code.

Example.
A developer creates a webpage with 3 fields and submit button, to search for employees on fields ‘name’,
‘lastname’ and ‘id’

The developer implements a string concatenated SQL statement or stored procedure in the code such as in
sample 7.8.

Sample 7.8

1 SqlDataAdapter thisCommand = new SqlDataAdapter(


2 “SELECT name, lastname FROM employees WHERE ei_id = ‘” +
idNumber.Text + “’”, thisConnection);

This code is equivalent to the executed SQL statement in sample 7.9.

Sample 7.9

1 SqlDataAdapter thisCommand = new SqlDataAdapter(


2 “SearchEmployeeSP ‘” + idNumber.Text + “’”, thisConnection);

A hacker can then insert the following employee ID via the web interface “123’;DROP TABLE pubs --” and exe-
cute the following code:
SELECT name, lastname FROM authors WHERE ei_id = ‘123’; DROP TABLE pubs --’

The semicolon “;” provides SQL with a signal that it has reached the end of the sql statement, however, the
hacker uses this to continue the statement with the malicious SQL code
; DROP TABLE pubs;

Parameter collections
Parameter collections such as SqlParameterCollection provide type checking and length validation. If you use
a parameters collection, input is treated as a literal value, and SQL Server does not treat it as executable code,
and therefore the payload can not be injected.

Using a parameters collection lets you enforce type and length checks. Values outside of the range trigger an
exception. Make sure you handle the exception correctly. Example of the SqlParameterCollection:
Hibernate Query Language (HQL)

You might also like