Php 帮助我阻止用户输入有害代码

Php 帮助我阻止用户输入有害代码,php,security,Php,Security,这个问题一直在我的脑海中发展,我如何完全阻止用户进入一些疯狂的SQL注入。mysql\u real\u escape\u字符串的功能不足以阻止它吗?我遵循了一些指导原则,尽管这里有一些用户批评我的代码,并对安全性表示反对。我无法理解背后的原因。虽然我没有使用$\u GET,但用户的唯一输入是通过评论系统。我只是想确保我不会出错。这是我的示例代码 $name = htmlspecialchars(strip_tags(mysql_real_escape_string($_POST['com_nam

这个问题一直在我的脑海中发展,我如何完全阻止用户进入一些疯狂的SQL注入。mysql\u real\u escape\u字符串的功能不足以阻止它吗?我遵循了一些指导原则,尽管这里有一些用户批评我的代码,并对安全性表示反对。我无法理解背后的原因。虽然我没有使用$\u GET,但用户的唯一输入是通过评论系统。我只是想确保我不会出错。这是我的示例代码

$name = htmlspecialchars(strip_tags(mysql_real_escape_string($_POST['com_name'])));

我在大约5个字段中使用了相同的方法。您对我的上述代码有何看法?

我们的想法不是阻止用户输入代码,而是确保您在数据库查询中安全地输入它们。这意味着使用
mysql\u real\u escape\u string
或使用参数化查询:


您还需要确保对从数据库读取的字段进行正确的html编码,以避免用户能够在将用户输入插入数据库时插入html(以及javascript)

,而
mysql\u real\u escape\u string
就足够了。更好的方法是使用准备好的语句——PDO或MySQLi

如果您只是在页面上显示用户数据,则应使用
htmlspecialchars()
htmlentities()

至于你发布的代码。让我们把它分解一下

  • htmlspecialchars
    -转换html 将字符转换为各自的实体
  • strip_标记
    -剥离HTML和PHP 代码中的标记
  • mysql\u real\u escape\u string
    -escape 数据库输入之前的字符
因此,正如您所看到的,您使用的前两个函数似乎适得其反。您正在将HTML字符合并到实体中,但也正在剥离标记


确保在DB entry
mysql\u real\u escape\u string
之前保护用户输入就足够了。或者正如我前面提到的,利用准备好的语句

如果找不到或无法创建与数据库的连接,则对
mysql\u real\u escape\u string
的调用可能会失败

我倾向于在实际执行查询之前尽可能深入地进行此类调用。这可能会降低我的性能,但我不必担心丢失更高级别的参数(关于sql注入),而且我知道在这一点上我始终与数据库保持有效连接


对于所有用户输入,我也要做的第一件事是在对其执行任何其他操作之前,先用filter\u SANITIZE\u SPECIAL\u CHARS运行它。

不,您的代码不太安全,甚至不太合理

这里是
简而言之,mysql\u real\u escape\u字符串本身并不能保护任何东西。只有将数据放在引号中,它才有效

至于htmlspecialchars/strip_标记,两者都与SQL无关,它是HTML保护,而不是SQL。
同时使用这两种方法是多余的。只要一个就够了。我更喜欢htmlspecialchars

我不希望我的用户输入任何html或javascript代码,它应该是至少这个项目的纯文本。难道你不认为我的代码已经处理好了吗?你的通用代码应该允许用户在数据库中插入任何(有效的)数据。如果需要额外的筛选,则应在单独的验证阶段进行,而不是在数据库中输入时。@Quamis我想这就是我要做的,我先筛选代码,然后将其传递给数据库,我从未将其直接传递给数据库。如果我错了,请纠正我。@Ibrahim look。你从错误的角度思考它(几乎每个人都是这样):数据库转义/参数化与用户输入无关。它不是用户输入的属性!这只是查询格式化规则。对于任何数据,无论数据来自何处,都应遵循这一点。您的数据库层应该只负责SQL。它与用户输入无关。您必须将这些大头钉分开。应该对任何数据进行数据库转义,无论id用户输入与否。虽然剥离标记应该在未受信任的输入下完成,而不是管理员的输入。这是不同的任务。这不会影响任何性能,但您看不到将转义放在“查询之前”的适当理由。这并不是因为像这个贫穷世界的每个人所想的那样,输入数据需要转义。但是对于SQL查询。所以,就在查询之前是唯一可能的地方。啊,是的,我知道你在说什么。感谢您指出了不太明显的地方。:)mysql\u real\u escape\u字符串不够。mysql\u real\u escape\u字符串加引号将
/* Prepare an insert statement */
$query = "INSERT INTO myCity (Name, CountryCode, District) VALUES (?,?,?)";
$stmt = mysqli_prepare($link, $query);

mysqli_stmt_bind_param($stmt, "sss", $val1, $val2, $val3);