有人能解释一下什么是SQL注入吗?它是如何导致安全漏洞的?SQL注入发生在哪个具体点?
有人能解释一下什么是SQL注入吗?它是如何导致安全漏洞的?SQL注入发生在哪个具体点?
有人能解释一下什么是SQL注入吗?
当你把一些内容插入到 SQL 查询字符串中时,如果结果修改了你原本不想要的查询语法,就会发生 SQL 注入。
这并不一定是恶意的,可能是意外的。但是意外的 SQL 注入更可能导致错误而不是漏洞。
有害内容不一定来自用户,它可以来自应用程序从任何来源获取的内容,甚至在代码中自动生成的内容。
它如何导致漏洞?
它会导致漏洞,因为攻击者可以向应用程序发送值,他们知道这些值将被插入到 SQL 字符串中。通过非常聪明的方式,他们可以操纵查询结果,读取数据或甚至更改他们不应该被允许更改的数据。
PHP 中的示例:
$password = $_POST['password'];
$id = $_POST['id'];
$sql = "UPDATE Accounts SET PASSWORD = '$password' WHERE account_id = $id";
假设攻击者将POST请求参数设置为"password=xyzzy
"和"id=account_id
", 导致以下SQL查询语句:
UPDATE Accounts SET PASSWORD = 'xyzzy' WHERE account_id = account_id
尽管我期望$id
是一个整数,但攻击者选择了一个作为列名的字符串。当然,现在条件在每一行上都成立,因此攻击者只是设置了每个账户的密码。现在攻击者可以登录任何人的帐户,包括特权用户。
SQL注入的确切点在哪里?
不是SQL被注入了,而是内容被插入到SQL字符串中(“注入”),导致查询的类型与我的意图不同。我没有验证动态内容,就盲目地执行了结果的SQL查询,这就是问题的起源。SQL注入是指应用程序的用户能够影响数据库查询的含义。这通常发生在将来自用户输入的任意字符串连接起来创建SQL并将其提供给数据库时。例如,假设我们有以下代码(使用PHP编写,但对于任何语言都是适用的),该代码可能用于处理用户登录。
$sql = "SELECT FROM users WHERE username='".$_GET['username']."' AND password='".$_GET['password']."'";
当用户输入类似于
时,就会造成损害。administrator'; --
...用于用户名。如果没有适当的编码,查询将变成:
SELECT * FROM users WHERE username='administrator'; -- AND password=''
这个问题在StackOverflow上已经被回答了很多次,但它是每个人都应该知道的一个重要话题,所以我不会投票关闭这个问题。
以下是我在这个主题上的一些过去答案链接:
我还在本月的MySQL会议上做了一个演讲,我的幻灯片在线上:
mysql_query("SELECT * FROM posts WHERE postid=$postid");
$postid
被设置为字符串10; DROP TABLE posts --
;突然之间,你发送的实际查询变成了:mysql_query("SELECT * FROM posts WHERE postid=10; DROP TABLE posts --");
$statement = $db->prepare('SELECT * FROM posts WHERE postid = :postid');
$statement->bindValue(':postid', $postid);
$statement->execute();
SQL注入是指恶意用户将SQL代码输入到输入字段中,以尝试在您的服务器上运行SQL。
我所坚持的第一条建议是使用参数化存储过程而非在代码中构建原始SQL。
存储过程参数不会被执行,在大多数情况下是安全的。
你会喜欢来自代码项目的this文章;)
摘要
- 加密敏感数据。
- 使用最少权限的帐户访问数据库。
- 使用最少权限的帐户安装数据库。
- 确保数据有效。
- 进行代码审查,以检查是否存在二次攻击的可能性。
- 使用参数化查询。
- 使用存储过程。
- 在存储过程中重新验证数据。
- 确保错误消息不透露应用程序或数据库的内部架构。
SQL注入的发生点是您的应用程序从用户接受输入的任何点。
无论这是否成为您的Web应用程序的危险漏洞,取决于此输入是否稍后作为SQL查询的一部分使用,而没有正确检查其类型并在必要时进行转义。
如果没有适当的转义,用户“注入”的某些SQL代码可能会被SQL引擎执行为SQL代码,而不是简单的字符串或值。