Site Administration Page 2 - Webserver Security (Part II) |
The third class of common problems are poorly written cgi programs or PHP scripts which put trust into parameters from untrustworthy sources and are using CGI parameters without sanity checking. A web application generally consists of components located inside your firewall. These components can be considered trustworthy, because they are controlled by the local administrator. Such components may be local scripts, the database, the web server and local data files. Additional components of any web application are located outside of the firewall and cannot be trusted. Mainly this is the users browser, if he uses any and is not typing his web request directly into a telnet session to better control which data he feeds our application in order to exploit any security problems we may have introduced into our code. The firewall is the demarcation line between the trustworthy intranetwork and the Evil Internet. It is a trust boundary. All data from outside the trust boundary must not enter a web application without checking. This includes all parameters passed to the CGI script such as all GET, POST and COOKIE variables, the HTTP_REFERER, HTTP_USER_AGENT and all other HTTP_* variables as well as all other variables generated remotely. Each and every such variable must be checked for validity before it can be used by the CGI script. That check will insure that the value of that particular variable is well within the expected domain. For example it is a common, but wrong practice that some scripts will accept form input only if the HTTP_REFERER of the request is correct. Using such a mechanism the script tries in vain to protect itself against faked requests. Of course it is trivial for a potential attacker to learn the required HTTP_REFERER and fake it along with the rest of a request - the protection is useless. Such a script is doing the wrong thing: The HTTP_REFERER is not the value that is required to be correct in such calls - all other values are. Faking web requests The following simple PHP program will echo the value of the CGI parameter b. It will also show the HTTP_REFERER with which the script was called. kris@valiant:~/www < cat test.php <?php print "The value of b is $b\n"; print "The value of HTTP_REFERER is $HTTP_REFERER\n"; ?> Using a simple telnet connect to port 80 we are able to feed this script with arbitrary values for parameter b as well as with any desired value for the HTTP_REFERER. We send the following lines to the server: GET /~kris/test.php?b=this+is+a+test HTTP/1.0 Host: valiant.koehntopp.de Referer: http://www.attacker.com/die_sucker_die.html Here is the complete session transcript: kris@valiant:~/www < telnet valiant 80 Trying 193.102.57.3... Connected to valiant.koehntopp.de. Escape character is '^]'. GET /~kris/test.php?b=this+is+a+test HTTP/1.0 Host: valiant.koehntopp.de Referer: http://www.attacker.com/die_sucker_die.html HTTP/1.1 200 OK Date: Sat, 08 Apr 2000 06:44:02 GMT Server: Apache/1.3.9 (Unix) (SuSE/Linux) PHP/4.0RC2-dev mod_ssl/2.4.7 OpenSSL/0.9.4 X-Powered-By: PHP/4.0RC2-dev Connection: close Content-Type: text/html The value of b is this is a test The value of HTTP_REFERER is http://www.attacker.com/die_sucker_die.html Connection closed by foreign host. Note that we have to enter values for b in urlencoded form. To urlencode a string, use a simple PHP program such as kris@valiant:~/www < cat urlencode.php #! /home/kris/bin/php -q <?php print urlencode($argv[1])."\n"; ?> kris@valiant:~/www < ./urlencode.php "this is a test" this+is+a+test It is only slightly more difficult to fake HTTP POST requests: The request now has to include a valid Content-Type header as well as the correct content length in bytes. Here is how it is done: kris@valiant:~/www < telnet valiant 80 Trying 193.102.57.3... Connected to valiant.koehntopp.de. Escape character is '^]'. POST /~kris/test.php HTTP/1.0 Host: valiant.koehntopp.de Referer: http://www.attacker.com/die_sucker_die.html Content-Type: application/x-www-form-urlencoded Content-Length: 16 b=this+is+a+test HTTP/1.1 200 OK Date: Sat, 08 Apr 2000 06:55:11 GMT Server: Apache/1.3.9 (Unix) (SuSE/Linux) PHP/4.0RC2-dev mod_ssl/2.4.7 OpenSSL/0.9.4 X-Powered-By: PHP/4.0RC2-dev Connection: close Content-Type: text/html The value of b is this is a test The value of HTTP_REFERER is http://www.attacker.com/die_sucker_die.html Connection closed by foreign host. Another common suicide technique is the passing of internal application state from page to page via <INPUT TYPE="HIDDEN"> tags. Keeping internal application state outside the trust boundary is like ripping the heart out of your application and presenting it on a silver tablet to any attacker. Anyone who cares to destroy such a insanely insecure installation can easily manipulate the application state and produce any desired effect. Application state should be kept on the server using sessions and session variables. It must never cross the trust boundary. All web application development platforms such mechanisms. For example in PHP3, PHPLIB is used to keep session data, PHP4 uses the session_*() calls, ASP has the Session object and Cold Fusion offers several different flavors of session variables. An application must not store any data from outside the trust boundary directly inside session variables: These are trusted variables and may not hold untrusted data. Usually data from the outside, such as form variables, are passed to validator functions. Only if the validator functions indicate that the content passed from the form is safe, values are copied from the form variables into session variables. Your application should do such checks in a single central location. All the rest of your application should never touch form variables, but always work with the checked and sanitized session data. Part of the job description of a webmaster is checking all installations for errors belonging into one of these error classes and change the applications in case they show any of the symptoms discussed here. Stolen credit card data or even servers which have been broken into and have been used as an attack base are not just embarassing: Such installations are negligently insecure and you can expect to be sued for damages or even aiding a computer breakin. For the layman on an Internet shopping afternoon all of this is not helpful: To validate the security of a server not only technical expertise is required, but also access to the server itself. Only an independent full scale audit and a technical seal of approval renewed each year or after all major technical changes will improve the current situation. If insurance and credit card companies will offer discount to installations with such a seal of approval, this will be a huge incentive for site operators to get themselves audited. Links http://www.koehntopp.de/kris/artikel/webtune/ "Webserver verstehen und tunen" (german language) http://www.koehntopp.de/php/ "de.comp.lang.php - H‰ufig gestellte Fragen" (german language) http://www.insecure.org/nmap/ "NMAP Port Scanner" (english language) http://ethereal.zing.org/ "Ethereal Network Monitor" (english language) http://www.marko.net/cheops "Ceops Network Mapper" (english language) http://freshmeat.net/appindex/1998/04/06/891857252.html "lsof - list open files" (english language) "TCP/IP Illustrated, Volume 1: The Protocols" (english language) W. Richard Stevens Addison-Wesley "Hacking Exposed - Network Security Secrets & Solutions" (english language) McClure, Scambray and Kurtz Osborne "Maximum Linux Security" (english language) Anonymous Sams
blog comments powered by Disqus |
|
|
|
|
|
|
|