您好我是初学者,所以请至少尝试给我一个提示,一个例子。
如果某人键入" Hello my name is J'hon '
,则文本不会插入数据库中,但如果他键入'Hello my name is jhon'
,则会输入'Hello my name is J[color=#FF0000]'[/color]hon J'onz. '
。我认为这是'
好的,我有问题,如果有人打字
mysqli_query($DB_H, "INSERT INTO tickets (name, continutscurt, continut,type,status) VALUES ('".$_SESSION['username']."', '".$_POST['titlu']."', '".$_POST['continut']."', $numar, 0)");
未插入数据库..
这是剧本:
File.ReadLines
答案 0 :(得分:4)
在处理任何类型的用户输入时,您应该使用预准备语句。如果您因任何奇怪的原因未使用预准备语句,请查看函数mysqli::real_escape_string
。这将处理特殊字符,例如'
,这可能会破坏SQL。
使用预准备语句,您的代码看起来像
if ($stmt = $DB_H->prepare("INSERT INTO tickets (`name`, continutscurt, continut, `type`, `status`) VALUES (?, ?, ?, ?, ?)")) {
$stmt->bind_param("ssssi", $_SESSION['username'], $_POST['titlu'], $_POST['continut'], $numar, 0);
$stmt->execute();
$stmt->close();
} else {
echo mysqli_error($DB_H);
}
如果你想使用mysqli::real_escape_string
,你需要将SESSION和POST绑定到一个变量,而你插入的变量就像这样(你也可以在查询中直接进行,但是这使代码更清晰。)
$username = mysqli_real_escape_string ($DB_H, $_SESSION['username']);
$titlu = mysqli_real_escape_string ($DB_H, $_POST['titlu']);
$continut = mysqli_real_escape_string ($DB_H, $_POST['continut']);
$numar = mysqli_real_escape_string ($DB_H, $numar);
if (!mysqli_query($DB_H, "INSERT INTO tickets (`name`, continutscurt, continut, `type`, `status`) VALUES ('$username', '$titlu', '$continut', '$numar', 0")) {
echo mysqli_error($DB_H);
}
我还在name
,status
和type
周围添加了反引号,因为它们是SQL中的关键字。这不是绝对必要的,但对于列为保留字或关键字的单词,this list of keywords上的更多信息,这是一种很好的做法。
您不应该理所当然地认为您的查询是成功的,因此我在其周围添加了if
- 块。除非在生产/开发中,否则不应显示错误。
参考文献:
答案 1 :(得分:2)
问题是SQL注入。
SQL文本中包含可能不安全的值。
要看到这一点,请稍微分解一下代码。
$sql = "INSERT INTO tickets ...'" . $val . "' ... ";
echo $sql;
echo
只是为了查看正在发生的事情,您可以检查包含SQL文本的字符串的内容。然后将该字符串转移到另一个客户端,并进行测试。你会看到问题所在。
... VALUES ( ..., 'J'onz. ', ...
无效。单引号结束字符串,因此字符串只是'J',而下一部分,MySQL将尝试解释为SQL的一部分,而不是字符串值。 (这是一个邪恶的漏洞。巧妙构造字符串并对您的应用程序和数据库造成严重破坏。)
解决这个问题的一种方法是对值进行消毒,以便安全地将其包括在内。
... VALUES ( ..., 'J\'onz. ', ...
^^
... VALUES ( ..., 'J''onz. ', ...
^^
作为一个简单的演示,请尝试以下查询:
SELECT 'J\'onz. '
SELECT 'J''onz. '
SELECT 'J'onz. '
(前两个将返回您期望的字符串,第三个将导致错误。)
带走的是,需要正确转义将包含在SQL语句文本中的潜在不安全值。幸运的是,MySQL客户端库包含mysqli_real_escape_string
功能。可能包含单引号字符的变量可以通过该函数运行,并且函数的返回可以包含在SQL文本中。
$sql = "INSERT INTO tickets ...'"
. mysqli_real_escape_string($DB_H,$val)
. "' ... ";
再次回显$sql
,您可以看到单个引号已被转义,可以通过在其前面加上反斜杠字符,或者用两个sinqle引号替换它。
比“转义”字符串有更好的模式。那就是使用预备语句和绑定占位符。
SQL文本可以是静态字符串:
$sql = 'INSERT INTO mytable (mycol) VALUES ( ? )'
然后你msyqli_prepare
声明。
然后通过调用mysqli_bind_param
为占位符提供值。
然后拨打mysqli_execute
。
使用这种模式,我们不需要运行“转义字符串”功能来清理输入。