Zen Cart Logo
Forums / Upgrading to 1.5.x / Question about replacing [Get]s in addon code for 1.5

Question about replacing [Get]s in addon code for 1.5

Views: 40,385

Results 1 to 13 of 13
16 Aug 2011, 2:26 AM
#1
nigelt74 avatar

nigelt74

Totally Zenned

Join Date:
Sep 2005
Location:
Waikato, New Zealand
Posts:
1,558
Plugin Contributions:
1

Question about replacing [Get]s in addon code for 1.5

Ok in this post regarding image handler 3 in the
"Confirmed working mods in Zen Cart 1.5" thread

Kuroi says

kuroi:

Clyde has addressed the page registration requirement, but our analysis of it has shown that it also has destructive GET actions - one of the potential security vulnerabilities addressed extensively in 1.5, and which are a tad more complex to deal with.

Indeed that's going to be one of the challenges going forward in a PCI-certified world: understanding "it works" v "it's secure".

What exactly does that mean, as when i look at the code the vast majority of the gets are in the php code and not available to the frontend user to manipulate, i am not doubting or dissing Kuroi in anyway, he knows way more than me, I just don't understand what is wrong with the GETs, i have attempted to read the PCI specs but well I can't make sense of them they seem vague in parts and obtuse in others.

What should i be looking at replacing "Get"s with that would be PCI complant, If i was working on a mod, is it specific usages of the GET action?or is it the whole GET action that is the problem?

16 Aug 2011, 8:49 AM
#2
kuroi avatar

kuroi

Totally Zenned

Join Date:
Apr 2006
Location:
London, UK
Posts:
10,475
Plugin Contributions:
11

Re: Question about replacing [Get]s in addon code for 1.5

The issue isn't GETs in general. It's limited to GETs that lead directly to a change to the database. These could theoretically be picked up and used out of context, in particular to bypass the protection added to Zen Cart to defend against Cross Site Request Forgery (CSRF) attacks.

Examples might be a delete confirm box that relied on a button wrapped in a link that passed details of the thing to be deleted as a string of GET parameters only. Normally that link would only be generated when a user hits a delete button, but a similar one could be constructed and used during a CSRF attack.

That's now prevented by checking a security token passed as a POST var against the one held in the session array. So those "destructive" GET actions have been converted into forms with the security token passed as a hidden variable (the zen_draw_form function automatically adds it). Usually the id of the thing being deleted is passed as a POST var too. Though that's not essential as long as the code forces at least one other piece of information to be present in the POST var before the database change can be executed.

16 Aug 2011, 8:58 AM
#3
kuroi avatar

kuroi

Totally Zenned

Join Date:
Apr 2006
Location:
London, UK
Posts:
10,475
Plugin Contributions:
11

Re: Question about replacing [Get]s in addon code for 1.5

It's also worth noting that there are some forms in mods that only pass data via the GET array. These need to be encouraged to use the POST array too.

16 Aug 2011, 9:07 AM
#4
kuroi avatar

kuroi

Totally Zenned

Join Date:
Apr 2006
Location:
London, UK
Posts:
10,475
Plugin Contributions:
11

Re: Question about replacing [Get]s in addon code for 1.5

Shortly before he so sadly passed away at the weekend, Clyde Jones and I were looking at the changes needed for his Links Manager. Clyde was a huge supporter of this community, and I'm sure that he would have been happy for me to use examples from our discussion for general benefit.

The following examples are taken from the links.php file:

Link Deletion

Line 609 uses a form for the delete confirm, but does so with a form action containing all the data needed for the database deletion:

      $contents = array('form' => zen_draw_form('links', FILENAME_LINKS, zen_get_all_get_params(array('lID', 'action')) . 'lID=' . $lInfo->links_id . '&action=deleteconfirm'));

This isn't good enough as that form action could be lifted out of the form and used as a simple URL plus parameters, thus bypassing the security token. Although there is some fallback code to try to prevent this, good practise dictates making at least one of the parameters passed (or in this case the only one), a POST variable:

      $contents = array('form' => zen_draw_form('links', FILENAME_LINKS, zen_get_all_get_params(array('lID', 'action')) . '&action=deleteconfirm') . zen_draw_hidden_field('lID', $lInfo->links_id));

Line 177 reads the now posted ID, so change from:

        $links_id = zen_db_prepare_input($_GET['lID']);

to:

        $links_id = zen_db_prepare_input($_POST['lID']);

Line 183 reconstructs the URL

        zen_redirect(zen_href_link(FILENAME_LINKS, zen_get_all_get_params(array('lID', 'action')));

and so needs to be changed to add the ID from POST for use when constructing the URL

        zen_redirect(zen_href_link(FILENAME_LINKS, zen_get_all_get_params(array('action')).'&lID=' . $_POST['lID'])));

Status Changes

Changing approved/pending flag can also be done on a GET alone. So ...

Lines 564-569, build the links that lead directly to database changes so:

	  if ($links->fields['links_status'] == '2') {
        echo zen_image(DIR_WS_IMAGES . 'icon_status_green.gif', 'Approved', 10, 10) . '  <a href="' . zen_href_link(FILENAME_LINKS, 'page=' . $_GET['page'] . '&lID=' . $links->fields['links_id'] . '&action=setflag&flag=1') . '">' . zen_image(DIR_WS_IMAGES . 'icon_status_yellow_light.gif', 'Set Pending', 10, 10) . '</a>';
      } else {
        echo '<a href="' . zen_href_link(FILENAME_LINKS, 'page=' . $_GET['page'] . '&lID=' . $links->fields['links_id'] . '&action=setflag&flag=2') . '">' . zen_image(DIR_WS_IMAGES . 'icon_status_green_light.gif', 'Set Approved', 10, 10) . '</a>  ' . zen_image(DIR_WS_IMAGES . 'icon_status_yellow.gif', 'Pending', 10, 10);
      }
	  ?>

needs to be converted to forms as follows:

	  if ($links->fields['links_status'] == '2') {
        echo zen_image(DIR_WS_IMAGES . 'icon_status_green.gif', 'Approved', 10, 10) . '  ';
        echo zen_draw_form('links_status', FILENAME_LINKS, 'page=' . $_GET['page'] . '&action=setflag');
        echo zen_draw_hidden_field('lID', $links->fields['links_id']);
        echo zen_draw_hidden_field('flag',1);
        echo '<input type="image" src="' . DIR_WS_IMAGES . 'icon_status_yellow_light.gif" title="Set Pending" />';
        echo '</form>';
      } else {
        echo zen_draw_form('links_status', FILENAME_LINKS, 'page=' . $_GET['page'] . '&action=setflag');
        echo zen_draw_hidden_field('lID', $links->fields['links_id']);
        echo zen_draw_hidden_field('flag',2);
        echo '<input type="image" src="' . DIR_WS_IMAGES . 'icon_status_green_light.gif" title="Set Approved" />';
        echo '</form>';
        echo '  ' . zen_image(DIR_WS_IMAGES . 'icon_status_yellow.gif', 'Pending', 10, 10);
      }
	  ?>

Of particular note is the way that we have converted the linked image into an image type input field to both display the status and act as a submit button for the form.
The monolingual image titles (naughty, naughty) have been not been fixed.

Lines 28-29, receive the now posted request:

        if ( ($_GET['flag'] == '1') || ($_GET['flag'] == '2') ) {
          zen_set_links_status($_GET['lID'], $_GET['flag']);

and so change to:

        if ( ($_POST['flag'] == '1') || ($_POST['flag'] == '2') ) {
          zen_set_links_status($_POST['lID'], $_POST['flag']);

Line 34 reconstructs the URL:

        zen_redirect(zen_href_link(FILENAME_LINKS, 'page=' . $_GET['page'] . '&lID=' . $_GET['lID']));

and so needs to change to:

        zen_redirect(zen_href_link(FILENAME_LINKS, 'page=' . $_GET['page'] . '&lID=' . $_POST['lID']));
30 Sep 2011, 12:10 AM
#5
nigelt74 avatar

nigelt74

Totally Zenned

Join Date:
Sep 2005
Location:
Waikato, New Zealand
Posts:
1,558
Plugin Contributions:
1

Re: Question about replacing [Get]s in addon code for 1.5

Cheers Kuroi, i am slowly assimilating this, thanks for taking the time out to explain it clearly

12 Nov 2011, 9:53 AM
#6
diavire avatar

diavire

New Zenner

Join Date:
Jan 2008
Posts:
43
Plugin Contributions:
0

Re: Question about replacing [Get]s in addon code for 1.5

Hi,

Thanks for the explanation.

I'm not fully grasping the idea behind this yet though.

Can't someone just use cURL to use the POST variable using another server or even a server installed on their own computer, like Xampp?

If so, is this just to make it more difficult, making it not possible to just lift a link from a GET form, instead of impossible?

12 Nov 2011, 10:32 AM
#7
kuroi avatar

kuroi

Totally Zenned

Join Date:
Apr 2006
Location:
London, UK
Posts:
10,475
Plugin Contributions:
11

Re: Question about replacing [Get]s in addon code for 1.5

Diavire:

Can't someone just use cURL to use the POST variable using another server or even a server installed on their own computer, like Xampp?The context here is not obtaining information from a different server, but submitting data from an admin page in a browser back to the site's own server.

Diavire:

is this just to make it more difficult, making it not possible to just lift a link from a GET form, instead of impossible?Not sure I understand the subtle differences between "not possible" and "impossible", so the best answer I can give is to re-iterate that this is to protect against Cross Site Request Forgery (CSRF) attacks that seek to exploit the trust the site has in an authenticated user's browser.

12 Nov 2011, 1:01 PM
#8
diavire avatar

diavire

New Zenner

Join Date:
Jan 2008
Posts:
43
Plugin Contributions:
0

Re: Question about replacing [Get]s in addon code for 1.5

I see, misunderstood the context then.

In my reasoning the "not possible" referred to disabling the possibility to simply create an url with gets (by adding or changing entirely to a post), making the overall exploit more difficult, but still possibly (using a server to server approach like cURL).

Since I misunderstood the context, the "not possible" and "impossible" thing don't make any sense whatsoever :P

Sometimes you don't learn until you've asked some stupid questions, so thanks for explaining. :)

18 Jan 2012, 5:31 AM
#9
dbltoe avatar

dbltoe

Totally Zenned

Join Date:
Jan 2004
Location:
N of San Antonio TX
Posts:
9,792
Plugin Contributions:
14

Re: Question about replacing [Get]s in addon code for 1.5

SO.... If my foggy brain is absorbing this, the following code only needs the $_GET on several lines changed to $_POST to meet standards. Yes or no?```php

<?php /** * Module Template * * @package templateSystem * @copyright Copyright 2007 FUAL * @copyright Portions Copyright 2003-2005 Zen Cart Development Team * @copyright Portions Copyright 2003 osCommerce * @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0 * @version $Id: tpl_modules_main_product_image.php 2007-12-04 btyler $ */ ?> <?php require(DIR_WS_MODULES . zen_get_module_directory(FILENAME_MAIN_PRODUCT_IMAGE)); ?> <div id="productMainImage" class="centeredContent back"> <!-- bof Zen Slimbox v0.1 btyler 2007-12-04 --> <?php if( FUAL_SLIMBOX == 'true' || ZEN_LIGHTBOX_STATUS == 'true' ) { // Set the title if ( $current_page_base == 'product_reviews' ) { $fual_slimbox_title = htmlentities($review->fields['products_name'],ENT_QUOTES); } else { $fual_slimbox_title = htmlentities($products_name,ENT_QUOTES); } // Get the href for the large image $fual_slimbox_href = zen_lightbox($products_image_large, $fual_slimbox_title, LARGE_IMAGE_WIDTH, LARGE_IMAGE_HEIGHT); $fual_slimbox_a = '<a href="' . $fual_slimbox_href . '" rel="lightbox[gallery]" title="' . $fual_slimbox_title . '">'; // Get the img element for this product. $fual_slimbox_image = zen_image($products_image_medium, $fual_slimbox_title, MEDIUM_IMAGE_WIDTH, MEDIUM_IMAGE_HEIGHT);
// Test remote images to simulate slow loading for local development
//$fual_slimbox_image = '<img src="http://demos.mootools.net/demos/DomReadyVS.Load/moo.png" width="150px" height="150px;" alt="test" />'; 

// Note if you want to test a slow DOM load, then in /index.php add sleep(5); (in php brackets) just before the final </html>
// This will make the DOM take an extra 5 seconds to load, which simulates dialup (what a cool feature)

$fualSlimboxContent = "";
if( ZEN_LIGHTBOX_STATUS == 'true' ) {
    $fualNervousSwitch = 0;
} else {
    $fualNervousSwitch = FUAL_SLIMBOX_NERVOUS;
}
switch( $fualNervousSwitch ) {
    case 2:
        $fualSlimboxContent .= '<div id="slimboxWrapper">';
        break;
    case 1:
        $fualSlimboxContent .=  '<div id="slimboxWrapper" style="display:block;">';
        break;
    case 0:
    default:
        $fualSlimboxContent .= '<div id="slimboxWrapper" style="display:block; visibility:visible;">';
}
$fualSlimboxContent .=  $fual_slimbox_a . $fual_slimbox_image . '</a>'; 
// Putting the text link together with the image is nasty!
$fualSlimboxContent .=  '<br class="clearBoth" />';
$fualSlimboxContent .=  $fual_slimbox_a . '<span class="imgLink">' . TEXT_CLICK_TO_ENLARGE . '</span></a>';
$fualSlimboxContent .=  '</div>';

?>
<script language="javascript" type="text/javascript"><!-- document.write('<?php echo $fualSlimboxContent; ?>' ); //--></script>
<noscript>
<?php // If they can't be bothered to get a decent browser or turn js on then they only deserve the default behaviour. echo '<a href="' . zen_href_link(FILENAME_POPUP_IMAGE, 'pID=' . $_GET['products_id']) . '" target="_blank">' . zen_image($products_image_medium, $products_name, MEDIUM_IMAGE_WIDTH, MEDIUM_IMAGE_HEIGHT) . '<br /><span class="imgLink">' . TEXT_CLICK_TO_ENLARGE . '</span></a>'; ?>
</noscript>

<?php } else { ?> <!-- bof Zen Slimbox v0.1 btyler 2007-12-04 -->
<script language="javascript" type="text/javascript"><!--
document.write('<?php echo '<a href="javascript:popupWindow(\\\'' . zen_href_link(FILENAME_POPUP_IMAGE, 'pID=' . $_GET['products_id']) . '\\\')">' . zen_image($products_image_medium, addslashes($products_name), MEDIUM_IMAGE_WIDTH, MEDIUM_IMAGE_HEIGHT) . '<br /><span class="imgLink">' . TEXT_CLICK_TO_ENLARGE . '</span></a>'; ?>');
//--></script>
<noscript>
<?php
echo '<a href="' . zen_href_link(FILENAME_POPUP_IMAGE, 'pID=' . $_GET['products_id']) . '" target="_blank">' . zen_image($products_image_medium, $products_name, MEDIUM_IMAGE_WIDTH, MEDIUM_IMAGE_HEIGHT) . '<br /><span class="imgLink">' . TEXT_CLICK_TO_ENLARGE . '</span></a>';
?>
</noscript>
<?php } ?> </div> ```
18 Jan 2012, 9:51 AM
#10
kuroi avatar

kuroi

Totally Zenned

Join Date:
Apr 2006
Location:
London, UK
Posts:
10,475
Plugin Contributions:
11

Re: Question about replacing [Get]s in addon code for 1.5

dbltoe:

SO.... If my foggy brain is absorbing this, the following code only needs the $_GET on several lines changed to $_POST to meet standards. Yes or no?No.

I doubt that any changes are needed. They rarely (maybe never) will be on the store side of a site unless they relate to the checkout or the account area, as these are the only places where database changes are likely to occur.

I recommend looking back specifically at post #2 earlier in this thread for an explanation of the limited circumstances when $_GET variables could create security vulnerabilities.

18 Jan 2012, 12:37 PM
#11
dbltoe avatar

dbltoe

Totally Zenned

Join Date:
Jan 2004
Location:
N of San Antonio TX
Posts:
9,792
Plugin Contributions:
14

Re: Question about replacing [Get]s in addon code for 1.5

THANX
Still trying to wrap my head around this.:frusty:
Know that it works with 1.5 without the "monitors" shutting it down a la IH3.
Nest stop.... The 37 $_GET calls in ih_manager.php:lookaroun

17 May 2012, 12:33 PM
#12
delia avatar

delia

Totally Zenned

Join Date:
May 2006
Location:
Gardiner, Maine
Posts:
2,383
Plugin Contributions:
7

Re: Question about replacing [Get]s in addon code for 1.5

I just have to have some more specifics about this! Just not feeling confident of my understanding.

For example, this line: $action = (isset($_GET['action']) ? $_GET['action'] : ''); has nothing to do with the actual database changes - it's just picking up what the action is. Same for this: switch($_GET['action'])

This one sets the form action as get and not post: <?php echo zen_draw_form('clean_cross', FILENAME_CROSS_SELL_PRODUCTS, 'action=select_cross_sell', 'get'); ?> But it looks like it's just trying to choose which table to work on and works no changes on the database

This one uses post so is not a problem <?php echo zen_draw_form('clean_cross', FILENAME_CROSS_SELL_PRODUCTS, 'action=cleancross_sell', 'post'); ?> Looks like all of the actions that make database changes are done that way.

This one changes the database but is not part of a form per se though must be the result of that choice of table mentioned before:

if(defined('CROSS_SELL_ENABLED') ) {

if (isset($_GET['select_cross_sell'])) {
$cross_sell_edit = ($_GET['select_cross_sell']);
$db->Execute("UPDATE " . TABLE_CONFIGURATION .
" set configuration_value = $cross_sell_edit
WHERE configuration_key = 'CROSS_SELL_SELECTED_TABLE'" );
zen_redirect(zen_href_link(FILENAME_CROSS_SELL_PRODUCTS));
}

So my conclusion is that no changes are necessary. Does that sound right?

12 Aug 2012, 2:39 PM
#13
potteryhouse avatar

potteryhouse

Zen Follower

Join Date:
Jun 2012
Location:
Florida
Posts:
123
Plugin Contributions:
0

Re: Question about replacing [Get]s in addon code for 1.5

Hello,
I must ask for a little help.

I am trying to update a sales tax mod to protect against the $_get vulnerability, but am not quite able to find the correct change for the section of code listed below. Any guidance / help would be appreciated. I have this mod working (locally on a test machine) with Zen Cart 1.5, but wanted to update this section before posting the changes.

The sample below is but one of four pieces that do insert, save, update, and delete. All have the same format, so once one of them are updated the others should be easy.
In-case your interested in the mod I am looking at updating, this is the link.
http://www.zen-cart.com/downloads.php?do=file&id=422 (Local Sales Tax Mod)

First is a question, does this code even need to be updated, I believe it does based on what I have read in the forum...
Second, if it does, what changes will make this work (I understand I will have update the post back from get to post etc. when this is updated).

      $heading[] = array('text' => '<b>' . TEXT_INFO_HEADING_NEW_LOCAL_SALES_TAX . '</b>');

      $contents = array('form' => zen_draw_form('local_sales_tax', FILENAME_LOCAL_SALES_TAXES, 'page=' . $_GET['page'] . '&action=insert'));
      $contents[] = array('text' => TEXT_INFO_INSERT_INTRO);
      $contents[] = array('text' => '<br>' . TEXT_INFO_COUNTRY . '<br>' . zen_draw_pull_down_menu('zone_country_id', zen_get_countries(TEXT_ALL_COUNTRIES), '', 'onChange="update_zone(this.form);"'));
      $contents[] = array('text' => '<br>' . TEXT_INFO_COUNTRY_ZONE . '<br>' . zen_draw_pull_down_menu('zone_id', zen_prepare_country_zones_pull_down()));
      $contents[] = array('text' => '<br>' . TEXT_INFO_TAX_RATE . '<br>' . zen_draw_input_field('tax_rate'));
      $contents[] = array('text' => '<br>' . TEXT_INFO_FIELDMATCH . '<br>' . zen_draw_pull_down_menu('tax_fieldmatch', $za_lookup));
			
      $contents[] = array('text' => '<br>' . TEXT_INFO_DATAMATCH . '<br>' . zen_draw_textarea_field('tax_datamatch', false, 35, 4));
      $contents[] = array('text' => '<br>' . TEXT_INFO_RATE_DESCRIPTION . '<br>' . zen_draw_input_field('tax_description'));
			
      $contents[] = array('text' => '<br />' . TEXT_INFO_TAX_SHIPPING . '<br />' . zen_draw_radio_field('tax_shipping', 'false', true) . ' ' . TEXT_TAX_SHIPPING_FALSE . '<br />' . zen_draw_radio_field('tax_shipping', 'true') . ' ' . TEXT_TAX_SHIPPING_TRUE);
      $contents[] = array('text' => '<br>' . TEXT_INFO_TAX_CLASS_TITLE . '<br>' . zen_tax_classes_pull_down('name="tax_class_id" style="font-size:10px"'));
      $contents[] = array('align' => 'center', 'text' => '<br>' . zen_image_submit('button_insert.gif', IMAGE_INSERT) . ' <a href="' . zen_href_link(FILENAME_LOCAL_SALES_TAXES, 'page=' . $_GET['page']) . '">' . zen_image_button('button_cancel.gif', IMAGE_CANCEL) . '</a>');


//As I see it the following line needs to be updated.
$contents = array('form' => zen_draw_form('local_sales_tax', FILENAME_LOCAL_SALES_TAXES, 'page=' . $_GET['page'] . '&action=insert'));

//And, this one might need to be updated.
 $contents[] = array('align' => 'center', 'text' => '<br>' . zen_image_submit('button_insert.gif', IMAGE_INSERT) . ' <a href="' . zen_href_link(FILENAME_LOCAL_SALES_TAXES, 'page=' . $_GET['page']) . '">' . zen_image_button('button_cancel.gif', IMAGE_CANCEL) . '</a>');

Thanks in advance for any suggestions / help.

Brent