切换到准备好的语句

切换到准备好的语句,第1张

切换到准备好的语句

我一直处于同样的情况。我也使用了串联语句,然后将应用程序切换为准备好的语句。

坏消息 是,您将更改通过将客户端数据连接到SQL语句而构建的每个SQL语句,这几乎将是50个源文件中包含的每个SQL语句。

好消息 是从切换到准备好的语句所获得的收益是无价的,例如:

1-您永远不会担心“ SQL注入攻击”

PHP 手册说

如果应用程序仅使用准备好的语句, 则开发人员可以确保不会发生SQL注入
(但是,如果使用未转义的输入来构建查询的其他部分,则仍然可以进行SQL注入)。

对我来说,这个理由-放心-足以支付更改我的源代码的费用。,现在您的客户可以在表单名称字段中输入内容

robert; DROp table students;-- ;)
,您可以放心,什么都不会发生

2-您不再需要转义客户端参数。您可以在SQL语句中直接使用它们,例如:

$query = "SELECT FROM user WHERe id = ?";$vars[] = $_POST['id'];

代替

$id = $mysqli->real_escape_string($_POST['id']);$query = "SELECt FROM user WHERe id = $id";

这是您在使用准备好的语句之前必须做的事情,这使您面临忘记作为正常人逃避一个参数的危险。攻击者破坏系统所需的一切只是1个未转义的参数。


修改密码

通常,更改源文件总是有风险的,并且会很痛苦,尤其是在您的软件设计不佳以及没有明显的测试计划的情况下。但我会告诉您我做了什么使它尽可能容易。

我创建了一个函数,每个数据库交互代码都将使用该函数,因此您以后可以在一个地方更改所需的内容-该函数-您可以进行如下 *** 作

class SystemModel{        public function preparedQuery($query,$types, array $vars, $conn)    {        if (count($vars) > 0) { $hasVars = true;        }        array_unshift($vars, $types);        $stmt = $conn->prepare($query);        if (! $stmt) { return false;        }        if (isset($hasVars)) { if (! call_user_func_array(array( $stmt, 'bind_param'), $this->refValues($vars))) {     return false; }        }        $stmt->execute();        return $stmt;    }            protected function refValues($arr)    {        if (strnatcmp(phpversion(), '5.3') >= 0) { $refs = array(); foreach ($arr as $key => $value)     $refs[$key] = &$arr[$key];     return $refs;        }        return $arr;    }}

现在,您可以在源文件中的任何位置使用此接口,例如,让我们更改问题中提供的当前SQL语句。让我们改变这个

$mysqli = new mysqli('localhost', "root", "", "testdb");$addresult = "     SELECt a.firstnames, a.surname, a.schoolrole, a.datejoined      FROM teachers a LEFT JOIN schools b ON a.schoolid = b.id      WHERe b.id = '".$inputvalues['schoolid']."'";if( $result = $mysqli->query($addresult) ) {    while($row = $result->fetch_all())    {        $returnResult = $row;    }}

入这个

$mysqli = new mysqli('localhost', "root", "", "testdb");$sysModel = new SystemModel();$addresult = "     SELECt a.firstnames, a.surname, a.schoolrole, a.datejoined     FROM teachers a LEFT JOIN schools b ON a.schoolid = b.id     WHERe b.id = ?";$types = "i"; // for more information on paramters types, please check ://https://php.net/manual/en/mysqli-stmt.bind-param.php$vars = [];$vars[] = $inputvalues['schoolid'];$stmt = $sysModel->preparedQuery($addresult, $types, $vars, $mysqli);if (!$stmt || $stmt->errno) {   die('error'); // TODO: change later for a better illustrative output}$result = $stmt->get_result();$returnResult = [];while ($row = $result->fetch_array(MYSQLI_ASSOC)) {    $returnResult[] = $row;}

另外,如果我没有向数据库输入任何数据,它仍然容易受到注入的攻击吗?

是的,通过将错误的字符串连接到您的SQL语句来应用Sql
Injection攻击。往哪里去是

INSERT
SELECt
DELETE
UPDATE
。例如

$query = "SELECT * FROM user WHERe name = '{$_GET['name']}' AND password = '{$_GET['pass']}'"

这样的东西可以被

// exmaple.com?name=me&pass=1' OR 1=1; --

这将导致一个SQL语句

$query = "SELECt * FROM user WHERe name = 'me' AND password = '1' OR 1=1; -- '"//executing the SQL statement and getting the resultif($result->num_rows){    //user is authentic}else{    //wrong password}// that SQL will always get results from the table which will be considered a correct password

祝您好运,将您的软件切换到准备好的语句,并要记住,知道发生了什么事,就可以放心使用SQL注入攻击,这值得您更改源文件。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4913105.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-12
下一篇 2022-11-12

发表评论

登录后才能评论

评论列表(0条)

保存