This site graciously hosted
by our friends at




Analysis of Topical Vulnerabilities

07 February 2004

Several days ago, a message was posted to BugTraq concerning an interesting array of vulnerabilities discovered in the widely-distributed PHP e-commerce application, X-Cart. Following is the relevant text of the posting...

We have discovered some security related bugs in X-Cart Version 3.4.3.
It is possible that other versions are vulnerable too.

Any visitor can view any file on the web server.
This URL my be used as proof of concept:
http://servername/customer/auth.php?config[General][shop_closed]=Y&shop_closed_file=../../../../../../../etc/passwd

Moreover, any visitor can execute any command on the server, if the command is allowed for the account used to run web server.
The urls used for test look like
http://server/admin/upgrade.php?prepatch_errorcode=1&patch_files[0][orig_file]=VERSION&perl_binary=/bin/rm -rf &patch_exe=..
http://server/admin/general.php?mode=perlinfo&config[General][perl_binary]=/bin/ls -lR ||

There are information leaks in this application.
Thse following URL discloses sensitive information to any visitor.
http://server/admin/general.php?mode=phpinfo
http://server/admin/general.php?mode=perlinfo
We find it particularly intriguing (from an academic standpoint, of course) that each of the aforementioned proof-of-concept exploits take advantage of a single common mistake: poor (or nonexistant) input validation. By crafting a malicious URL, an attacker can easily coax irresponsible code such as this into executing a dangerous shell command, divulging sensitive information, or both. Obviously, this is NOT cool!

What IS cool, however, is that mistakes such as these can easily be avoided, and potential disasters averted. Specifically, let's consider a layered approach in which precautions are taken at both the application and operating system levels.

That being said, dealing with the problem at the application level should probably involve some sort of input validation mechanism. Any parameter that can be passed to the script by way of a URL must always be subject to intense scrutiny. 'Cause I don't know where you come from, but where I come from, user input don't come pre-screened! (That's an Emeril joke. It's funny, trust us.) Simply placing blind faith in a URL parameter, especially when the user is able to specify a path to an executable binary, is typically not a great idea in our opinion. Had Emeril chosen to pursue a career in computer security, we're sure that he would agree.

If you absolutely must accept an executable path from the user--and there had better be a REALLY good reason--certainly it would be in your best interest to compare the string to a whitelist of sorts - a list of explicitly allowed binaries. The problem, you see, is that this sort of input screening is quite different than "merely" screening for such nasties as buffer overflows, malicious commands obfuscated via unicode characters, etc. The reason that it's different is that a valid input parses very similarly to an invalid one--e.g., "/usr/bin/perl" parses fundamentally the same as, say, "/usr/bin/tcsh". The potential outcome, of course, can be quite different in those two examples. So, in addition to the usual screening for buffer length, unicode characters, and other things that can cause your code to behave in a way other than which you intend, you have to make a _policy decision_ of whether or not to allow a string based on its content. Sounds a bit like a firewall, eh? In a sense it is a component of an application-level firewall. One way to scrutinize user input against a policy in this context is to have a "whitelist" file that contains the entire set of acceptable strings that may be passed to the program.

Additionally, precautions can be taken at the operating system level to ensure a limited extent to any potential disaster that might occur. For example, running the webserver within the context of a compartmentalized environment (a chroot jail, perhaps) would make it extremely difficult for an attacker to gain access to sensitive files (such as the system /etc/passwd). If this isn't an option, PHP offers a conceptually similar feature known as "safe mode", which is definitely worth investigating. [1] A few other methodologies for compartmentalizing an application like this are covered in Secure Coding in Chapter 3.

Of course, being of the "belt and suspenders" type, we recommend a combination of both application and OS layer defenses. In a perfect world, no one would even think to trick a webserver into deleting the entire root filesystem. But that idealistic outlook just isn't realistic these days--"reality" TV (no pun intended) is still quite popular, after all. Therefore, each layer of defense contributes value, and we feel that you just can't be too careful.

Cheers,

R Sean Eidemiller
Kenneth R. van Wyk
07 February 2004

[1] http://www.php.net/features.safe-mode

Copyright (C) 2004, R Sean Eidemiller and Kenneth R. van Wyk. Permission granted to reproduce and distribute in entirety with credit to authors.


Site Contents Copyright (C) 2002-2004 Mark G. Graff and Kenneth R. van Wyk (unless otherwise noted). All Rights Reserved.
webmaster@securecoding.org