Php sql中的引号导致问题
我有一个非常简单的html输入文本框。此表单的信息表单通过sql字符串传输到mysql数据库 一切都很顺利,除了有人键入“或”之外。我不想限制用户键入什么 在对数据库运行查询之前,是否应该查找并替换字符串 有简单的方法吗 下面是一些代码:Php sql中的引号导致问题,php,mysql,sql-injection,Php,Mysql,Sql Injection,我有一个非常简单的html输入文本框。此表单的信息表单通过sql字符串传输到mysql数据库 一切都很顺利,除了有人键入“或”之外。我不想限制用户键入什么 在对数据库运行查询之前,是否应该查找并替换字符串 有简单的方法吗 下面是一些代码: <?php session_start(); if (empty($_SESSION['user']) && empty($_REQUEST['form'])) //check this code!!1 { exit; } if
<?php
session_start();
if (empty($_SESSION['user']) && empty($_REQUEST['form'])) //check this code!!1
{
exit;
}
if (isset($_REQUEST['Submit']))
{
//echo "Let's process this form!";
include "config.php";
include "mail.php";
if ($_REQUEST['form'] == "profile")
{//public profile
//print_r($_REQUEST);
//"UPDATE `tims`.`pending_profile` SET `nickname` = 'I Don''t Have One' WHERE `pending_profile`.`id` = 1;";
$sql = "INSERT INTO `tims`.`pending_profile`"
. "(`id`, `nickname`, `location`, `role`, `yog`, `interests`, `favMoment`, `gainThisYr`, `futurePlans`, `bio`) \n"
. "VALUES ('" . $_SESSION['id'] . "', '" . $_REQUEST['nickname'] . "', '" . $_REQUEST['town'] . "', '" . $_REQUEST['role'] . "', '" . $_REQUEST['yog'] . "', '" . $_REQUEST['interests'] . "', '" . $_REQUEST['fav_moment'] . "', '" . $_REQUEST['gain'] . "', '" . $_REQUEST['future'] . "', '" . $_REQUEST['bio'] . "')\n"
. "ON DUPLICATE KEY UPDATE nickname ='" . $_REQUEST['nickname'] . "', location='" . $_REQUEST['town'] . "', role= '" . $_REQUEST['role'] . "', yog='" . $_REQUEST['yog'] . "', interests='" . $_REQUEST['interests'] . "', favMoment='" . $_REQUEST['fav_moment'] . "', gainThisYr='" . $_REQUEST['gain'] . "', futurePlans='" . $_REQUEST['future'] . "', bio='" . $_REQUEST['bio'] . "'\n";
$qry = mysql_query($sql) or die(mysql_error());
//@todo overlay this
//http://flowplayer.org/tools/overlay/index.html
//send mail to moderators
include "vars.php";
$to = $captMail;
$prof = implode("\n", $_REQUEST);
$subject = "Moderation Needed";
$body = $_SESSION['fullname'] . " Has just changed their public profile.\n" .
"Please login here to moderate their changes:\n" .
//"http://team2648.com/OPIS/login.php?page=manage".
"http://www." . $sysurl . "/login.php?page=manage\n" .
"Best,\n" .
"Blake\n\n\n" .
"Click here to accept the profile bleow\n\n" .
"http://www." . $sysurl . "/login.php?page=manage&acceptID=".$_SESSION['id']."\n" .
$prof;
mailer($to, $subject, $body);
$to = $mentorMail;
mailer($to, $subject, $body);
echo "<link href=\"../css/styling.css\" rel=\"stylesheet\" type=\"text/css\" media=\"screen\" />";
echo "<div class =\"widget\" style=\"width:350px\">";
echo "Your changes have been saved, they will not go live until reviewed by a moderator";
echo "<br>";
echo "<a href=\"../\">Click here to continue</a>";
echo "</div>";
}
exit;
}
$sql = "SELECT * FROM `pending_profile` WHERE id ='" . $_SESSION['id'] . "'";
$qry = mysql_query($sql) or die(mysql_error());
$row = mysql_fetch_assoc($qry);
?>
<!--<h3>Use this page to manage your profile information</h3>-->
<h4>Public Profile</h4>
<strong>NOTE:</strong> Fields filled with [NONE] will not show on the website.
<br />
<form id="profile" name="profile" method="get" action="lib/preview.php">
<input type="hidden" value="profile" name="form">
<input type="hidden" value="<?php echo $_SESSION['id']; ?>" name="id">
<table>
<tr>
<td><label for="myname">Hello, My name is:</label><td>
<td><input type="text" readonly="readonly" name="myname" value="<?php echo $_SESSION['firstname']; ?>"/><td>
</tr>
<tr>
<td><label for="nickname">But I like to be called:</label><td>
<td><input type="text" name="nickname" value="<?php echo $row['nickname']; ?>"/><td>
</tr>
<tr>
<td><label for="town">I live in:</label><td>
<td><input type="text" name="town" value="<?php echo $row['location']; ?>"/><td>
</tr>
<tr>
<td><label for="role">My role on the team is:</label><td>
<td><input type="text" name="role" value="<?php echo $row['role']; ?>"/><td>
</tr>
<tr>
<td><label for="yog">I will graduate High School in:</label><td>
<td><input type="text" name="yog" value="<?php echo $row['yog']; ?>"/><td>
</tr>
<tr>
<td><label for="interests">Some of my interests are:</label><td>
<td><input type="text" name="interests" value="<?php echo $row['interests']; ?>"/><td>
</tr>
<tr>
<td><label for="fav_moment">One of my favorite team moments:</label><td>
<td><input type="text" name="fav_moment" value="<?php echo $row['favMoment']; ?>"/><td>
</tr>
<tr>
<td><label for="gain">I would like to gain the following this year:</label><td>
<td><input type="text" name="gain" value="<?php echo $row['gainThisYr']; ?>"/><td>
</tr>
<tr>
<td><label for="future">My future plans include:</label><td>
<td><input type="text" name="future" value="<?php echo $row['futurePlans']; ?>"/><td>
</tr>
<tr>
<td><label for="bio">My Bio:</label><td>
<td><textarea name="bio" ><?php echo $row['bio']; ?></textarea><td>
</tr>
</table>
* All fields are required.
<?php
include "disclaimer.php";
// @todo add js validation of all fields filled in
?>
<br><input type="submit" name="Submit" value=" I Agree, Preview "/>
</form>
*所有字段都是必填字段。
尝试使用;在将用户输入放入数据库之前,必须在所有用户输入上使用该功能
例如:
将$\u请求['昵称]
更改为mysql\u real\u escape\u字符串($\u请求['昵称]])
或者使用。您的代码已被填充。请查看。或至少。不要使用您的代码
还有
不要使用$\u请求。请使用适当的全局$\u POST或$\u GET。GET请求不应更改任何内容,因此应使用$\u POST。在可以使用引号的值的每个位置使用
添加斜杠($mystringwithquotes)
方法在引号之前添加斜杠
请确保不要在完整的SQL字符串中使用这些内容,因为您仍然希望保留所需的内容
例如,在您的代码中:
$sql = "INSERT INTO `tims`.`pending_profile`"
. "(`id`, `nickname`, `location`, `role`, `yog`, `interests`, `favMoment`, `gainThisYr`, `futurePlans`, `bio`) \n"
. "VALUES ('" . $_SESSION['id'] . "', '" . $_REQUEST['nickname'] . "', '" . $_REQUEST['town'] . "', '" . $_REQUEST['role'] . "', '" . $_REQUEST['yog'] . "', '" . $_REQUEST['interests'] . "', '" . $_REQUEST['fav_moment'] . "', '" . $_REQUEST['gain'] . "', '" . $_REQUEST['future'] . "', '" . $_REQUEST['bio'] . "')\n"
. "ON DUPLICATE KEY UPDATE nickname ='" . $_REQUEST['nickname'] . "', location='" . $_REQUEST['town'] . "', role= '" . $_REQUEST['role'] . "', yog='" . $_REQUEST['yog'] . "', interests='" . $_REQUEST['interests'] . "', favMoment='" . $_REQUEST['fav_moment'] . "', gainThisYr='" . $_REQUEST['gain'] . "', futurePlans='" . $_REQUEST['future'] . "', bio='" . $_REQUEST['bio'] . "'\n";
$qry = mysql_query($sql) or die(mysql_error());
在将变量插入数据库之前,如果没有对表单中的变量进行清理,你会被痛骂一顿 PHP手册中有过滤/消毒的示例 由于您使用的是php和mysql,另一种流行的方法是这样的
$var = mysql_real_escape_string($_POST['var']);
更多信息请点击此处:
希望这会有所帮助。访问数据库时始终使用参数化查询。在这样做时构造动态SQL语句会引发SQL注入攻击(以及您看到的错误) 在PHP中,执行此操作的代码如下所示
$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'world');
$stmt = $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
$stmt->bind_param('sssd', $code, $language, $official, $percent);
(无耻地摘自PHP手册)。如果$\u POST
变量必须是数字,也可以使用(int)
。使用传统的“普通”(非参数化)查询,您必须遵循3条规则
- 所有字符串(数据的引用部分)都必须转义
- 所有数字必须显式转换为其类型
- 所有标识符或运算符都应从先前定义的变量中选择
function dbSet($fields,&$source) {
$set='';
foreach ($fields as $field) {
if (isset($source[$field])) {
$set.="`$field`='".mysql_real_escape_string($source[$field])."', ";
}
}
return substr($set, 0, -2);
}
但是你的代码太脏了,不能用它来做一个有效的例子。这是虚拟的一个
$fields = explode(" ","name surname lastname address zip fax phone");
$query = "INSERT INTO $table SET ".dbSet($fields, $_POST);
正如其他人提到的,您需要处理字符串中的文字引号字符,否则很容易受到攻击 有关更多示例和解决方案,请参见我的演示 使用查询参数是一种有效的防御措施,它实际上更容易编写,并且使代码看起来更漂亮。我建议使用PDO,因为它允许您使用命名参数
还考虑使用PHP来编写SQL代码更简单,而不用担心所有的双引号和级联字符串。
$sql = <<<END_SQL
INSERT INTO `tims`.`pending_profile`
(`id`, `nickname`, `location`, `role`, `yog`, `interests`, `favMoment`,
`gainThisYr`, `futurePlans`, `bio`)
VALUES (:id, :nickname, :town, :role:, :yog, :interests, :fav_moment,
:gain, :future, :bio)
ON DUPLICATE KEY UPDATE
nickname = :nickname,
location = :town,
role = :role,
yog = :yog,
interests = :interests,
favMoment = :fav_moment,
gainThisYr = :gain,
futurePlans = :future,
bio = :bio
END_SQL;
$stmt = $pdo->prepare($sql);
$success = $stmt->execute(array(
':id' => (int) $_SESSION['id'],
':nickname' => $_POST['nickname'],
':town' => $_POST['town'],
':role' => $_POST['role'],
':yog' => $_POST['yog'],
':interests' => $_POST['interests'],
':fav_moment' => $_POST['fav_moment'],
':gain' => $_POST['gain'],
':future' => $_POST['future'],
':bio' => $_POST['bio'],
));
除了SQL注入风险之外,您的代码还充满了不同类型的安全风险,称为XSS或XSS。当您将用户提供的内容回显到HTML输出时,就会发生这种情况,而不会转义HTML中的特殊字符,例如
,对于未来的人来说,这对我很有用
string addslashes(string$str)
(PHP4、PHP5、PHP7)
addslashes-带斜杠的引号字符串
返回需要转义的字符前带有反斜杠的字符串。这些字符是单引号(')、双引号(“)、反斜杠()和NUL(空字节)。
阅读SQL注入:那么,当我将它们从数据库中取出时,如何取消它们的转义呢?另外,如果你想知道如果你不太关心SQL注入会发生什么,请看一下这个,因为妈妈说:哇,“这条线索中所有的幻影否决票是怎么回事?”斯帕雷尔上校——我只是指出,对否决票的解释可能会得到接收者的赞赏。没有必要居高临下。有一个好的。不是“你可以”,“你绝对必须”。愚蠢的“用户输入”再次。似乎不需要在管理输入中转义引号。和愚蠢的“用户输入”而不是字符串。在未加引号的数字上使用这个函数,然后吃掉你的注入。在这里,你可以看到一个新的例子,说明这种愚蠢假设的后果:最好是SQL注入。@delnan:不,你不需要在用户的任何和所有输入上使用它。如果在运行查询之前验证输入,则绝对没有注入的风险@Col:用户输入包括管理员的输入。这与你在网页上的权利无关。@nikic去告诉所有这些家伙吧。管理员输入只是一个数字,它可以是脚本生成的数据或任何东西。为什么要提到愚蠢的用户输入,而查询中的每一个该死的字符串都必须转义,不管它来自何处?至于您的“无需”,验证规则可能会更改。数据验证与数据库级别完全无关。请不要建议使用addslashes进行SQL注入防御。这不是正确的解决方案,因为它不考虑多字节字符集。使用数据库API提供的转义函数:例如mysql_real_escape_string.+1,但我要补充的是,在PDO中使用参数要容易得多。我发现MySQLIAPI更难使用。+1但我发现六次键入同一组字段令人难以置信地无聊。更不用说一个字段被添加到表中的情况了。。。应该有一些帮助函数,使程序员的工作更智能一些。@Col shrapanel:如果您将位置参数与?
占位符一起使用,您只需键入三次而不是六次名称。但在这个例子中,在重复密钥更新时插入…必须将每个值传递两次(可以使用array\u merge()
$sql = <<<END_SQL
INSERT INTO `tims`.`pending_profile`
(`id`, `nickname`, `location`, `role`, `yog`, `interests`, `favMoment`,
`gainThisYr`, `futurePlans`, `bio`)
VALUES (:id, :nickname, :town, :role:, :yog, :interests, :fav_moment,
:gain, :future, :bio)
ON DUPLICATE KEY UPDATE
nickname = :nickname,
location = :town,
role = :role,
yog = :yog,
interests = :interests,
favMoment = :fav_moment,
gainThisYr = :gain,
futurePlans = :future,
bio = :bio
END_SQL;
$stmt = $pdo->prepare($sql);
$success = $stmt->execute(array(
':id' => (int) $_SESSION['id'],
':nickname' => $_POST['nickname'],
':town' => $_POST['town'],
':role' => $_POST['role'],
':yog' => $_POST['yog'],
':interests' => $_POST['interests'],
':fav_moment' => $_POST['fav_moment'],
':gain' => $_POST['gain'],
':future' => $_POST['future'],
':bio' => $_POST['bio'],
));
$id = (int) $_SESSION['id'];
$sql = "SELECT * FROM `pending_profile` WHERE id = {$id}";
$stmt = $pdo->query($sql);
$row = $stmt->fetch();
<td><input type="text" name="nickname" value="<?php echo htmlentities($row['nickname']); ?>"/><td>
<?php
$str = "Is your name O'Reilly?";
// Outputs: Is your name O\'Reilly?
echo addslashes($str);
?>