[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [suse-security] Stopping XSS attacks



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


--
Check the headers for your unsubscription address
For additional commands, e-mail: suse-security-help@xxxxxxxx
Security-related bug reports go to security@xxxxxxx, not here