防止仅 INSERT 查询上的 SQL 注入。这有什么大不了的吗?

发布于 2025-01-03 01:51:51 字数 447 浏览 4 评论 0原文

这是我第一次创建 PHP 表单,该表单将使用 INSERT INTO 运行 MySQL 查询以将数据存储在生产数据库中。这会被视为“安全”还是太过分了?

$orderText = $mysqli->real_escape_string(stripslashes(htmlentities((!isset($_POST["order_text"])?"undefined":$_POST["order_text"]))));
$stmt = $mysqli->prepare("INSERT INTO testtable (order_text) VALUES (?)");
$stmt->bind_param('s',$orderText);
$stmt->execute();

我不确定缺少 SELECT * 会如何影响我面临的风险程度,但似乎只使用 INSERT 的脚本更安全。真的?

This is my first time creating a PHP form that will run a MySQL query using INSERT INTO to store data in a production DB. Will this pass for "secure" or is it over-kill?

$orderText = $mysqli->real_escape_string(stripslashes(htmlentities((!isset($_POST["order_text"])?"undefined":$_POST["order_text"]))));
$stmt = $mysqli->prepare("INSERT INTO testtable (order_text) VALUES (?)");
$stmt->bind_param('s',$orderText);
$stmt->execute();

I'm not sure how the lack of a SELECT * affects the amount of risk I'm opening myself up to, but it seems like a script that only uses INSERT is safer. True?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

标点 2025-01-10 01:51:51

你的问题中有很多错误的假设。

  1. 这确实是一种矫枉过正的行为。
    让我们检查一下您的极其难以阅读的 zillion-nested-operator 语句:

    • 存储“未定义”一词没有任何意义。数据库对未定义的字段有一个特殊的标记——NULL 值。或者只需一个空字符串就足够了。
    • 无条件的 stripslashes 不会增加安全性,但可能会破坏数据。
    • htmlentities 与 SQL 安全无关,可能有助于其他方面的站点安全,并且也可能损坏数据。
    • 转义不会增加安全性,并且会破坏数据。
  2. 你从错误的角度看待问题。
    您的主要目标是正确设置查询格式。不是为了防御想象中的“攻击者”,而是为了利用最诚实的数据来防止故障。虽然格式正确的查询将不会受到各种攻击,但作为副作用。
    比如说,real_escape_string 与安全性无关。它仅用于格式化字符串。您的查询中没有字符串(用引号引起来的数据) - 因此这个函数完全无用(甚至有害)。

  3. 事实上,通过 INSERT 注入的灾难性并不比通过 SELECT 注入少。

最后,正确的代码是

$stmt = $mysqli->prepare("INSERT INTO testtable (order_text) VALUES (?)"); 
$stmt->bind_param('s',$_POST["order_text"]); 
$stmt->execute(); 

,当将订单文本打印回网站时,使用 htmlspecialchars()

即可。

There is a great amount of false assumptions in your question.

  1. It is certainly an overkill.
    Let's examine your extremely-hard-to-read zillion-nested-operator statement:

    • storing word 'undefined' makes no sense. A database has a special mark for the undefined fields - a NULL value. Or simply an empty string would be enough.
    • unconditional stripslashes adds nothing to security but may spoil the data.
    • htmlentities has nothing to do with SQL security, may help with site security in other aspects and may spoil the data as well.
    • escaping adds nothing to security and will spoil the data.
  2. You are taking the problem from the wrong end.
    Your primary goal is to format your query properly. Not to defend from imaginary "attackers" but to privent malfunction with most honest data. While properly formatted query will be invulnerable to various attacks just as a side effect.
    Say, real_escape_string has nothing to do with security. It is used merely to format strings. There are no strings (data enclosed in quotes) in your query - thus this function is utterly useless (and even harmful).

  3. In fact, an injection via INSERT is no less disastrous than via SELECT.

Finally, the right code would be

$stmt = $mysqli->prepare("INSERT INTO testtable (order_text) VALUES (?)"); 
$stmt->bind_param('s',$_POST["order_text"]); 
$stmt->execute(); 

and when printing the order text back to the site, use htmlspecialchars()

that's all.

烟花肆意 2025-01-10 01:51:51

您在第 3 行执行的变量绑定足以防止一般的注入攻击。绑定是一个好主意,在我看来,应该始终进行。它不仅具有安全优势,而且还可以提高性能。

我认为在第 1 行执行额外的解析实际上是一个缺点:
它增加了复杂性,并且一些攻击利用了已知的数据转换,尽管使用绑定也可以减轻这些攻击。

Variable binding, which you do on line 3, is sufficient to prevent injection attacks in general. Binding is a good idea and, in my opinion, should always be done. It has not only security advantages, but can yield a performance boost as well.

I would argue that performing the extra parsing at line 1 is actually a disadvantage:
It increases complexity, and some attacks take advantage of known data transformations, though using binding mitigates those as well.

南风几经秋 2025-01-10 01:51:51

我建议将来自客户、您的访客的一切视为威胁。不要放松,只关注一些sql查询。养成一个好习惯是没有限制的。

I will recommend to treat everything that comes from a client, your visitors, as threat. Don't relax and only focus on some sql queries. Practicing a good habit has no limitation.

豆芽 2025-01-10 01:51:51

我同意 Charles 的观点,通过绑定参数,您已经正确地转义了变量,消除了 SQL 注入攻击的机会,并且第 1 行的复杂性有些过大。当您跳转到 PDO 时,这一点会变得很明显,因为没有特定的 $dbo-> 。 escape()调用,因为转义工作已经通过prepare()/bind()调用完成。

I agree with Charles, by binding the param you are already properly escaping the variable removing the chance of a SQL injection attack, and the complexity of line 1 is overkill. This will be come evident when you make the jump to PDO, because there is no specific $dbo->escape() call, as the escaping work is already completed with the prepare() / bind() calls.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文