A Codelab by Bruce Leban, Mugdha Bendre, and Parisa Tabriz
Most web applications serve static resources like images and CSS
files. Frequently, applications simply serve all the files in a
folder. If the application isn't careful, the user can use a path
traversal attack to read files from other folders that they shouldn't
have access to. For example, in both Windows and
.. represents the parent directory, so if you can
../ in a path you can "escape" to the parent
If an attacker knows the structure of your file system, then they
can craft a URL that will traverse out of the installation directory
/etc. For example, if Picasa was vulnerable to path
traversal (it isn't) and the Picasa servers use a Unix-like system,
then the following would retrieve the password file:
Find a way to read
a running Gruyere server.
Amazingly, this attack is not even necessary in many cases: people often install applications and never change the defaults. So the first thing an attacker would try is the default value.
Find a way to replace
a running Gruyere server.
A denial of service (DoS) attack is an attempt to make a server unable to service ordinary requests. A common form of DoS attack is sending more requests to a server than it can handle. The server spends all its time servicing the attacker's requests that it has very little time to service legitimate requests. Protecting an application against these kinds of DoS attacks is outside the scope of this codelab. And attacking Gruyere in this way would be interpreted as an attack on App Engine.
Hackers can also prevent a server from servicing requests by taking advantage of server bugs, such as sending requests that crash a server, make it run out of memory, or otherwise cause it fail serving legitimate requests in some way. In the next few challenges, you'll take advantage of bugs in Gruyere to perform DoS attacks.
Find a way to make the server quit.
Find a way to overload the server when it processes a request.
Unlike a well defined vulnerability like XSS or XSRF, denial of service describes a wide class of attacks. This might mean bringing your service down or flooding your inbox so you can't receive legitimate mail. Some things to consider:
If you were evil and greedy, how quickly could you take down your application or starve all of its resources? For example, is it possible for a user to upload their hard drive to your application? Entering the attacker's mindset can help identify DoS points in your application. Additionally, think about where the computationally and memory intensive tasks are in your application and put safeguards in place. Do sanity checks on input values.
Put monitoring in place so you can detect when you are under attack and enforce per user quotas and rate limiting to ensure that a small subset of users cannot starve the rest. Abusive patterns could include increased memory usage, higher latency, or more requests or connections than usual.
If an attacker can execute arbitrary code remotely on your server, it's usually game over. They may be able to take control over the running program or potentially break out the process to open a new shell on the computer. From here, it's usually not hard to compromise the entire machine the server is running on.
Similar to information disclosure and denial of service, there is no recipe or specific defense to prevent remote code execution. The program must perform validation of all user input before handling it and where possible, implement functions with least privilege rights. This topic can't be done justice in just a short paragraph, but know that this is likely the scariest results a security bug can have and trumps any of the above attacks.
Find a code execution exploit.
Even though there is no single or simple defense to remote code execution, here is a short list of some preventative measures:
Least Privilege: Always run your application with the least privileges it needs.
Application Level Checks: Avoid passing user input
directly into commands that evaluate arbitrary code,
system(). Instead, use the
user input as a switch to choose from a set of developer controlled
Bounds Checks: Implement proper bounds checks for non-safe languages like C++. Avoid unsafe string functions. Keep in mind that even safe languages like Python and Java use native libraries.
© Google 2010 Terms of Service
The code portions of this codelab are licensed under the Creative Commons Attribution-No Derivative Works 3.0 United States license <http://creativecommons.org/licenses/by-nd/3.0/us>. Brief excerpts of the code may be used for educational or instructional purposes provided this notice is kept intact. Except as otherwise noted the remainder of this codelab is licensed under the Creative Commons Attribution 3.0 United States license <http://creativecommons.org/licenses/by/3.0/us>.