Securing Web Applications

If you are developing a web application, almost every design decision you make can introduce a security flaw if you get it wrong. Although attacks are becoming more common, and more widely reported, the same common errors continue to provide the most opportunities for hackers. OWASP provides a 'top ten' security problems. Vishwas here describes them and explains how to avoid them

Now that enterprises are increasingly adopting open source software to cut down their software costs, the business stakeholders, technical architects, Website managers now own a greater share of the responsibility of ensuring that only the best security practices are employed as part of the development lifecycle. Although Open Source software is increasingly reliable, available and scalable; we can no longer rely on a vendor to do the worrying for us about security if we no longer purchase commercial off-the-shelf (COTS) software.

So what security measures do we employ?

Thanks are due to the Open Web Application Security Project (OWASP); a worldwide not-for-profit charitable organization that is dedicated to improving the security of software. This community focuses on the top threats to cater for, so that individuals and organizations are able to make informed decisions about what is necessary for application security throughout the development life cycle of the software product.

OWASP develops standards and provides guidance on development, testing, and tools. The community lists what they suggest are the top 10 threats for web applications. This helps us with assigning priorities to our security efforts so we can ensure that we identify and fix those flaws that pose the maximum risk.

According to the latest 2013 OWASP threat assessment, following are the top 10 in the order of priority.

  1. Injection
  2. Broken Authentication and Session Management
  3. Cross-Site Scripting (XSS)
  4. Insecure Direct Object References
  5. Security Misconfiguration
  6. Sensitive Data Exposure
  7. Missing Function Level Access Control
  8. Cross-Site Request Forgery (CSRF)
  9. Using Known Vulnerable Components
  10. Invalidated Redirects and Forwards

In this article, I’ll describe each of these threats, what they imply, and the sort of measures we would need to mitigate them.

Injection

SQL Injection is the most common form of attack, and it can severely compromise server operations, especially where developers use ‘dynamic SQL’. If user input is not checked, it is possible for a user to introduce SQL commands that can be executed by the database if database-level access control is lax. Where parameters are not used within the interface with the database, SQL can be easily introduced into any user input.

By providing a way for attackers to execute SQL, they can enable the user to read data, and possibly even delete or update it.

An attack could be launched as simply as by modifying the user-input parameters to change the logic of a SQL Statement executed on the server side.

Here is a login page which takes userName and passcode as input fields.

User Name

Scott

Password

Tiger

Our hapless developer has devised the following server side code:

SQL executed on the server side would be:

and if the rowcount returned is greater than 0 the application knows it is a valid user.

Watch, now, what happens when an attacker manipulates the input parameters as follows:

User Name

‘ or ‘1’=’1

Password

‘ or ‘1’=’1

SQL executed on the server side (Oracle in this instance) would be:

The above SQL would always fire successfully allowing the attacker to bypass validation since WHERE ‘1’=’1′is always true!

Sample 2:

In our next example, a webpage takes in the name of an author to provide, in response, a list of books written by the author.

Author

Scott

Result:

Book 1

Book 2

Author Scott as two books written displayed as above. Let’s look at the following server side code

SQL executed on the server would be:

What if an attacker provides the following input?

Author

‘; DELETE from books where 1=1 or author = ‘

SQL executed on server side would be:

Since the database can take batched inputs, it would execute the second query right away, leading to loss of entire data table on books!

Prevention Measures

A common theme of these two examples is that the incoming untrusted user-inputs have been blindly accepted without any attempt at validation. Purely by good coding practice within the application, one can make such attacks extremely difficult by using parameterized queries and input validation. This would be part of a defense in depth that includes database access control that restricts database permissions to just what is necessary for them for their legitimate use of the system.

Parameterized Queries

SQL parameters are values that are added to an SQL query at execution time, and the execution plans are cached and reused every time the parameterized query is executed. When a bind variable is passed as an argument to an SQL prepared statement, it is automatically escaped by the ODBC or JDBC driver. The resulting escaped strings treat the variable as user data and they cannot be interpreted by the database server as an SQL statement. Therefore, any user-supplied data will be escaped before it is added to an SQL statement.

The setString method of the prepStmt object escapes the authorName string and adds it to the SQL statement. Any malicious SQL statements passed in through the authorName variable is rendered as non-executable in the escaped version of the input.

Input validation

Client-side Input validation minimizes the risk and is easy to implement on existing applications. Some web developers use a “blacklist” of words or characters to search for SQL input, to prevent SQL injection attacks. This security mechanism is not effective since the blacklist has to be maintained quite frequently over time. Time tested approach would be to follow the opposite, i.e.: a whitelist approach.

In whitelist validation, you specify a set of patterns or characters you can allow in an input field. Anything which doesn’t match the pattern is blocked automatically.

Example: if the expectation on a field is a positive integer, the following regular expression will ensure that anything entered is always a number “^[0-9]+$”

Broken Authentication and Session Management

An attacker can impersonate users by using leaks or flaws in the authentication management or session management functions. Poor session control, weak password recovery, insecure server transmissions, insecure storage of credentials, inadequate session timeouts etc. are some of the flaws an attacker can use to gain access to user accounts. Public exposure of such vulnerability can severely hamper the reputation of an organization.

Scenario #1: Airline reservations application supports URL rewriting, putting session IDs in the URL:

An authenticated user of the site wants to let his friends know about the sale. He e-mails the above link without knowing he is also giving away his session ID. When his friends use the link they will use his session and his personal account details such as credit card information by impersonation.

Scenario #2: A User uses a computer in an internet café or other public area to use an internet application. Instead of selecting “logout” the user simply closes the browser tab and walks away. If an application timeout is not set on the session, Attacker can use the same browser an hour later, and that browser would be still authenticated.

Scenario #3: The Insider or external attacker gains access to the system’s password database. If an application is storing plain text passwords, the attacker could expose every user’s password on any public domain.

The following are the most obvious loopholes which can leave your application vulnerable to this threat.

  • User authentication credentials aren’t protected when stored using hashing or encryption.
  • Credentials can be guessed or overwritten through weak account management functions (e.g., account creation, change password, recover password, weak session IDs).
  • Session IDs are exposed in the URL (e.g., URL rewriting).
  • Session IDs don’t timeout, or user sessions or authentication tokens, particularly single sign-on (SSO) tokens, aren’t properly invalidated during logout.
  • Session IDs aren’t rotated after successful login.
  • Passwords, session IDs, and other credentials are sent over unencrypted connections.

Prevention Measures

User Logins

  • Always use encrypted forms for user login.
  • Validate form input.
  • Avoid using remember me functionality with mission critical applications.
  • Provide users with a logout button to manually terminate a session
  • Consider supporting third-party authentication providers such as Google or Facebook.

Password Policies

  • Provide two-factor authentication features
  • Expire all current sessions after changing passwords
  • Notify users of password changes via email or SMS
  • Ensure that passwords have an expiration date, and force a reset when necessary.
  • Implement strong complex password requirements

Session Control

  • Use strong random number generators to ensure you have a sufficiently long session Id
  • Store session ids in cookies and never pass them via URL parameters, hidden form fields, or custom HTTP headers
  • Use standard frameworks to handle security rather than writing your own custom session management systems
  • Set absolute time limits on session identifiers to ensure proper session expiration

Cookie Security

  • Store session identifiers in session cookies rather than persistent cookies.
  • Set Secure cookie attribute to ensure such are transmitted over secure connections.
  • Set HttpOnly cookie to ensure scripts cannot access these cookies via DOM object.

Cross-Site Scripting (XSS)

Cross-Site Scripting (XSS) attacks are also a type of injection attack, in which malicious scripts are injected into trusted web sites. These attacks occur when an attacker uses a web application to send malicious code to a different end user, generally in the form of a browser-side script. Flaws that allow these attacks can occur anywhere that a web application unwisely uses input from a user within the output it generates without validating or encoding it.

Although cross-site scripting is a form of injection, it is unique in both scope and target and needs its own classification. Attacker could access and modify the structure, appearance, and behavior of browser content or simply redirect the user to a site that contains malicious content. The end user’s browser has no way to know that the script should not be trusted, and will execute the script. Because it thinks the script came from a trusted source, the malicious script can access any cookies, session tokens, or other sensitive information retained by the browser and used with that site. These scripts can even rewrite the content of the HTML page.

These XSS attacks fall mainly into two categories: Stored and reflected attacks

Stored XSS Attack, also known as a persistent attack, where an attacker sends malicious input that is later stored in the application’s database. The malicious input is then displayed as a normal part of the site’s content. When a user views or requests the stored content, the malicious code is executed.

For example, below is simple post from an attacker which could redirect an authenticated user cookie to attacker’s website. All an attacker has to do is to place the code in any posted input (i.e.: message boards, comments, or even one-one messages):

The above code will pass an escaped content of the cookie to cookieGrabber.php script in a “cookieInfo” variable. The attacker then can check the results of cookieGrabber.php script (This could very well write the information to a persistent store like a file or database) and hijack the user’s session.

Reflected XSS Attack, also known as a non-persistent attack, where an attacker gets the user to send malicious input to a particular URL.

For example, sending the user an email with a link to click. By clicking the link, the victim sends the malicious input to the web application which then uses that input to generate a response.

This will cause the user, clicking on the link supplied by the attacker, to download and execute a file malicious.exe which could provide remote administration capabilities to the attacker.

Prevention Measures

  • For all user inputs, use a whitelist validation approach as defined above in SQL Injection section.
  • For all user inputs, use blacklist validation to filter or block any known specific set of untrusted code patterns
  • Consider auto-sanitization libraries like OWASP’s Java HTML Sanitizer Project.
  • Explicitly define character encoding and output mime types.
  • Turn off HTTP TRACE support on all webservers. An attacker can steal cookie data via JavaScript even when document.cookie is disabled or not supported on the client utilizing the underlying asynchronous HTTP trace event triggered by the system to collect client cookie information from the server.

Insecure Direct Object References

When a critical resource in your application (an object, file or database key) is not subject to access control, this provides an opportunity for attackers who can use these unprotected resources and gain access to confidential information which may not belong to them.

The attack could be carried out simply, by changing a parameter value that refers to an object for which the user hasn’t the necessary authorization.

In the sample below, let’s suppose that an account-retrieval page has the following logic on the server side:

An attacker can simply change the acct variable that was passed in via the page’s query string to verify details on an account he does not own!

http://example.com/app/accountInfo?acct=some_other_acct

Prevention Measures

To protect against this threat, the only viable solution is to secure objects via access control. The logged-in user needs to be authorized for the requested information before the server responds a query even when the underlying session is pre-authenticated.

For example, in above case you can make that query to retrieve accounts rather more intelligent by providing the context of the logged in user session:

String query = “SELECT * FROM user_accounts WHERE account = ? and userId = “loggedInUser_OrgId” “;

Security Misconfiguration

These vulnerabilities arise when the security configuration on the application has not been kept up-to-date. The attacker can access default accounts, unused pages, unpatched OS flaws, unprotected directories or files etc. to gain server-side information. These vulnerabilities may prevail anywhere across the application stack – and could be in such places as the load balancer, webserver, application server, client slide custom scripts or database. Most of these are common errors and these are the preferred attack vectors that attackers can exploit.

Some of the sample attack scenarios of these attacks that are referenced in OWASP are:

Scenario #1: The admin console of the app server is automatically installed and not removed. Default accounts aren’t changed. The attacker discovers where the standard admin pages are on your server, logs in with default passwords, and takes over.

Scenario #2: Directory listing is not disabled on your server. Attackers can simply list directories to find any file. They can, for example, find and download all your compiled Java classes, which can be decompiled and reverse-engineered to get all your custom code. By doing so, they can find any serious access control flaws in your application.

Scenario #3: The app server configuration allows stack traces to be returned to users, potentially exposing underlying flaws. Attackers love all the extra information that error messages provide.

Scenario #4: The app server comes with sample applications that are not removed from your production server. These sample applications have well-known security flaws that attackers can then use to compromise your server.

Prevention Measures

  • Ensure that all components such as the OS, webserver, app server, load balancer, database etc. have the latest security updates.
  • Disable all default accounts.
  • Set the server-side directory permissions to least necessary that is required to run the application.
  • Secure the log files and ensure periodic audits.
  • Deploy the web application with only those modules that are actually required.
  • Ensure that you have authorization controls on sensitive modules.
  • Secure by an Access Control List (by IP addresses) for restricted access on the server file system.
  • Perform a periodic web-vulnerability scan.

Sensitive Data Exposure

Sensitive data exposure occurs due to insecure cryptographic storage on your data at rest, in transit or even in the user browser. Strong encryption would be fundamental in securing your sensitive information. Common issues such as failure to encrypt passwords, using custom or old algorithms (such as MD5 or SHA1), poor key managements or un-patched servers are some of the vulnerabilities an attacker can exploit.

Prevention Measures

Because of the range of the threats that you need to protect this data from (e.g., insider attack, external user), you must make sure you encrypt, sufficiently, all sensitive data at rest and in transit.

  • Do not store sensitive data unnecessarily. Data that you don’t have can’t be stolen.
  • Disable ‘autocomplete’ on all forms that collect sensitive data, and disable caching for pages that contain sensitive data.
  • Utilize the SALT technique in creating password hashes. A salt is random data added to the hashing process to ensure that every hash of a password produces a unique result which would ensure that an attacker must always compute the hash in a brute-force attack.
  • Ensure that passwords are stored with an algorithm that is specifically designed for password protection, such as bcrypt, PBKDF2, or scrypt.
  • Ensure that the transport layer is secured via TLS. Avoid SSL, which was used before it was deemed unsafe due to its significant security flaws. Ensure that the application supports at least TLS v1.0. There are upgraded versions up to TLS v1.2 available, which should be used when possible.
  • Ensure that server certificates are up-to date, and ensure that you use standard digital certificate providers as mentioned in https://en.wikipedia.org/wiki/Certificate_authority,

Missing Function-Level Access Control

This vulnerability allows an attacker to get elevated privileges to access sensitive functional modules within the application. Often this is caused due to improper development or improper configuration rules on the server side.

Consider an example of two portals within an application

  • http://example.com/app/getappInfo Provides General User specific information on the application
  • http://example.com/app/admin_getappInfo Provides application wide information and Admin capabilities on the application to add or delete sensitive configuration records

Let’s assume these two portals require different sensitivity levels for an authorized user. Now:

  • If an unauthenticated user can access either page, that’s a flaw.
  • If an authenticated, non-admin, user is allowed to access the “admin_getappInfo” page, this is also a flaw and may lead the attacker to more improperly protected admin pages.

Prevention Measures

  • Deny access to all sensitive pages and functions by default.
  • Consider role-based security to define clear boundaries for user access and re-check user roles every time before allowing access to sensitive functions, data, files, URLs, and services.
  • Centralize authorization functions and policy management.
  • Always make authorization decisions on the server side.

Cross-Site Request Forgery (CSRF)

The Cross-site request forgery (CSRF) exploit uses cross-site scripting (mentioned above), browser insecurities, and other techniques to cause a user to unwittingly perform an action within their current authenticated context that allows the attacker to access the user’s account. This type of attack usually occurs when a malicious email, blog, or a message causes a user’s Web browser to perform an unwanted action on a trusted site for which the user is currently authenticated.

Let’s assume https://www.SampleBankPortal.com has CSRF vulnerability. An attacker could setup a CSRF attack as follows.

Attacker setup’s a 1X1 Pixel on https://www.malicioussite.com which fails to load and goes unnoticed by a victim entering this site. This Pixel has the following code:

If the victim has pre-logged in on www.SampleBankPortal.com on his browser before visiting the malicious Site, browser would auto execute the script within the img tag and the server side for exampleBankPortal would execute this request considering it has been generated from a pre-authenticated user session!

Prevention Measures

  • Include a unique unpredictable runtime generated token in a hidden field for all requests to the server. This causes the token value to be sent in the body of the HTTP request and avoids its inclusion in the URL. The server would then validate such token before executing the request.
  • Require users to re-authenticate when performing critical sensitive operations can be another measure to prevent CSRF.
  • Have strong measures for re-authentication such as Captcha, 2 step verification processes to exclude BOT activity.

Using Known Vulnerable Components

Let’s imagine that you are using open source software which has a flaw recently discovered. This information has already been made public to the community. An attacker could also get to hear about it and exploit such flaws by launching extensive automated scripts to list all vulnerable sites utilizing search engines. Given the fact such flaws usually take some time to get patched, attackers can, in the meantime, exploit the vulnerability to steal sensitive information.

Prevention Measures

  • Before you use any third party libraries, you must be confident that open-source developers on such apps are carefully vetted and there is a detailed security review before they are used in your production environment.
  • Stay up to date with all reports of vulnerabilities via mailing lists, RSS feeds etc. and check on all possible repercussions on your application.
  • Do not disclose the version numbers of any software components anywhere on your application

Invalidated Redirects and Forwards

Web applications which use some sort of visible URL redirects to perform activities such as page navigation or post user authentication redirects are vulnerable to these attacks. Such a visible redirect exposes the user to a phishing attack where an attacker could route the user to a malicious website and exploit the session or install malware on user’s computer.

As an example, imagine that we have an application which redirects the user by passing in the URL as a parameter:

The attacker could manipulate the user by changing this URL parameter in order to redirect to a malicious site that performs phishing.

Prevention Measures

  • Consider adopting a single-page-application design, where the underlying navigation URL is not exposed to the end user.
  • Simply avoid using redirects and forwards.
  • If used, don’t involve user parameters in calculating the destination.
  • If destination parameters can’t be avoided, ensure that the supplied value is valid, and authorized for the user. It is recommended that any such destination parameters be a mapping value, rather than the actual URL or portion of the URL, and that server side code translate this mapping to the target URL.

Conclusion

Application security isn’t an afterthought; it is intrinsic to the day-to-day design of the application. Security risks and standards change rapidly, so whether you are new to web application security or are already familiar with security risks, you should establish and use repeatable and up-to-date security processes and standard security controls. This could be an overwhelming task if you are already managing a large portfolio. To assist organizations in verifying the security of their applications there are numerous free and open resources on OWASP Projects that we can use. It pays to augment your current code-review process to include a scrutiny of security as a constant part of the daily routine. Tools such as FindBugs and its new plugin FindSecurityBugs can be leveraged to identify security flaws. Application penetration tools such as ZAP can be used to intercept web application requests to figure out how the application works, and then submit test requests to see if the application responds securely to such requests. Last but not least, achieving application security requires many different parts of an organization to work together efficiently, including security and audit, software development, and business and executive management. It requires security to be visible, so that all the different players can see and understand the importance of security in any organization’s security.

References

  1. https://www.owasp.org/
  2. http://www.w3schools.com/Sql/sql_injection.asp
  3. https://www.ibm.com/developerworks/library/se-bindvariables/
  4. http://findbugs.sourceforge.net/index.html
  5. http://find-sec-bugs.github.io/
  6. https://www.incapsula.com/web-application-security/reflected-xss-attacks.html
  7. https://en.wikipedia.org/wiki/Bcrypt
  8. https://en.wikipedia.org/wiki/PBKDF2
  9. https://en.wikipedia.org/wiki/Scrypt
  10. https://en.wikipedia.org/wiki/Transport_Layer_Security