Mailinglist Archive: opensuse-security (394 mails)

< Previous Next >
Re: [suse-security] Stopping XSS attacks
  • From: Christian Boltz <cb.suse@xxxxxxxxxxxxxxxxxx>
  • Date: Sun, 7 Dec 2003 22:54:11 +0100
  • Message-id: <200312072015.55032@xxxxxxxxxxxxxxx>

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">
> <INPUT TYPE="SUBMIT" VALUE="<?php echo $text; ?>"> </P>

Depending on where $text comes from, htmlentities($text) would be more

> <!-- ========================================================== -->
> <!-- 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>">

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


Christian Boltz
Fontlinge developer
Fontlinge - font management for Linux / Schriftenverwaltung for Linux
Infos and Download:

< Previous Next >