Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用参数如何防止SQL注入?_Sql_Sql Injection - Fatal编程技术网

使用参数如何防止SQL注入?

使用参数如何防止SQL注入?,sql,sql-injection,Sql,Sql Injection,使用参数如何防止SQL注入 很多人都说,使用参数而不是输入字符串(例如,来自网站用户)可以防止SQL注入 但我不明白,我的意思是“drop database”字符串与在查询中使用的参数中输入的“drop database”字符串有何不同 myfunction(myuser) { sql="SELECT user, password FROM users WHERE user='"+myuser+"'" return db.execute(sql) } 攻击者可通过此调用利用此漏

使用参数如何防止SQL注入

很多人都说,使用参数而不是输入字符串(例如,来自网站用户)可以防止SQL注入


但我不明白,我的意思是“drop database”字符串与在查询中使用的参数中输入的“drop database”字符串有何不同

myfunction(myuser)
{
    sql="SELECT user, password FROM users WHERE user='"+myuser+"'"
    return db.execute(sql)
}
攻击者可通过此调用利用此漏洞获取表的所有密码:

myfunction("x' OR true OR 'a'='")
相反,如果程序员通过绑定变量执行查询:

myfunction(myuser)
{
    sql="SELECT user, password FROM users WHERE user=?"
    sql.setParam(1, myUser)
    return db.execute(sql)
}

在这种情况下,攻击者输入前一个棘手的值是没有用的,因为数据库引擎将100%透明地处理该值,而不允许其中包含任何控制字符。

请参阅sql注入攻击的示例:让我们假设以下伪代码:

myfunction(myuser)
{
    sql="SELECT user, password FROM users WHERE user='"+myuser+"'"
    return db.execute(sql)
}
攻击者可通过此调用利用此漏洞获取表的所有密码:

myfunction("x' OR true OR 'a'='")
相反,如果程序员通过绑定变量执行查询:

myfunction(myuser)
{
    sql="SELECT user, password FROM users WHERE user=?"
    sql.setParam(1, myUser)
    return db.execute(sql)
}

在这种情况下,攻击者输入任何与前一个值相同的棘手值都是无用的,因为数据库引擎将以100%透明的方式处理该值,而不允许其中包含任何控制字符。

SQL注入的工作原理是在RDBMS解析SQL语法之前修改SQL查询

查询参数在SQL已被解析后发送到服务器,因此恶意值影响SQL语法解析为时已晚


查询参数只能解释为标量值,如字符串。

SQL注入通过在RDBMS解析SQL语法之前修改SQL查询来工作

查询参数在SQL已被解析后发送到服务器,因此恶意值影响SQL语法解析为时已晚

查询参数只能解释为标量值,如字符串。

,因为仅仅在字段中输入“drop database”是不够的。您必须添加一些其他字符来说服SQL解释器终止上一条语句并启动一条新语句(以执行DROP)。除其他外,参数化将阻止SQL以预期的方式成功注入和解释此类序列。例如,
等可能关闭字符串的字符将被转义,以便它们被视为变量的一部分,而不是SQL的一部分

具体来说,包含一个工作示例。在本例中,有一些PHP代码用于将行插入表中:

$sql = "INSERT INTO Students (Name) VALUES ('" . $studentName . "');";
execute_sql($sql);
如果
$studentName
设置为“John”之类的正常值,则代码生成的最终SQL字符串是良性的:

INSERT INTO Students (Name) VALUES ('John');
同样,与您的示例类似,如果将
$studentName
设置为“DROP TABLE Students”,它仍然没有任何效果。最后一个SQL是:

INSERT INTO Students (Name) VALUES ('DROP TABLE Students');
没有造成伤害

但是…如果将
$studentName
设置为更微妙的值,例如:

Robert'); DROP TABLE Students;--
INSERT INTO Students (Name) VALUES ('Robert'); DROP TABLE Students;--');
最后一个字符串如下所示:

Robert'); DROP TABLE Students;--
INSERT INTO Students (Name) VALUES ('Robert'); DROP TABLE Students;--');
然后将其传递给SQL引擎,SQL引擎将其解释为两条语句(顺便说一句,末尾有一条注释),并执行这两条语句,结果令人不快

但是,如果
$studentName
中的值作为参数传递,而不是仅仅连接到标准字符串,那么最终的查询将以

INSERT INTO Students (Name) VALUES ('Robert\'); DROP TABLE Students;--'); 
注意中间的逃逸<代码> <代码>,因此现在它被认为是字符串的一部分。它不再导致字符串在“t”之后停止

因此,在表中的
Name
字段中输入的内容将是

Robert'); DROP TABLE Students;--
DROP TABLE语句不会被执行,因为SQL解释器从未看到它——它只是将其作为要添加到表中的值的一部分来处理

参数化意味着参数值内的任何内容都只被视为字符串(或者可能是数字)——它永远不能在字符串外转义,并被视为SQL语句本身的一部分

进一步阅读:

可能会帮助你更好地理解

因为仅仅在字段中输入“drop database”是不够的。您必须添加一些其他字符来说服SQL解释器终止上一条语句并启动一条新语句(以执行DROP)。除其他外,参数化将阻止SQL以预期的方式成功注入和解释此类序列。例如,
等可能关闭字符串的字符将被转义,以便它们被视为变量的一部分,而不是SQL的一部分

具体来说,包含一个工作示例。在本例中,有一些PHP代码用于将行插入表中:

$sql = "INSERT INTO Students (Name) VALUES ('" . $studentName . "');";
execute_sql($sql);
如果
$studentName
设置为“John”之类的正常值,则代码生成的最终SQL字符串是良性的:

INSERT INTO Students (Name) VALUES ('John');
同样,与您的示例类似,如果将
$studentName
设置为“DROP TABLE Students”,它仍然没有任何效果。最后一个SQL是:

INSERT INTO Students (Name) VALUES ('DROP TABLE Students');
没有造成伤害

但是…如果将
$studentName
设置为更微妙的值,例如:

Robert'); DROP TABLE Students;--
INSERT INTO Students (Name) VALUES ('Robert'); DROP TABLE Students;--');
最后一个字符串如下所示:

Robert'); DROP TABLE Students;--
INSERT INTO Students (Name) VALUES ('Robert'); DROP TABLE Students;--');
然后将其传递给SQL引擎,SQL引擎将其解释为两条语句(顺便说一句,末尾有一条注释),并执行这两条语句,结果令人不快

但是,如果
$studentName
中的值作为参数传递,而不是仅仅连接到标准字符串,那么最终的查询将以

INSERT INTO Students (Name) VALUES ('Robert\'); DROP TABLE Students;--'); 
注意中间的逃逸<代码> <代码>,因此现在它被认为是字符串的一部分。它不再导致字符串在“t”之后停止

因此,什么被输入到