【问题标题】:Jquery security regarding mysql injection关于 mysql 注入的 Jquery 安全性
【发布时间】:2013-12-22 12:33:48
【问题描述】:

我知道它可能非常规,但我想知道下面的代码是否安全。

第一段代码是 htee jquery 对象创建加上对 retrieve_data 函数的调用:

var dataset = [
        {
            query_column: "articles.id,articles.category_id,articles.text,articles.slug article_slug,site_categories.title,site_categories.slug site_categories_slug",
            table_name: 'articles',
            query_join: 'LEFT JOIN site_categories ON site_categories.Id = ' + category,
            query_filter: ['articles.category_id LIKE ', '%' + category + '%'],
            query_limit: 'LIMIT ' + limit,
            unique_column_switch: '1'
        }
    ];
    retrieve_data(dataset, function (data) {

接下来是retrieve_data函数本身:

function retrieve_data(dataset, callback) {
    $.ajax(
        {
            type: "POST",
            url: "<?php echo ROOT_URL; ?>php/content/retrieve_data.php",
            data: {json: JSON.stringify(dataset)},
            success: function (data) {
                var data = $.parseJSON(data);
                callback(data);
            }
        });
}

最后是获取数据并打印出来返回给jquery的php:

mb_internal_encoding("UTF-8");
session_start();
include '../../config.php';
include ROOT_DIR . "php/dbconnection/dbconnection.php";
include ROOT_DIR . 'php/authentication/encryption.php';
$encrypt_decrypt = new encryption();
$json = json_decode($_POST['json']);
$array = array();

/*
 * THIS IS TO BUILD A STRING OF DIFFERENT QUERIES TO BE PERFORMED UPON UPDATE BEING PRESSED
 * PARAMS:
 * data_value:::::::::::: THE VALUE USED TO FIND THE ROW
 * table_name:::::::::::: TABLE NAME
 * unique_column::::::::: UNIQUE DATA ELEMENT THAT LINKS ALL THE TABLES TOGETHER
 * query_end::::::::::::: END OF QUERY (EXTRA WHERE CLAUSES, ORDER BY, LIMIT, ETC)
 * query_column:::::::::: COLUMNS THAT ARE GOING TO BE CALLED, DEFAULTS TO * IF USING JOINS THEN      THIS MUST BE SPECIFIED I.E. TABLE1.*, TABLE2.*, ETC
 * query_join:::::::::::: SET ANY JOINS HERE
 * unique_column_switch:: IF SET TO 1 DISABLES USE OF A UNIQUE COLUMN AND USES QUERY END EXCLUSIVELY
 */
foreach($json as $item){
    $table_name = $mysqli->real_escape_string($item->table_name);
    $unique_column = $mysqli->real_escape_string($item->unique_column);
$data_value = $mysqli->real_escape_string($item->data_value);
$query_column = $mysqli->real_escape_string($item->query_column);
$query_join = $mysqli->real_escape_string($item->query_join);
$query_filter = $item->query_filter;
$query_order = $mysqli->real_escape_string($item->query_order);
$query_limit = $mysqli->real_escape_string($item->query_limit);
$unique_column_switch = $mysqli->real_escape_string($item->unique_column_switch);
$query_filter_safe = array();
foreach($query_filter as $key1 => $val1){
    array_push($query_filter_safe, ($key1 % 2) ? "'" . $mysqli->real_escape_string($val1) . "'" : $mysqli->real_escape_string($val1));
}
if(empty($unique_column) && $unique_column_switch != '1'){
    $query1 = $mysqli->query("SHOW KEYS FROM `$table_name` WHERE Key_name = 'PRIMARY'");
    $fetch1 = $query1->fetch_array(MYSQLI_ASSOC);
    $unique_set = $fetch1['Column_name'] . " = '" . $data_value . "'";
    $unique_column = $fetch1['Column_name'];
} else{
    $unique_set = ($unique_column_switch != '1') ? "`" . $table_name . "`.`" . $unique_column . "` = '" . $data_value . "'" : '';
}
$unique_column = (empty($unique_column)) ? '' : $unique_column;
$where = (empty($unique_set) && empty($query_filter)) ? '' : 'WHERE';
$select_items = (empty($query_column)) ? '*' : $query_column;
$query2 = "SELECT " . $select_items . " FROM " . $table_name . " " . $query_join . " " . $where . " " . $unique_set . " " . join(' ', $query_filter_safe) . " " . $query_order . " " . $query_limit;
//echo $query2;
$query2 = $mysqli->query($query2);
for($x = 0; $fetch2 = $query2->fetch_array(MYSQLI_ASSOC); $x++){
    $fetch2 = $encrypt_decrypt->decrypt_val($fetch2, $table_name, $mysqli);
    foreach($fetch2 as $column => $value){
        ($unique_column == $column) ? $array[$table_name][$x]['INDEX_VALUE'] = $value : $array[$table_name][$x][$column] = $value;
    }
}
}
echo json_encode($array);

编辑 12/5 下午 12:00 EST

我已经重写了我想要做的事情。再次感谢大家的指点! @MonkeyZeus 和 @Carth 非常有用。

include '../../config.php';
include ROOT_DIR . "php/dbconnection/dbconnection_pdo.php";
$query = "SELECT * FROM site_users WHERE username = :username";
$query = $pdo->prepare($query);
$query->execute(array('username' => $_POST['username']));
$result = $query->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($result);

回到jquery:

function article_box_basic(category, limit, max_char_count, location) {
    $.ajax(
        {
            type: "POST",
            url: "<?php echo ROOT_URL; ?>php/content/article_box_basic.php",
            data: {username: 'moltmans'},
            success: function (data) {
                var data = $.parseJSON(data);

在这里用数据做一些事情

【问题讨论】:

  • 为什么要在客户端构建查询?你不能只在服务器端传递参数和构建查询吗?
  • 你想为least secure website赢得奖项吗?
  • 转义机制旨在转义单个标记(考虑字符串文字),not 跨越多个标记的查询片段。此外,您的代码中没有任何内容可以阻止用户传递您不期望的 JOIN(例如,传递给 users 表)。
  • 我并不抱歉,并感谢 DCoder 能够以更好的语气表达我的想法。有太多基本的先决条件要么被完全忽略,要么被公然忽略。请停止你正在做的事情,在你通过stackoverflow.com/questions/14880531/…然后stackoverflow.com/questions/60174/…之前不要触摸另一段代码
  • 你不是第一个,我相信你也不会是最后一个尝试这个的。我只是在这里将一个简单的大红色Caution: HOT 标志放在明火上,而不是说明Caution: the difference between the body's upper temperature tolerance level is far exceeded by the temperature provided by this flame

标签: php jquery security


【解决方案1】:

这显然不是一种“安全”的方法。客户端的验证和控制应被视为生成请求的固有不安全便利,而不是强制执行真正安全性的手段。您的服务器端代码应该在您的用户是谁以及他们在做什么的上下文中验证请求参数。由于用户可以将“数据集”设置为他们想要的任何内容,因此类别变量本身是否容易根据语句其余部分的使用情况而被注入并不重要。

通过像这样在客户端公开您的架构,您会泄露无需公开的有价值信息。

【讨论】:

  • 我认为你的回答是正确的。问题是解决方案可能相当困难且成本高昂。我想知道 OP 是否可以强制 $mysql-&gt;query 只执行一个查询,从而避免在同一查询中注入其他恶意执行。
  • 所以我只是在我的网站上玩这个,我可以很容易地把我构建的东西拿来用它纯粹的 php 端。我只是想知道是否有办法确保这个安全,或者它是否完全不可能?
  • 这里的实现当然可以尝试确保只执行一条语句,但封装额外的语句以通过注入运行只是一种类型的注入攻击。由于当前的方法允许攻击者设置语句以发出他们希望系统已经受到攻击的查询。 GGio 关于只允许用户提供参数的评论是限制底层系统暴露给客户端的典型方法。看看这个-stackoverflow.com/questions/60174/…
  • @MikeOltmans - 完全理解,迈克。大多数反应,包括我自己在内,都是基于“如果这是在生产中”的想法。我之前评论中关于锁定 MYSQL/PHP 语句的 SO 线程的链接是一个很好的来源,您可以在这里做些什么来帮助提高网站的安全性。
  • 但实际上,无论我做什么,使用它都不安全。这种方法只是让处理在某人浏览器上运行的网站页面期间所需的快速查询变得更加简单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-28
  • 1970-01-01
  • 2018-08-31
  • 2015-10-17
  • 2017-12-21
  • 2021-10-24
  • 1970-01-01
相关资源
最近更新 更多