Secure Development - Denial of Service Attacks

Jun 16 2010

No matter how well-written or secure your application is, Denial of Service (DoS) attacks always pose a risk. Most web applications are publicly accessible by design, so the server/application really has no way to tell 10,000 legitimate user requests from 10,000 malicious requests designed to bring it down. If a DoS attack originates from a single source or from a few sources, it can be blocked fairly easily once the source(s) are identified. Unfortunately, most DoS attacks today are actually DDoS attacks (distributed DoS), which means that they originate from hundreds or thousands of different places across the Internet, most commonly from botnets. This makes it nearly impossible to shut down the malicious traffic without also cutting off the legitimate users...which is exactly the point of a DoS attack.

Some common types of DoS attacks are the following:

  • Exhaustion of limited pooled resources: bandwidth, database connections, disk storage, CPU, memory, threads
  • Attacking resources limited to a particular user, i.e. user lockout or password change
  • Causing an unhandled exception, leading to a crash of the application

The biggest way in which developers make their applications more susceptible to DoS attacks is by providing resource-intensive functionality to unauthenticated users. This allows an attacker to make repeated requests and quickly exhaust the server's resources. Here are some additional mitigation techniques you can use against DoS attacks:

  1. Limit actions of unauthenticated users - Make sure that users must authenticate before they can perform resource-intensive operations (large uploads/downloads, complex database operations, etc.). Additionally, you may want to restrict multiple logins from the same username from different IP addresses. This raises the bar for an attacker significantly since he would need to have a separate, valid login account for each of his DoS bots.
  2. Optimize database queries - Your database schemas should use the correct data types and indexes to facilitate your most common queries. Query optimization is a separate science unto itself, but the basic idea is to ensure you are fully using the features of your database to support your application's operations. A few tips: avoid wildcard string queries, use integer/time/date range queries, use indexed table joins instead of subqueries when possible.
  3. Cache frequently used data - With ever-decreasing storage costs, caching results of complex operations is increasingly attractive, especially when it can be utilized by many different users. There are three main levels of caching in the web application realm:

    1. Shared server-side caching - Certain objects may be shared by all components/users of your application, and they are perfect candidates for caching at the application level. For example, you can pre-compute complex database results and store them in temporary tables. Be sure to put database triggers in place to update these cached tables when the source data changes.
    2. Session-scope caching - While this data cannot be shared by multiple users, it can be reused by the same session over and over with little performance penalty. For example, you can build custom drop-down menus from the database at the start of a session, then store them in a session variable to avoid future database hits. If the menus change, they will be updated the next time the user logs in.
    3. Client-side caching - While HTML5 is bringing some major improvements in this space, there is currently no standard mechanism specifically designed for selective client-side caching. Cookies are often "abused" for this purpose, but there are many security and logistical issues with this approach. In general, you should carefully weigh the benefits of client-side caching against the risks of exposing user data and the internals of your application to the unknown environments on your users' computers.
  4. Design smart lockout mechanisms - If an inflexible lockout policy is in place, the easiest DoS attack in the world is to guess common usernames (or better, obtain a list of valid usernames) and then purposely try three incorrect passwords for each of them. The next day, all or most of your users will be locked out and your helpdesk will be overwhelmed with calls... A better approach would be to temporarily lock the account after X attempts, and then unlock it again after Y minutes of no failed attempts. This will still slow down bulk online password guessing to a crawl while largely defeating such a "lockout DoS" attack.
  5. Limit size of uploaded data - If your application allows users to upload data, make sure there are strict limits on its size (both per-upload and per-user total). As indicated in 1. above, any upload functionality should ideally be restricted to logged-in users.

Keep in mind that these techniques are not designed to prevent DoS attacks, merely to lessen their impact and make it harder to DoS your application. Even if you follow all of these guidelines, a botmaster with access to several thousand distributed bots can take down almost any website simply by having each bot visit the home page every few seconds.

Next week, we will conclude the OWASP Top 10 list with an unlikely subject: buffer overflows. While most modern languages (such as Java) no longer allow direct memory access, there are still some security issues to keep in mind, especially when interfacing with legacy back-end systems.

About the Author

Daniel is a business and technical systems analyst with a background in IT security and software development. He has six years experience in the IT security field, including published academic research. His main areas of expertise include software assurance, network security, and authentication. In addition to security, Daniel has a software development background in languages such as Java, Perl, SQL, and PHP. He also has 14 years experience working with and administering various versions of Linux and related open-source software.

 

Disclaimer

The words and opinions expressed here are those of each article's respective author, and do not necessarily represent the views of CapTech Ventures.