devtutor: How to Avoid Using Parent Paths

What is Parent Pathing?

A good deal of web scripters start first in the HTML realm and later learn how to develop server-side scripts.  Unfortunately, most of us also bring a bad HTML habit with us into the scripting realm: the use of parent pathing.  The use of parent paths refers to the technique of "addressing up" a directory level and then going elsewhere.

Parent Path Example:

If I'm currently working on a page with a URL of http://ase.tufts.edu/its/webParentPath.htm and need to access an image (using an <img/> tag) located at http://ase.tufts.edu/its/images/image.gif, my HTML source would look like so...

<img src="../images/image.gif">

The "../" in the src property is the parent path which basically says "move up on level to its and then down through images to image.gif.

Basically, parent pathing allows you to address resources relative to the object (HTML page, script page, etc.).  While this is fine to do in straight HTML, there are quite a few security issues caused by parent pathing in scripting.  As such, the default setting for parent pathing for sites hosted on in the Arts & Sciences web hosting environment is off.  Thus, another method needs to be used to avoid needing to use parent pathing.  The best method to avoid parent pathing is using Root Relative Pathing.

What is Root Relative Pathing?

The use of root relative pathing refers to the technique of addressing resources relative to the root of the site.

Root Relative Path Example:

If I'm currently working on a page with a URL of http://ase.tufts.edu/its/web/webRootRelative.htm and need to access an image (using an <img/> tag) located at http://ase.tufts.edu/its/images/image.gif, my HTML source would look like so...

<img src="/its/images/image.gif">

The first "/" in the src property specifies that the address is root relative which basically says "from http://ase.tufts.edu, go down through its to images and finally to image.gif

The use of root relative pathing, therefore, allows resources to be accessed from a "top down" approach rather than from a file relative approach.  One very nice side effect of using root relative pathing is that it is extremely easy to do global find/replaces if you need to move resources (i.e. just search for "/its/images/image.gif" and replace with "/its/images/new/image.gif" if the name of the image was to be moved into a new subdirectory).  This isn't all that easy to do if you were using parent pathing because, depending on the directory structure of your site, the number of parent "../" to include in the global find/replace wouldn't be as predictable.

Root Relative Pathing and Include Files

Many sites (especially ASP sites) make use of Include files to encapsulate commonly used code into a central location.  Unfortunately, many of us also use a parent pathing method of addressing these files.

Include File Parent Pathing Example:

If I'm working on a page with a URL of http://ase.tufts.edu/its/webIncludeParentPath.asp and need to include an Include file located at http://ase.tufts.edu/its/includes/include.inc, my include directive would look like this...

<!-- #Include File="../includes/include.inc" -->

As in the <img/> example above, the "../" parent path implies that the address needs to move up one level to its before going through includes to include.  As sites hosted in the A&S web hosting environment should be avoiding parent paths, include files should be addressed in a root relative fashion.

Include File Root Relative Example:

If I'm working on a page with a URL of http://ase.tufts.edu/its/webIncludeRootRelative.asp and need to include an Include file located at http://ase.tufts.edu/its/includes/include.inc, my include directive would look like this...

<!-- #Include Virtual="its/includes/include.inc" -->

The Virtual directive implies that the pathing starts at http://ase.tufts.edu and can then move through its to includes and finally to include.inc.

Determining the Absolute Path from a Root Relative Path for use in Server Side Script

If you site makes use of file IO in any of its server side script, it is often necessary to know the absolute path of the file so it can be properly accessed.  While some sites may hard code this value into an include file for use, this is typically not an optimal technique.  If an absolute path is hard coded into an application, the application looses a great deal of flexibility.  If, the site is moved to a different directory for any reason (sometimes prompted by disk usage and expansion), the script will break.  It is therefore preferable to create a routine to determine the absolute path based on the root relative path.  In ASP and ASP.NET, this can easily be accomplished using the Server object.

Determining the Absolute Path from the Root Relative Path Example:

If I need to determine the absolute path of http://ase.tufts.edu/its/database/myDb.mdb, I would only need to realize that the root relative path is "its/database/myDb.mdb", and then the Server object can do the rest of the work.  In ASP (using VBScript) the code would look like this...

Dim strDatabasePath
strDatabasePath = Server.MapPath("/its/database/myDb.mdb")

In ASP.NET (using C#) the code would look like this...

string strDatabasePath = Server.MapPath("/its/database/myDb.mdb");

Obviously, as you can then accomplish absolute path navigation in your code by doing the appropriate substitutions on the absolute path we have just obtained.

Please note, it seems that under the .Net v1.0 Framework, this method will not produce the desired results if the sub-directory you are targetting is actually a virtual directory.  For example, if the "database" sub-directory was actually a virtual directory that lived outside of the "its" pathing structure, the MapPath method would return a result as if the "database" sub-directory was actually inside the "its" pathing structure.

Determining the Absolute Directory Path from an Absolute File Path

If I need to know the absolute directory path of http://ase.tufts.edu/its/dabase/ (for file listing, etc.), we simply make use of the absolute file path we determined above.

Determining the Absolute Directory Path from an Absolute File Path Example:

Using ASP & VBScript, the code would look like this...

Dim strDatabase
strDatabase = Server.MapPath("/its/database/myDb.mdb")
strDatabase = Replace(strDatabase, "myDb.mdb", "")

In ASP.NET & C#, the code would look like this...

string strDatabase = Server.MapPath("/its/database/myDb.mdb").Replace("myDb.mdb","");

Replicating Parent Pathing Functionality Using Root Relative/Absolute Pathing

While the use of parent pathing is something that you should try to avoid in general, there are times when it is really quite necessary. For example, let's say your script needs to access a data file that is placed completely outside of the web root (for security purposes), but is located relative to the web root. In such a case, you'd need to replicate parent pathing functionality using a combination of root relative and absolute pathing.

This is done by first determining the absolute path of your starting point, then moving up the directory structure in the required number of steps, and finally, moving down to the file you're trying to access.

Replicating Parent Pathing Functionality Using Root Relative/Absolute Pathing Example:

For this example, let us assume that our script is at http://ase.tufts.edu/its/parentPath.asp(x). Furthermore, there is a directory called "dataStorage" that is on the same level (and, thus, outside) of the web root directory (called "wwwroot"). Finally, the file we're trying to access named "myDb.mdb" is located in a sub-directory of "dataStorage" called "its". If we were to use parent pathing to access this file the path would be...

../../dataStorage/its/myDb.mdb

To access this file by the method I described above, the code would look something like this using ASP & VBScript:

' First, get the absolute path of our starting point.
Dim strDatabase
Dim intCount
Dim intPosition
strDatabase = Server.MapPath("/its/parentPath.asp")
' We now have the absolute path to our starting point.

' Now, we need to address the directory of our starting point
'  and then move up two levels.
strDatabase = Replace(strDatabase, "\parentPath.asp", "")
For intCount = 1 To 2
intPosition = InStrRev(strDatabase, "\")
strDatabase = Left(strDatabase, (intPosition - 1))
Next
' We now have the absolute path of the directory
'  containing "wwwroot" and "dataStorage".

' Finally, we need to move down the structure to the file.
strDatabase = strDatabase & "\dataStorage\ite\myDb.mdb"
' File path determined!

In ASP.NET & C#, the code would look like this:

// First, get the absolute path of our starting point.
string sDatabase = Server.MapPath("/its/parentPath.aspx");

// Now, access the directory of the starting point
//  and then move up two levels.
sDatabase = sDatabase.Replace("\\parentPath.aspx", "");
for (int iCount = 0; iCount < 2; iCount++)
{
int iPosition = sDatabase.LastIndexOf("\\");
sDatabase = sDatabase.Substring(0, iPosition);
}

// Finally, move down the structure to the file.
sDatabase += "\\dataStorage\\its\\myDb.mdb";

My thanks to Mike Hosking for posing the question of how to access files outside the web root without using parent paths.

Conclusion

As you can see, with just a bit of planning, your site's code need not depend upon parent pathing.  This will enable you to make use of a secure and more predictable site.  Please email any comments regarding this tutorial to Will Hilley.  Enjoy!!!


Web Services
 ITSearch   Go
  © 2012 Tufts University. All rights reserved.