[ic] Cart programming question

Steffen Dettmer interchange-users@interchange.redhat.com
Sun Mar 17 13:03:01 2002


Hi,
 
here an update. I solved the "eval" issue. Maybe someone could
overview it a little and say if there are some violations of Best
Practices or so, this code is mainly the result of "try and
error".
 
To anyone who reads it: please consider that as a potential
security hole as long not otherwise known. See below for details.

* Steffen Dettmer wrote on Sun, Mar 17, 2002 at 16:06 +0100:
> * Mike Heins wrote on Sat, Mar 16, 2002 at 16:02 -0500:
> > This should actually be:
> > 
> > 	$Carts->{main} = 
> > 	 [data table=group_carts column=content key=cart_id]
> > 	;
> 
> Again, this leads to: 
> 
> Can't use string ("[{"price_group" => "general","mv") as an ARRAY
[...]
> I should try it in a global user tag? Should I do a 
> 
> use Safe; 
> $ready = new Safe;
> $arrar_ref = $ready->reval($string);
> 
> or is there a better way? Maybe I should just try it...

And I did and it works. But it's tricky... 

First, I used a ordinary catalog.cfg usertag. After two hours
watching my browser's mysterious error messages I found a little
detail I wasn't aware of:

The $Tag->data changes the data returned from the DB. It replaces
the bracket "[" with "[". This entity renders to "[", so the
HTML debug output didn't show it. Hum. Finally, a small:

$cart =~ s|[|\[|g;

solved it.



For the others of the list who are interested in cart storing/loading:

- use a new instance of Safe in UserTags

- write my $ready = new Safe;

- use $ready->reval as "eval" function

- make absolutly clear to never pass unchecked contents to it,
  since it could lead to arbitrary code execution (if someone
  manages it to save a cart that contains backticks with a shell
  command or so). I haven't checked it so far, but I could
  imagine that a SKU which contains backticks could lead to such
  a case. It may be possible that the reval function detects such
  things and is safe for it (as the module name suggests) but I
  haven't verified it yet.

- make sure to unescape (==restore) the data returned from the
  data Tag (seems the escaping is not documented).



Well, here some code from my user tag. I use a group_id and a
shop_id, but I don't included the code here, since it shouldn't
be of common interest. I pass the cart_id as [tmp], since the
user tag parameter wasn't interpolated.

oki, here it comes:

#===================================
# loads a cart from group_carts
#  Parameter: scratch cart_selected: ID of cart to load
#  [...]
#===================================

UserTag group_cart_load Order debug
UserTag group_cart_load Routine <<EOR
sub
{
        my $cart_id = $Tag->scratch("cart_selected");
        $cart_id =~ tr|\[\]|?|;
        my $ready = new Safe;

        my $out = "";
        my $err = undef;

	#... parameter checks cut off...

        my $cart;
        if (!$err) {
                $cart = $Tag->data( { 'table' => 'group_carts',
                                        'field' => 'cart',
                                        'key' => $cart_id
                                      } ) ;
                if (!defined($cart) || $cart eq "") {
                        $out .= "undefined cart content";
                        $err = "1";
                }
		#undo $Tag->data's escaping:
                $cart =~ s|&#91;|\[|g;
        }

        my $array_ref;
        if (!$err) {
                $Tag->tmp("tc_cart", $cart);
                $array_ref  = $ready->reval($cart);
                if (!defined($array_ref) || ref($array_ref) ne "ARRAY") {
                        $out .= "no array ref: ($array_ref) for ($cart)";
                        $err = "1";
                }
        }
        if (!$err) {
                $Carts->{main} = $array_ref;
                $out .= "cart fetched and stored: " . $cart;
        } else {
                $out .= "cart fetching failed.";
        }
        if ($debug) {
                return $out;
        } else {
                return(!$err);
        }
}
EOR

Have a nice weekend!

oki,

Steffen

-- 
Dieses Schreiben wurde maschinell erstellt,
es trägt daher weder Unterschrift noch Siegel.