Hello, Am Donnerstag, 04. Dezember 2003 23:38 schrieb Keith Roberts:
I have found a way to limit the effects of Cross Site Scripting attacks - possibly stopping them completely.
The idea is to write a 'closed site' that will not allow passing of variables on the URL line.
I've used special FORM POST buttons written for passing values between php4 scripts in a closed environment. (please see below)
The only way into the website is via a URL WITHOUT anything passed after the ? of the URL.
Once a user is on the homepage, they have to use the special FORM POST buttons to navigate this site.
Here it is:
// this line needs to be called at the begining of each php4 // script, to put the URL query string into the global scope.
// register_globals in php.ini must be set to OFF // or this method will not work!
Sorry, this is wrong. If register_globals is set to ON, this will also work. It is just depending on your PHP version if $_SERVER is set. According to the PHP documentation, the $_* variables are always set since PHP 4.1. $HTTP_*_VARS are always set since PHP 4.0.3 (in older versions "track_vars" must be set).
$url_string = $_SERVER["QUERY_STRING"]; [...] // get form button POST variables from array
$host_name = $HTTP_POST_VARS["host_name"]; $debug_value = $HTTP_POST_VARS["debug_value"]; $table_output = $HTTP_POST_VARS["table_output"]; $advcd_search = $HTTP_POST_VARS["advcd_search"];
// $xyz_var_name = $HTTP_POST_VARS["xyz_var_name"];
Why don't you use $_GET? $HTTP_*_VARS is deprecated since the $_* variables were introduced. Also, $_GET is shorter and can be typed faster ;-)
[...] function simple_SEARCH_button($text) { // declare the following variables as global to access them global $debug_value; global $table_output;
?> <!-- back into HTML mode -->
<FORM ACTION="./search.hml" METHOD="POST">
<P ALIGN=CENTER> <INPUT TYPE="SUBMIT" VALUE="<?php echo $text; ?>"> </P>
Depending on where $text comes from, htmlentities($text) would be more safe.
<!-- ========================================================== -->
<!-- pass the following hidden variables with the form -->
<INPUT TYPE="HIDDEN" NAME="debug_value" VALUE="<?php echo $debug_value; ?>">
<INPUT TYPE="HIDDEN" NAME="table_output" VALUE="<?php echo $table_output; ?>">
Again: better use htmlentities()
<INPUT TYPE="HIDDEN" NAME="advcd_search" VALUE="OFF">
<!-- ========================================================== -->
</FORM> [...]
So, variables are passed between the php4 scripts, as HIDDEN HTML FORM variables, and not on the URL line.
Hidden? No. Just have a look at the page source in your browser.
AFAIK, this makes altering values passed between scripts very difficult for attackers, which is what is intended.
Not really. If somebody wants to attack your site, he just has to create a little form with some "hidden" elements... OK, this can't be done in a link directly, but it isn't really safe. Just think about the following, which could be from an attacker: <INPUT TYPE="HIDDEN" NAME="debug_value" VALUE="evil string"> <INPUT TYPE="HIDDEN" NAME="table_output" VALUE="let's hack! <table><tr><td>hacked!</td></tr></table>"> <INPUT TYPE="HIDDEN" NAME="advcd_search" VALUE="OFF"> The only thing you'll notice in your logfile is a "strange" referrer. (BTW: If you check the referrer, make sure to allow requests without a referrer - some browsers don't send it and some proxies filter it out.) Another question: Did you ever think about using sessions? With sessions, you can keep your "hidden" variables server-side and only pass a session-id to the browser. Gruß Christian Boltz -- Fontlinge developer Fontlinge - font management for Linux / Schriftenverwaltung for Linux Infos and Download: http://www.gesindel.de