通过准备和执行来避免SQL注入

问题描述 投票:3回答:1

像一行代码

my $sql_query = "SELECT * FROM Users WHERE user='$user';";

可能会在您的程序中引入SQL注入漏洞。为了避免这个,可以使用类似的东西

my $sth = $dbh->prepare("SELECT * FROM Users WHERE user='?';");
$dbh->execute($user);

但是,在我目前正在处理的代码中使用了以下内容

$sql_query = "SELECT * FROM Users WHERE user='" . $user . "';";
$dbh->prepare($sql_query);
$dbh->execute();

这实际上有用吗?如果是的话,我会做些什么?有哪些优点和缺点?

perl sql-injection dbi
1个回答
6
投票
my $sth = $dbh->prepare("SELECT * FROM Users WHERE user='?'");

这不起作用,因为它正在搜索文字'?'字符 - 而不是参数。如果你试图为参数发送一个值,那么MySQL就像是,“你想让我用这个做什么?”因为查询没有参数占位符。

如果要使用参数,则不能将参数占位符放在SQL查询中的字符串分隔符内,即使参数将采用字符串或日期时间值:

my $sth = $dbh->prepare("SELECT * FROM Users WHERE user=?");

下一个例子:

$sql_query = "SELECT * FROM Users WHERE user='" . $user . "'";
$dbh->prepare($sql_query);
$dbh->execute();

这将运行查询,但它不安全。即使没有参数,您也可以准备任何查询。

使用prepare()并不是使SQL注入安全的原因。更安全的是使用参数来组合动态值,而不是像在本例中那样进行字符串连接。

但使用参数确实需要使用prepare()

PS:当您以编程方式一次运行一次时,不需要在SQL查询结束时放置;。只有在运行多个查询(例如SQL脚本或存储过程)时才需要分隔符。在你的例子中,;是无害的,但MySQL并不需要它,它只会忽略它。

© www.soinside.com 2019 - 2024. All rights reserved.