ohno Posted April 20, 2020 Share Posted April 20, 2020 Not sure how to debug this. I have the following error that is ONLY happening when our site has a PCI scan running : - ERRNO: 2 TEXT: htmlspecialchars() expects parameter 1 to be string, array given LOCATION: /home/bttorj45/public_html/smarty_templates_c/dbbe565f1731d4158472b66b75c85442498e81b9_0.file.top_menu_bar.tpl.php, line 42, at April 11, 2020, 5:05 pm Showing backtrace: htmlspecialchars(Array[1], "3", "UTF-8", true) # line 42, file: /home/siteaddress/public_html/smarty_templates_c/dbbe565f1731d4158472b66b75c85442498e81b9_0.file.top_menu_bar.tpl.php content_5e83087341d089_14126332(Object:Smarty_Internal_Template) # line 123, file: /home/siteaddress/public_html/include/smarty/sysplugins/smarty_template_resource_base.php Smarty_Template_Resource_Base.getRenderedTemplateCode(Object:Smarty_Internal_Template) # line 114, file: /home/siteaddress/public_html/include/smarty/sysplugins/smarty_template_compiled.php Smarty_Template_Compiled.render(Object:Smarty_Internal_Template) # line 216, file: /home/siteaddress/public_html/include/smarty/sysplugins/smarty_internal_template.php Smarty_Internal_Template.render() # line 385, file: /home/siteaddress/public_html/include/smarty/sysplugins/smarty_internal_template.php Smarty_Internal_Template._subTemplateRender("file:page_elements/top_menu_bar.tpl", null, null, "0", "120", Array[0], "0", false) # line 56, file: /home/siteaddress/public_html/smarty_templates_c/0e4c1495f7a25cef1d85553f951690964f702a5a_0.file.error404.tpl.php content_5e4ffba4a49c66_36622821(Object:Smarty_Internal_Template) # line 123, file: /home/siteaddress/public_html/include/smarty/sysplugins/smarty_template_resource_base.php Smarty_Template_Resource_Base.getRenderedTemplateCode(Object:Smarty_Internal_Template) # line 114, file: /home/siteaddress/public_html/include/smarty/sysplugins/smarty_template_compiled.php Smarty_Template_Compiled.render(Object:Smarty_Internal_Template) # line 216, file: /home/siteaddress/public_html/include/smarty/sysplugins/smarty_internal_template.php Smarty_Internal_Template.render(false, "1") # line 232, file: /home/siteaddress/public_html/include/smarty/sysplugins/smarty_internal_templatebase.php Smarty_Internal_TemplateBase._execute(Object:Smarty_Internal_Template, null, null, null, "1") # line 134, file: /home/siteaddress/public_html/include/smarty/sysplugins/smarty_internal_templatebase.php Smarty_Internal_TemplateBase.display("pages/error404.tpl") # line 65, file: /home/siteaddress/public_html/errors/404.php include("/home/siteaddress/public_html/errors/404.php") # line 34, file: /home/siteaddress/public_html/smarty_plugins/function.load_product.php Product.init("api") # line 5, file: /home/siteaddress/public_html/smarty_plugins/function.load_product.php smarty_function_load_product(Array[2], Object:Smarty_Internal_Template) # line 39, file: /home/siteaddress/public_html/smarty_templates_c/53725e8a2fc4b6c7c0c42e801dab2741a0994a8e_0.file.product.tpl.php content_5e579e9761f086_59385269(Object:Smarty_Internal_Template) # line 123, file: /home/siteaddress/public_html/include/smarty/sysplugins/smarty_template_resource_base.php Smarty_Template_Resource_Base.getRenderedTemplateCode(Object:Smarty_Internal_Template) # line 114, file: /home/siteaddress/public_html/include/smarty/sysplugins/smarty_template_compiled.php Smarty_Template_Compiled.render(Object:Smarty_Internal_Template) # line 216, file: /home/siteaddress/public_html/include/smarty/sysplugins/smarty_internal_template.php Smarty_Internal_Template.render(false, "1") # line 232, file: /home/siteaddress/public_html/include/smarty/sysplugins/smarty_internal_templatebase.php Smarty_Internal_TemplateBase._execute(Object:Smarty_Internal_Template, null, null, null, "1") # line 134, file: /home/siteaddress/public_html/include/smarty/sysplugins/smarty_internal_templatebase.php Smarty_Internal_TemplateBase.display("pages/product.tpl") # line 85, file: /home/siteaddress/public_html/dirs.php I ***think*** the scan must be inputting something in the search box to cause this (I'm awaiting info from Security Metrics with regard to this). {load_chat assign="chat"} {if $chat->mChat} <script type="text/javascript" id="763333b0f312f025d780a8f4451bf6f3" src="https://www.siteaddress.com/online-support/script.php?id=763333b0f312f025d780a8f4451bf6f3"></script> {/if} {if !$chat->mChat && $settings->mSettings[13]} <script type="text/javascript" id="aaa07817d7cd2a7dce9e0ffac6286dbb" src="https://www.siteaddress.com/online-support/script.php?id=aaa07817d7cd2a7dce9e0ffac6286dbb"></script> {/if} <div id="menu_switch"><i class="fa fa-bars fa toggler"></i></div> <form id="product_search" method="get" action="{$smarty.const.SITE_ROOT}/searchresults/"> <input type="text" name="search" placeholder=" Product Search" style="font-family: FontAwesome, Arial; font-style: normal; font-size:18px;" {if isset($smarty.request.search) && $settings->mSettings[107]}value="{$smarty.request.search|escape:'htmlall'}"{/if} /><button type="submit" class="button"><i class="fa fa-search" aria-hidden="true"></i> <i class="fa fa-caret-right" aria-hidden="true"></i></button> </form> <form id="code_search" method="post" action="{$smarty.const.SITE_ROOT}/cart/quickadd.php"> <input type="text" name="code" maxlength="14" placeholder=" Product Code" style="font-family: FontAwesome, Arial; font-style: normal; font-size:18px;" /><button type="submit" name="submit" class="orange"><i class="fa fa-shopping-cart" aria-hidden="true"></i> Quick Add <i class="fa fa-caret-right" aria-hidden="true"></i></button> </form> {if !isset($hidecart) && isset($cartsmall) && $cartsmall->mCart.sub > 0} <p id="view_cart"><a class="button orange" href="{$smarty.const.SITE_ROOT}/cart/"><span class="hidden-xs hidden-sm"><i class="fa fa-shopping-cart" aria-hidden="true"></i> View Cart </span>£{$cartsmall->mCart.sub} <i class="fa fa-caret-right" aria-hidden="true"></i></a></p> {/if} <script> $('.toggler').click(function() { $(this).toggleClass("fa-bars fa-times"); }); </script> function.load_search.php :- <?php function smarty_function_load_search($params, $smarty) { $search = new Search(); $search->init(); $smarty->assign($params['assign'], $search); } class Search { // public fields public $mSearchString; public $mSearchArray; public $mProducts; public $mProductCount; // private fields private $mDoSettings; private $mDoCatalogue; function __construct() { require_once FILE_ROOT . '/data_objects/do_settings.php'; $this->mDoSettings = new DoSettings(); require_once FILE_ROOT . '/data_objects/do_catalogue.php'; $this->mDoCatalogue = new DoCatalogue(); if (isset($_REQUEST['search']) && strlen(trim($_REQUEST['search']))>0 ) { $this->mSearchString = trim(stripslashes($_REQUEST['search'])); $this->mSearchArray = explode(" ", $this->mSearchString); } else { header ("Location: /emptysearch/"); die (); } } public function init() { $this->mProducts = $this->mDoCatalogue->SearchProducts($this->mSearchArray); $this->mProductCount = count($this->mProducts); for ($i = 0; $i < count($this->mProducts); $i++) { $this->mProducts[$i]['price_inc'] = number_format($this->mProducts[$i]['price'] * (($this->mDoSettings->GetSetting(1) / 100) + 1), 2, ".", ","); } } } ?> do_catalogue.php :- public function SearchProducts($search) { $fields = array("code", "title", "keywords"); $query_string = "SELECT p.code, p.title, p.cattext, p.price, p.img, p.url, p.available, p.due, p.special, p.newproduct, p.discontinued, c.name, c.menulinktext FROM " . $this->mProductTable . " p " . "JOIN categories c ON p.category = c.id " . "WHERE (("; for ($f = 0; $f < count($fields); $f++) { if ($f != 0) { $query_string .= ") OR ("; } for ($s = 0; $s < count($search); $s++) { if ($s != 0) { $query_string .= " AND "; } $query_string .= "p." . $fields[$f] . " LIKE '%" . $this->mDoQuery->dbManager->DbEscape($search[$s]) . "%'"; } } $query_string .= ")) AND active=1 AND live=1 " . "ORDER BY p.rating ASC"; return $this->mDoQuery->dbManager->DbGetAll($query_string); } Any idea's how to fix it? I can't replicate it with a specific issue as I don't know what the scan is doing to cause this! Thanks Quote Link to comment Share on other sites More sharing options...
requinix Posted April 20, 2020 Share Posted April 20, 2020 If you skip over the template stuff in the backtrace, you'll see these two lines: include("/home/siteaddress/public_html/errors/404.php") # line 34, file: /home/siteaddress/public_html/smarty_plugins/function.load_product.php Product.init("api") # line 5, file: /home/siteaddress/public_html/smarty_plugins/function.load_product.php What is the code for function.load_product.php? Quote Link to comment Share on other sites More sharing options...
ohno Posted April 20, 2020 Author Share Posted April 20, 2020 2 minutes ago, requinix said: If you skip over the template stuff in the backtrace, you'll see these two lines: include("/home/siteaddress/public_html/errors/404.php") # line 34, file: /home/siteaddress/public_html/smarty_plugins/function.load_product.php Product.init("api") # line 5, file: /home/siteaddress/public_html/smarty_plugins/function.load_product.php What is the code for function.load_product.php? <?php function smarty_function_load_product($params, $smarty) { $product = new Product(); $product->init($params['dir']); $smarty->assign($params['assign'], $product); } class Product { // public fields public $mProduct; //public $mImages; //public $mImageCount; public $mOptions; public $mXsells; // private fields private $mDoSettings; private $mDoCatalogue; function __construct() { require_once FILE_ROOT . '/data_objects/do_settings.php'; $this->mDoSettings = new DoSettings(); require_once FILE_ROOT . '/data_objects/do_catalogue.php'; $this->mDoCatalogue = new DoCatalogue(); } public function init($dir) { $this->mProduct = $this->mDoCatalogue->GetProductFromDir(trim(stripslashes($dir))); if (!$this->mProduct) { header('HTTP/1.1 404 Not Found'); $_GET['e'] = 404; include(FILE_ROOT . '/errors/404.php'); exit(); } $this->mProduct['price_inc'] = number_format($this->mProduct['price'] * (($this->mDoSettings->GetSetting(1) / 100) + 1), 2, ".", ","); $options = trim($this->mProduct['optionprods'], ",\t\n\r\0\x0B"); $options_ids = explode(",", $options); for ($i = 0; $i < count($options_ids); $i++) { if (is_numeric($options_ids[$i])) { $product = $this->mDoCatalogue->GetProduct((int)$options_ids[$i]); if ($product) { $product['price_inc'] = number_format($product['price'] * (($this->mDoSettings->GetSetting(1) / 100) + 1), 2, ".", ","); $this->mOptions[] = $product; } } } $this->mXsells = $this->mDoCatalogue->GetXsells($this->mProduct['productid']); shuffle($this->mXsells); } } ?> Quote Link to comment Share on other sites More sharing options...
requinix Posted April 20, 2020 Share Posted April 20, 2020 Well that's not it. Most recent template was Smarty_Internal_Template._subTemplateRender("file:page_elements/top_menu_bar.tpl", null, null, "0", "120", Array[0], "0", false) What's in that file? Quote Link to comment Share on other sites More sharing options...
ohno Posted April 20, 2020 Author Share Posted April 20, 2020 function.load_product.php IS the above code. The tpl was already posted, it's this code : - {load_chat assign="chat"} {if $chat->mChat} <script type="text/javascript" id="763333b0f312f025d780a8f4451bf6f3" src="https://www.siteaddress.com/online-support/script.php?id=763333b0f312f025d780a8f4451bf6f3"></script> {/if} {if !$chat->mChat && $settings->mSettings[13]} <script type="text/javascript" id="aaa07817d7cd2a7dce9e0ffac6286dbb" src="https://www.siteaddress.com/online-support/script.php?id=aaa07817d7cd2a7dce9e0ffac6286dbb"></script> {/if} <div id="menu_switch"><i class="fa fa-bars fa toggler"></i></div> <form id="product_search" method="get" action="{$smarty.const.SITE_ROOT}/searchresults/"> <input type="text" name="search" placeholder=" Product Search" style="font-family: FontAwesome, Arial; font-style: normal; font-size:18px;" {if isset($smarty.request.search) && $settings->mSettings[107]}value="{$smarty.request.search|escape:'htmlall'}"{/if} /><button type="submit" class="button"><i class="fa fa-search" aria-hidden="true"></i> <i class="fa fa-caret-right" aria-hidden="true"></i></button> </form> <form id="code_search" method="post" action="{$smarty.const.SITE_ROOT}/cart/quickadd.php"> <input type="text" name="code" maxlength="14" placeholder=" Product Code" style="font-family: FontAwesome, Arial; font-style: normal; font-size:18px;" /><button type="submit" name="submit" class="orange"><i class="fa fa-shopping-cart" aria-hidden="true"></i> Quick Add <i class="fa fa-caret-right" aria-hidden="true"></i></button> </form> {if !isset($hidecart) && isset($cartsmall) && $cartsmall->mCart.sub > 0} <p id="view_cart"><a class="button orange" href="{$smarty.const.SITE_ROOT}/cart/"><span class="hidden-xs hidden-sm"><i class="fa fa-shopping-cart" aria-hidden="true"></i> View Cart </span>£{$cartsmall->mCart.sub} <i class="fa fa-caret-right" aria-hidden="true"></i></a></p> {/if} <script> Hopefully that helps? Quote Link to comment Share on other sites More sharing options...
requinix Posted April 20, 2020 Share Posted April 20, 2020 Oh, that's what the file was? I think the issue is in {$smarty.request.search|escape:'htmlall'} That's the only place that uses unknown input. The search was an array, as in search[]=.... Submit a regular search, then go into your browser's address bar and add brackets to the search=. Then see what happens. How to fix that, it's kinda up to you. Standard MVC is that you should be passing the search value into the view, not getting it from the request. If you did that then you would validate the search value in your regular code: the 404 page, and any other place that ends up including top_menu_bar. 33 minutes ago, ohno said: function.load_product.php IS the above code. Right, yes, you did post the code I asked about. What I meant was "well that's not where the problem is". Was rather ambiguous, now that I look at it again. Quote Link to comment Share on other sites More sharing options...
ohno Posted April 20, 2020 Author Share Posted April 20, 2020 (edited) That gives a slightly different error in the log : - ERRNO: 2 TEXT: trim() expects parameter 1 to be string, array given LOCATION: /home/website/public_html/smarty_plugins/function.load_search.php, line 27, at April 20, 2020, 7:00 pm function.load_search.php is above too. Now, I have no clue how to fix it! Any idea's what code I'd need to fix it? Edited April 20, 2020 by ohno Quote Link to comment Share on other sites More sharing options...
ohno Posted April 20, 2020 Author Share Posted April 20, 2020 Could I simply do : - $this->mSearchString = str_replace ( "[", " ",($_REQUEST['search'])); To prevent an array in the search? Quote Link to comment Share on other sites More sharing options...
requinix Posted April 20, 2020 Share Posted April 20, 2020 38 minutes ago, ohno said: That gives a slightly different error in the log : - A new error. 38 minutes ago, ohno said: Now, I have no clue how to fix it! Any idea's what code I'd need to fix it? You have to fix your code so that it doesn't assume everything, like query string parameters, are in the format you expect. This particular problem you're dealing with is something most PHP developers never even care about. They should, they just don't. 2 minutes ago, ohno said: Could I simply do : - $this->mSearchString = str_replace ( "[", " ",($_REQUEST['search'])); To prevent an array in the search? No. Not only will the code not make the problem go away (and actually create a new problem along the way), what you're trying to do is not a good idea. It'll take me longer to explain what I'm thinking in words than in code, so here: class SearchQuery { public $value = ""; public static function readFromRequest() { $query = new self(); if (isset($_GET["search"]) && is_string($_GET["search"])) { $query->value = $_GET["search"]; } return $query; } } $query = SearchQuery::readFromRequest(); // pass $query around to places that need to know about searching Quote Link to comment Share on other sites More sharing options...
ohno Posted April 20, 2020 Author Share Posted April 20, 2020 Thanks, I'll pass this onto a developer who has been doing other work on my site (as I have no clue where the above code would be used!). Thanks for your help, would the above code fix both errors? Quote Link to comment Share on other sites More sharing options...
requinix Posted April 20, 2020 Share Posted April 20, 2020 20 minutes ago, ohno said: Thanks, I'll pass this onto a developer who has been doing other work on my site (as I have no clue where the above code would be used!). Thanks for your help, would the above code fix both errors? Sure, why not. Quote Link to comment Share on other sites More sharing options...
ohno Posted April 20, 2020 Author Share Posted April 20, 2020 Thanks again hopefully they can sort the issue now. Quote Link to comment Share on other sites More sharing options...
ohno Posted April 21, 2020 Author Share Posted April 21, 2020 This is what he did..... new function.load_search_query.php file <?php function smarty_function_load_search_query($params, $smarty) { $query = new SearchQuery(); $smarty->assign('query', $query->readFromRequest()); } class SearchQuery { public $value = ""; public static function readFromRequest() { $query = new self(); if (isset($_GET["search"]) && is_string($_GET["search"])) { $query->value = $_GET["search"]; } return $query; } } ?> Modified function.load_search.php : - function __construct() { require_once FILE_ROOT . '/data_objects/do_settings.php'; $this->mDoSettings = new DoSettings(); require_once FILE_ROOT . '/data_objects/do_catalogue.php'; $this->mDoCatalogue = new DoCatalogue(); if (!isset($_REQUEST['search']) || !is_string($_REQUEST['search']) ) { header ("Location: /emptysearch/"); die (); } if (strlen(trim($_REQUEST['search']))>0 ) { $this->mSearchString = trim(stripslashes($_REQUEST['search'])); $this->mSearchArray = explode(" ", $this->mSearchString); } else { header ("Location: /emptysearch/"); die (); } } Changed tpl file to include {load_search_query assign="query"} & change the search query to {$query->value|escape:'htmlall'}. It doesn't error with the [], running PCI scan now..... Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.