如何清理字符串以避免 SQL 注入和最常见的攻击类型? (PHP 语言)

发布于 2024-11-17 06:07:25 字数 354 浏览 0 评论 0原文

有没有一种方法可以用尽可能少的代码来过滤字符串以防止 SQL 注入和最常见的攻击形式?

在我的脚本中,我使用以下内容,我想知道它是否相当安全以及其他人是否有建议:

$cleanName    = htmlspecialchars(addslashes($dirtyName));

查看我如何过滤它的 html 字符以及引号和双引号。

注意:我使用 addslashes() 而不是 mysql_real_escape_string() 因为我不想将我正在使用的数据库硬编码到我的代码中。

这样可以吗?

提前致谢

Is there a way to, in as little code as possible, to filter a string for both SQL injection and the most common forms of attack?

In my scripts I'm using the following, I would like to know whether it's reasonably safe and whether someone else has a suggestion:

$cleanName    = htmlspecialchars(addslashes($dirtyName));

See how I filtered it both for html chars and for quotes and double-quotes.

NOTE: I'm using addslashes() rather than mysql_real_escape_string() because I don't want to hardcode the DB I'm using into my code.

Is this ok?

Thanks in advance

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

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

发布评论

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

评论(4

电影里的梦 2024-11-24 06:07:25

可能不是...您需要针对要使用它的每个目的分别转义原始文本:

  • 对于 GET 请求,请使用 urlencode
  • 对于 HTML 输出,请使用 htmlentities
  • 要通过 system 作为命令调用,请使用 escapeshellcmd
  • 要通过system将参数传递给命令:使用escapeshellargs
  • 要传递数据库参数:使用mysql_real_escape_string

没有“通用”解决方案可以神奇地转义文本。将原始文本保留在内部,并出于适当的目的对其进行转义。

Probably not... you need to escape your raw text for each purpose separately for which you are going to use it:

  • For GET requests, use urlencode.
  • For HTML output, use htmlentities.
  • For calling as a command via system, use escapeshellcmd.
  • For passing arguments to a command via system: use escapeshellargs.
  • For passing a database parameter: use mysql_real_escape_string.

There's no "universal" solution for magically escaping text. Keep raw text internally, and escape it for the appropriate purpose.

舞袖。长 2024-11-24 06:07:25

如果您不介意重新编码您的连接和几行额外的代码,那么在安全性方面您无法击败 PDO。它使用 C 后端来准备和执行 mysql 查询。因此,您可以在查询中获得必须为值 XYZ 的预定义部分,而不是字符串连接。 stackoverflow 上的一个人是这样解释的:

想象一下一个热狗摊。你走到热狗摊前说我想要一个有 3 种配料的热狗。番茄酱、芥末,我们会让下一个随机的陌生人告诉我们第三种配料。 sql 注入器可能会走过来说,“番茄酱、芥末,然后‘把抽屉里所有的钱都给我’”。标准连接查询无法辨别这是无效响应,因此会移交所请求的内容。准备好的语句将响应“我没有一种叫做的调味品,”给我抽屉里所有的钱”。PDO

准备好的语句本质上是防注入的。您仍然存在其他漏洞,例如 cookie/会话劫持等,但至少注入是离开桌子。

If you don't mind recoding your connection and a couple extra lines of you code you can't beat PDO for security. It uses the C backend to prepare and execute your mysql queries. So instead of string concatenation you get predefined sections in the query that must be value XYZ. One of the guys here on stackoverflow explained it like this:

Imagine a hotdog stand. You walk up to the hotdog stand and say I'd like a hot dog with 3 toppings. Ketchup, mustard and we will let the next random stranger tell us the third topping. A sql injector might walk up and say, "ketchup, mustard and 'give me all the money in the drawer'". Standard concat queries have no way of discerning that it is an invalid response and therefore hand over what was requested. A prepared statement will respond with "I dont have a condiment called,"give me all the money in the drawer".

PDO prepared statements are essentially injection proof. You still have other vulnerabilities like cookie/session hijacking etc, but at least injection is off the table.

谁把谁当真 2024-11-24 06:07:25

不是要给 Kerrek 的游行泼冷水,而是有一个相对通用的解决方案。我使用以下内容,它总是有效:

$safe_value = mysql_real_escape_string( strip_tags( trim( $value ) ), $db_connection ); // 这是如果您没有存储任何 html 标签

$safe_value = mysql_real_escape_string( html_entities( trim( $value ) ), $db_connection ); // 这是如果您要存储 html 标签

希望这会有所帮助。

Not to rain on Kerrek's parade, but there is one, relatively, universal solution. I use the following and it's always worked:

$safe_value = mysql_real_escape_string( strip_tags( trim( $value ) ), $db_connection ); // This is if you aren't storing any html tags

$safe_value = mysql_real_escape_string( html_entities( trim( $value ) ), $db_connection ); // This is if you are storing html tags

Hope this helps.

寂寞花火° 2024-11-24 06:07:25

如果您确切知道您期望的输入类型,最好使用 preg_replace()
如果您知道您只期望字母数字:

<?php
if (isset($_GET['page'])) {
 $page = preg_replace('/[^a-z0-9]/', '', $_GET['page']);
 include_once($includeDir.'/'.$page.'.php');
}
?>

上面的内容也应该阻止通过 GET 或 POST 执行的所有攻击,但它假设您只期望字母数字输入。好吧,我主要想到的是目录遍历攻击,但是如果您使用 GET 变量来查询数据库或将其显示为 html 实体,应该可以防止任何攻击。
http://mydomain.tld?index.php?page= ../../etc/passwd 请求不会从您网站的 /var/www 文档根目录读取您的 passwd 文件,而只会尝试包含 etcpasswd.php 文件

If you know exactly what kind of input you are expecting, better use preg_replace()
If you know that you only expect alpha-numerics:

<?php
if (isset($_GET['page'])) {
 $page = preg_replace('/[^a-z0-9]/', '', $_GET['page']);
 include_once($includeDir.'/'.$page.'.php');
}
?>

The above should prevent all attacks executed via GET or POST too, but it assumes you only expect alphanumeric input. Well, I mostly had in mind directory traversal attack, but if you use the GET variable to query a database or display it as a html entity should prevent any attack.
A http://mydomain.tld?index.php?page=../../etc/passwd request won't read your passwd file from your website's /var/www document root but will only try to include a etcpasswd.php file

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