Safe alternative to mysql_real_escape_string? (PHP) 安全的mysql_real_escape_string的替代方法?(PHP)

19 浏览
0 Comments

Safe alternative to mysql_real_escape_string? (PHP) 安全的mysql_real_escape_string的替代方法?(PHP)

我将一个变量传递给一个执行查询的函数

MySQL连接仅在函数内部发生,并在函数内部关闭

我希望在将字符串发送到函数之前能够安全地转义它们

我不能使用mysql_real_escape_string,因为它需要一个MySQL连接(该连接仅在函数内部创建)

我知道简单的答案是在函数内部转义字符串,但我不能这样做,因为我需要发送一些转义的和一些非转义的字符串的部分

例如,我需要像这样运行函数:

myquery("'" . escape_me("My string") . "'");

注意,我发送了两个撇号--未转义的,带有转义的字符串内部。因此,我不能在myquery函数的参数中使用mysql_real_escape_string。

我找到了以下代码,建议我可以将其用作mysql_real_escape_string的替代方法:

// 转义字符
function escape_me($value) {
    $return = '';
    for($i = 0; $i < strlen($value); ++$i) {
        $char = $value[$i];
        $ord = ord($char);
        if($char !== "'" && $char !== "\"" && $char !== '\\' && $ord >= 32 && $ord <= 126)
            $return .= $char;
        else
            $return .= '\\x' . dechex($ord);
    }
    return $return;
}

我不知道这个函数是否安全,能否防止多字节攻击,但我认为每次查询都需要撤销该函数

例如,输入:

Testing 3's "OK" 转换为 Testing 3x27s x22OKx22 在数据库中

所以我的主要问题是:

您是否知道是否有另一个函数可以作为mysql_real_escape_string的替代方法,可以安全地转义字符?

0
0 Comments

问题:安全替代mysql_real_escape_string()的方法是什么?

原因:mysql_real_escape_string()函数在处理字符串时可以防止SQL注入攻击,但在某些情况下可能会出现安全问题。为了找到更安全的替代方法,用户提出了这个问题。

解决方法:建议传入一个需要转义的值的数组,并使用sprintf()函数格式化查询语句,同时对每个值进行转义。以下是查询函数的第一部分:

public function querya($query, $args=null){
    //检查是否传入了args参数
    if($args !== null){
        //如果是一个数组...
        if(is_array($args)){
            //...对args数组中的每个值进行转义
            foreach($args as $key=>$value){
                $args[$key] = mysql_real_escape_string($value);
            }
            //将查询语句添加到args数组的开头
            array_unshift($args, $query);
            //使用数组作为sprintf的参数来调用sprintf函数
            $query = call_user_func_array("sprintf", $args);
        } else {
            //如果args不是一个数组,则是一个字符串(传入的是单个参数)
            $query = sprintf($query, mysql_real_escape_string($args));
        }
    }
    //执行查询和其他操作
}

在类似的函数中,我会给%s通配符添加引号,以确保查询中没有未引用的%s。这样做是为了保险起见。由于这个方法只是我自己使用的,所以我通常会这样编写查询语句:$DB->querya("SELECT COLUMN FROM TABLE WHERE VALUE='%s' AND 1=%d",array('test',1));,并在需要时在查询中的%s周围添加引号。

0
0 Comments

安全的替代方法是使用预处理语句(prepared statements),预处理语句可以防止SQL注入攻击。可以通过以下代码实现:

function fetchAll(){
 $args = func_get_args();
 $query = array_shift($args);
 $stmt = $pdo->prepare($query);
 $stmt->execute($args);
 return $stmt->fetchAll();
}
$a=$db->fetchAll("SELECT * FROM users WHERE status=? LIMIT ?,?",$status,$start,$num);

如果使用单字节编码或UTF-8编码,就不需要使用`mysql_real_escape_string`函数,`mysql_escape_string`(已弃用)或`addslashes`就足够了。

`mysql_escape_string`函数已经被弃用(而推荐使用`mysql_real_escape_string`),除此之外,其他都是好的建议。连接一次,然后在每个查询之前打开和关闭连接,比每次查询都连接一次更好。

原问题中提到了连接每次调用函数都是一个糟糕的想法,并且指出了良好规划的应用程序不会有这样奇怪的限制。可以使用替换(substitutions)的方法来解决这个问题,如下所示:

myquery("SELECT * FROM table WHERE id = %s","My string");

总结起来,避免使用`mysql_real_escape_string`函数可以通过使用预处理语句或者在单字节编码或UTF-8编码中使用`mysql_escape_string`函数来解决这个问题。并且,为了提高性能,应该在每个查询之前打开连接,而不是每次调用函数都连接一次。

0