2012-12-30 82 views
0

此JavaScript/AJAX在我的本地主机服务器上工作,但是当我将它移动到共享主机时,它现在会抛出一个调用成员函数的错误execute()在MySQL调用中。在使用AJAX时不能正确转义引号

的HTML:

onclick="showTrending('page_views DESC', 'product.active= "y" 
AND product.deleted= "n" ', '12', 'popular')" 

,然后的JavaScript:

function showTrending(mysql_order, mysql_limit, limit, trend) 
{ 
$.ajax({ type: "POST", 
url: '/ajax/product_trending.php', 
data: {Mysql_Order: mysql_order, Mysql_Limit: mysql_limit, Limit: limit}, 
cache: false, 
success: function(result) { 
// if productSubType array is defined and has at least one element, display subcategory list 
if(result != 0){... 

和被称为AJAX的PHP文件被示数出来:

//Retrieve subcategories for supplied product type 
if(isset($_POST['Mysql_Order']) && isset($_POST['Mysql_Limit']) 
&& isset($_POST['Limit'])){ 
$mysql_order = $_POST['Mysql_Order']; 
$mysql_limit = $_POST['Mysql_Limit']; 
$limit = $_POST['Limit']; 
//Overlay for wishlist 
if(!isset($_SESSION['email'])){ 
    $item_wishlist = NULL; 
} else{ 
    $item_wishlist = $_SESSION['id']; 
} 
//Get product records from db 
require_once($GLOBALS['domain'].'includes/connection.inc.php'); 
$db = dbConnect(); 
$stmt = $db->stmt_init(); 


$stmt = $db->prepare("SELECT product.id, product.image_thumb, product.title, 
    product.eng_title, product.price, seller.shop_name, seller.id FROM product 
    INNER JOIN seller ON product.seller_id=seller.id WHERE $mysql_limit ORDER BY 
    $mysql_order LIMIT 0,$limit"); <-- This is the part that errors 


$stmt->execute(); 
$stmt->bind_result($row['product_id'], $row['image_thumb'], $row['title'], 
    $row['eng_title'], $row['price'], $row['shop_name'], $row['seller_id']); 
$counter = 0; 
$product_array = array(); 
while ($stmt->fetch()){ 
    ...store variables 
    $counter++; 
} 
if($counter > 0){ 
    echo json_encode($product_array); 
}else{ 
    echo json_encode(0); 
} 
} 

问题是当我插入从HTML传递的POST变量时,我没有正确准备MySQL字符串。我测试并确认,如果我只是写MySQL的以下工作原理:

"SELECT product.id, product.image_thumb, product.title, 
product.eng_title, product.price, seller.shop_name, seller.id FROM product 
INNER JOIN seller ON product.seller_id=seller.id WHERE product.active= 'y' 
AND product.deleted= 'n' ORDER BY 
page_views DESC LIMIT 0,12" 

如何我应该写初始HTML调用正确的,所以我得到在MySQL中期望的结果?

+1

尽管使用了MySQLi准备好的语句,但您将获得它的好处,事实上,您的脚本仍然容易受到SQL注入的影响。在HTTP请求中发送SQL片段以构建服务器端是一个糟糕的主意。 –

+0

因此,只需在这些片段上使用bind_param,而不是直接在bind_result中插入它们将解决此问题? – vinsanity38

+2

@ vinsanity38不,它不会解决它。你不能绑定像'product.active ='y''这样的任意SQL片段作为参数。它必须被绑定为'product.active =?'而且你不能绑定'ORDER BY'列的名字或方向。你真的需要重新思考AJAX如何通知PHP应该如何进入SQL,而不是通过AJAX发送SQL> –

回答

1

您的主机可能有一个古老的PHP功能magic_quotes启用,导致所有GET/POST/etc数据被自动转义。这是防止SQL注入的一种非常糟糕的方式,现在已经被弃用了。

你的脚本有一个非常强大的SQL注入漏洞,这个特性确实“保护”了你。重写您的脚本,以便不会将用户输入添加到SQL字符串中 - 最好使用参数化查询(google it)。

1

我想提请您注意$mysql_order需要SQL注入。

仅仅因为您使用的是准备好的语句并不意味着查询是安全的。 您需要使用白名单$mysql_order part

+0

白名单,如分别传递字段名称和值并仔细验证字段名称,以及使用该值的参数(不能参数化字段名称,但可以创建允许字段的列表并使用该字段验证) –

+0

这是真的。在他的情况下,他很幸运,他得到了一个错误。许多类似的漏洞可能未被发现,这就是为什么在所有PDO谈论安全性之后SQL注入仍然是一个问题的原因之一。这是一个大开眼界> http://www.youtube.com/watch?v=o4dJ7hdA8fs –