如果插入用户输入而不修改SQL查询,则应用程序容易受到SQL注入的攻击,如下例所示:
$unsafe_variable = $_POST['user_input'];
mysql_query("INSERT INTO `table` (`column`) VALUES ('$unsafe_variable')");
Run Code Online (Sandbox Code Playgroud)
这是因为用户可以输入类似的内容value'); DROP TABLE table;--,查询变为:
INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')
Run Code Online (Sandbox Code Playgroud)
可以采取哪些措施来防止这种情况发生?
这是关于编程PHP时可能遇到的警告,错误和通知的一些答案,并且不知道如何修复.这也是社区Wiki,因此邀请每个人参与添加和维护此列表.
Stack Overflow上经常弹出诸如"已发送标头"或"调用非对象成员"之类的问题.这些问题的根本原因总是一样的.因此,这些问题的答案通常会重复,然后显示OP在他/她的特定情况下要改变哪一行.这些答案不会为网站添加任何价值,因为它们仅适用于OP的特定代码.具有相同错误的其他用户不能轻易地从中读取解决方案,因为它们过于本地化.这很难过,因为一旦你理解了根本原因,修复错误是微不足道的.因此,该列表试图以一般的方式解释解决方案.
如果您的问题已被标记为重复,请在下面找到您的错误消息并将修复程序应用于您的代码.答案通常包含进一步调查的链接,以防单独的一般答案不清楚.
如果您想贡献,请添加您的"收藏"错误消息,警告或通知,每个答案一个,简短说明它意味着什么(即使它只是突出显示其手册页的术语),可能的解决方案或调试方法和现有问答的清单.此外,随时改善任何现有的答案.
另外,请参阅
即使使用mysql_real_escape_string()函数,是否存在SQL注入的可能性?
考虑这个示例情况.SQL是用PHP构造的,如下所示:
$login = mysql_real_escape_string(GetFromPost('login'));
$password = mysql_real_escape_string(GetFromPost('password'));
$sql = "SELECT * FROM table WHERE login='$login' AND password='$password'";
Run Code Online (Sandbox Code Playgroud)
我听过很多人对我说,这样的代码仍然很危险,即使使用了mysql_real_escape_string()函数也可以破解.但我想不出任何可能的漏洞?
像这样的经典注射:
aaa' OR 1=1 --
Run Code Online (Sandbox Code Playgroud)
不工作.
你知道任何可能通过上面的PHP代码注入的注入吗?
当我尝试从PHP连接到MySQL服务器时,我看到以下错误:
不推荐使用:不推荐使用mysql扩展,将来会将其删除:在第123行的/path/to/filename.php中使用mysqli或PDO
引用行上的代码是:
mysql_connect($server, $username, $password);
Run Code Online (Sandbox Code Playgroud)
我确信这些论点是正确的,而且这个确切的代码已经工作多年而没有问题.实际上,我是从PHP的一个很好的教程中获得的.
为什么会这样?
我该如何解决?
据我所知,这是可以通过设置来抑制弃用错误error_reporting的php.ini排除E_DEPRECATED:
error_reporting = E_ALL ^ E_DEPRECATED
Run Code Online (Sandbox Code Playgroud)
如果我这样做会怎么样?
我有一个PHP文件,试图回应一个$_POST,我得到一个错误,这里是代码:
echo "<html>";
echo "<body>";
for($i=0; $i<5;$i++){
echo "<input name='C[]' value='$Texting[$i]' " .
"style='background-color:#D0A9F5;'></input>";
}
echo "</body>";
echo "</html>";
echo '<input type="submit" value="Save The Table" name="G"></input>'
Run Code Online (Sandbox Code Playgroud)
这是回应POST的代码.
if(!empty($_POST['G'])){
echo $_POST['C'];
}
Run Code Online (Sandbox Code Playgroud)
但是当代码运行时,我得到一个错误:
Notice: Array to string conversion in
C:\xampp\htdocs\PHIS\FinalSubmissionOfTheFormPHP.php on line 8
Run Code Online (Sandbox Code Playgroud)
这个错误意味着什么,我该如何解决?
可能重复:
如何从"Bobby Tables"XKCD漫画中注入SQL?
https://stackoverflow.com/search?q=sql+injection
有人可以解释SQL注入吗?它是如何导致漏洞的?注入SQL的确切位置在哪里?
我尝试过不同的方法来清除表单:
<form action="service.php" id="addRunner" name="addRunner" method="post">
First Name: <input type="text" name="txtFirstName" id="txtFirstName" /><br />
Last Name: <input type="text" name="txtLastName" id="txtLastName" /><br />
Gender: <select id="ddlGender" name="ddlGender"><option value="">--Please Select--</option>
<option value="f">Female</option>
<option value="m">Male</option>
</select><br />
Finish Time:
<input type="text" name="txtMinutes" id="txtMinutes" size="10" maxlength="2">(Minutes)
<input type="text" name="txtSeconds" id="txtSeconds" size="10" maxlength="2">(Seconds)
<br />
<button type="submit" name="btnSave" id="btnSave">Add Runner</button>
<input type="hidden" name="action" value="addRunner" id="action">
</form>
Run Code Online (Sandbox Code Playgroud)
jQuery#1:
function clearInputs(){
$("#txtFirstName").val('');
$("#txtLastName").val('');
$("#ddlGender").val('');
$("#txtMinutes").val('');
$("#txtSeconds").val('');
}
Run Code Online (Sandbox Code Playgroud)
这非常有效.
jQuery#2:
function clearInputs(data){
$("#addRunner :input").each(function(){
$(this).val('');
});
Run Code Online (Sandbox Code Playgroud)
这会清除表单,但不允许我再向其提交任何信息.我尝试再次单击该按钮,它什么也没做.
这是按钮单击处理程序: …
我使用jQuery datepicker,datepicker的格式是这样的 08/25/2012
插入到我的数据库时我有错误它只插入00 00 00 00
我的代码是
<?php
$id = $_POST['id'];
$name = $_POST['name'];
$date = $_POST['date'];
$sql = mysql_query( "INSERT INTO user_date VALUE( '', '$name', '$date')" ) or die ( mysql_error() );
echo 'insert successful';
?>
Run Code Online (Sandbox Code Playgroud)
我确定我的插入是正确的....
我一直在阅读有关SQL注入攻击以及如何避免它们的内容,尽管我似乎永远无法在工作中制作"糟糕"的例子,例如看到这篇文章.
我在数据库中创建了一个PHP文件和一个表,有一个值传递$_GET并尝试通过执行删除表bob'); drop table students; --,但它不起作用.PHP自动转义\'并且查询有错误,没有造成任何伤害.尝试复制登录"攻击" AND WHERE 1=1等时出现同样的问题.
示例代码:
<?php
$id = $_GET['id'];
$sql = "INSERT INTO Users (Username) VALUES ($id)";
echo $sql;
mysql_query($sql) or die(mysql_error());
Run Code Online (Sandbox Code Playgroud)
而且我会通过 sql.php?id=1); delete from Users; --
那么这个过时的东西过去常常适用于PHP3或者什么东西,现在甚至新手都不受魔法引号之类的保护?
我在Ubuntu上使用PHP5.
初学者:
在我对如何将数据插入SQL Server的问题的答案中,他提到了传递参数而不是像我目前所拥有的字符串连接.
这对安全来说真的有必要吗?如果是这样,究竟是什么传递参数?当我谷歌它我得到很多关于存储过程.这就是我想要的,我不知道存储过程....
如果你能指出我正确的方向,我将不胜感激.
谢谢.
编辑:
好的,这就是我得到的.它似乎正确地更新了数据库,最终我将硬编码的int更改为标签的输入.请确认我是如何做到这一点不容易受到任何SQL注入或攻击.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
public partial class Stats : System.Web.UI.Page
{
public SqlDataReader DataReader;
public SqlCommand Command;
string queryString = ("INSERT INTO UserData (UserProfileID, ConfidenceLevel, LoveLevel, HappinessLevel) VALUES (@UID, @CL, @LL, @HL);");
//string queryString = ("INSERT INTO UserData (UserProfileID, ConfidenceLevel, LoveLevel, HappinessLevel) VALUES ('a051fc1b-4f51-485b-a07d-0f378528974e', 2, 2, 2);");
protected void Page_Load(object sender, EventArgs e)
{ …Run Code Online (Sandbox Code Playgroud)