首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么是SQL注入?

什么是SQL注入?
EN

Stack Overflow用户
提问于 2009-03-02 04:50:50
回答 9查看 40.5K关注 0票数 102

有人能解释一下SQL注入吗?它是如何导致漏洞的?SQL的注入点到底在哪里?

EN

回答 9

Stack Overflow用户

发布于 2009-03-02 07:31:08

谁能解释一下SQL injecton?

当您将一些内容插入到SQL查询字符串中,并且结果以您不想要的方式修改了查询的语法时,就会发生SQL注入。

它不一定是恶意的,它可以是一个意外。但是,意外的SQL注入更有可能导致错误而不是漏洞。

有害的内容不一定来自用户,它可以是您的应用程序从任何来源获得的内容,甚至可以在代码中生成自身。

它是如何导致漏洞的?

这可能会导致漏洞,因为攻击者可以将值发送到他们知道将被插入到SQL字符串中的应用程序。通过非常聪明,他们可以操纵查询的结果,读取数据,甚至更改他们不应该被允许做的数据。

PHP示例:

代码语言:javascript
复制
$password = $_POST['password'];
$id = $_POST['id'];
$sql = "UPDATE Accounts SET PASSWORD = '$password' WHERE account_id = $id";

现在假设攻击者将POST请求参数设置为"password=xyzzy“和"id=account_id”,结果如下:

代码语言:javascript
复制
UPDATE Accounts SET PASSWORD = 'xyzzy' WHERE account_id = account_id

虽然我希望$id是一个整数,但攻击者选择了一个字符串作为列的名称。当然,现在条件在每一行都为真,所以攻击者只是为每个帐户设置了密码。现在攻击者可以登录到任何人的帐户--包括特权用户。

的注入点到底在哪里?

注入的不是SQL,而是插入(“注入”)到SQL字符串中的内容,从而导致不同类型的查询。我信任动态内容而不对其进行验证,并盲目地执行结果SQL查询。这就是麻烦开始的地方。

SQL注入是应用程序代码中的错误,通常不是数据库、数据库访问库或框架中的错误。

大多数SQL注入情况都可以通过使用查询参数来避免。有关示例,请参阅How can I prevent SQL injection in PHP?

票数 91
EN

Stack Overflow用户

发布于 2009-03-02 06:43:35

当应用程序的用户能够影响数据库查询的意义时,就会发生SQL注入。当连接来自用户输入的任意字符串以创建SQL并将其提供给数据库时,通常会发生这种情况。例如,假设我们有以下代码(用PHP编写,但同样适用于任何语言),可以用来处理用户登录。

代码语言:javascript
复制
$sql = "SELECT  FROM users WHERE username='".$_GET['username']."' AND password='".$_GET['password']."'";

当用户输入以下内容时,就会造成危害

代码语言:javascript
复制
administrator'; --

..。作为用户名。如果没有正确的编码,查询将变成:

代码语言:javascript
复制
SELECT * FROM users WHERE username='administrator'; -- AND password=''

这里的问题是,username中的‘关闭了username字段,然后--启动了一个SQL注释,导致数据库服务器忽略字符串的其余部分。最终结果是,用户现在可以以管理员身份登录,而不必知道密码。SQL Inection还可用于执行UPDATE、DELETE或DROP查询并真正损坏数据库。

可以通过使用参数化查询或应用您的语言/工具包的转义函数(例如PHP中的mysql_real_escape_string() )来防止SQL注入。

一旦你理解了SQL注入,你就会明白this cartoon背后的笑话。

票数 28
EN

Stack Overflow用户

发布于 2010-05-01 08:16:41

SQL注入是指本应是数据的东西被不情愿地当作SQL代码处理。

例如,如果您要执行以下操作

代码语言:javascript
复制
mysql_query("SELECT * FROM posts WHERE postid=$postid");

通常,它会为您提供具有给定id的post,但是假设$postid被设置为字符串10; DROP TABLE posts --;突然之间,您发送的实际查询是

代码语言:javascript
复制
mysql_query("SELECT * FROM posts WHERE postid=10; DROP TABLE posts --");

这是一个相当大的问题,因为你会因为一个恶意用户而丢失整个posts表--哦,天哪。

防止这种情况的最简单方法是使用预准备语句,例如通过PDOMySQLi

PDO中的等效示例将是

代码语言:javascript
复制
$statement = $db->prepare('SELECT * FROM posts WHERE postid = :postid');
$statement->bindValue(':postid', $postid);
$statement->execute();

这样做可以确保数据库系统知道$postid将被视为数据而不是代码,因此将得到适当的处理。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/601300

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档