SQL注入是一种主要在Web应用程序上执行的攻击,在SQL注入中,攻击者通过Web表单等输入接口注入部分恶意SQL。这些注入的语句发送到Web应用程序后面的数据库服务器,可能会执行不需要的操作,例如提供对未经授权的人的访问或删除或读取敏感信息等。

SQL注入漏洞可能会影响由支持SQL的数据库(如Oracle,MySQL等)提供支持的任何应用程序。

SQL注入攻击是最广泛使用,以及最古老和非常危险的应用程序漏洞之一。OWASP组织(Open Web Application Security Project)在其OWASP Top 10文档中列出了SQL Injections 作为Web应用程序安全性的最大威胁。

SQL注入示例

用HTML创建一个表单:

<!DOCTYPE html> <html> <body> <h2>SQL injection in web applications</h2> <form action=”/form-handler.php”> Username:<br> <input type=”text” name=”username” value=””> <br> Password:<br> <input type=”password” name=”password” value=””> <br><br> <input type=”submit” value=”Submit”> </form> </body> </html>

当我们点击提交时,上面的表单提交到PHP脚本下面:

<?php mysql_connect(‘localhost’, ‘root’, ‘root’); mysql_select_db(‘bootsity’); $username = $_POST[“username”]; $password = $_POST[“password”]; $query = “SELECT * FROM Users WHERE username = ” . $username . ” AND password =” . $password; $re = mysql_query($query); if (mysql_num_rows($re) == 0) { echo ‘Not Logged In’; } else { echo ‘Logged In’; } ?>

SQL注入的工作原理

在上面的示例中,假设用户填写表单如下:

Username: ‘ or ‘1’=’1 Password: ‘ or ‘1’=’1

现在我们的$查询成为:

SELECT * FROM Users WHERE username=” or ‘1’=’1′ AND password=” or ‘1’=’1′;

此查询始终返回一些行,并导致在浏览器上打印登录。因此,攻击者不知道在数据库中注册的任何用户名或密码,但攻击者仍然可以登录。

如何修复或防止SQL注入?

最好的解决方案是使用预准备语句和参数化查询,当我们使用预准备语句和参数化查询时,SQL语句由数据库引擎单独解析。

使用PDO

我们可以将form-handler.php更改为使用PDO:

<?php $dsn = “mysql:host=localhost;dbname=bootsity”; $user = “root”; $passwd = “root”; $pdo = new PDO($dsn, $user, $passwd); $username = $_POST[“username”]; $password = $_POST[“password”]; $stmt = $pdo->prepare(‘SELECT * FROM Users WHERE username = :username AND password = :password’); $stmt->bindParam(‘:username’, $username); $stmt->bindParam(‘:password’, $password); $stmt->execute(); if (count($stmt) == 0) { echo ‘Not Logged In’; } else { echo ‘Logged In’; } $stmt->close(); $pdo->close(); ?>

使用MySQLi(仅适用于MySQL)

我们也可以在form-handler.php中使用MySQLi来修复SQL注入问题:

<?php $servername = “localhost”; $username = “root”; $password = “root”; $dbname = “bootsity”; // Create connection $conn = new mysqli($servername, $username, $password, $dbname); $username = $_POST[“username”]; $password = $_POST[“password”]; // prepare and bind $stmt = $conn->prepare(‘SELECT * FROM Users WHERE username = ? AND password = ?’); $stmt->bind_param($username, $password); $stmt->execute(); if (count($stmt) == 0) { echo ‘Not Logged In’; } else { echo ‘Logged In’; } $stmt->close(); $conn->close(); ?>

结论

在本文中,我们了解了SQL注入是什么以及如何避免可能导致SQL注入攻击的Web应用程序中的漏洞,如果无法识别是否被执行SQL注入,可以使用web漏洞扫描工具进行扫描识别。