【问题标题】:Sanitize filter_var PHP string but keep " '清理 filter_var PHP 字符串但保留 " '
【发布时间】:2016-03-09 18:52:27
【问题描述】:

我正在清理联系表单字符串:

$note = filter_var($_POST["note"], FILTER_SANITIZE_STRING);

这很好用,除非人们用英寸 (") 和英尺 (') 书写。所以 I'm interested in 5" 8" 10" & 1' 出现为 I'm interested in 5" 8" 10" & 1' 这有点乱码。

我可以消毒并保持我 5 英尺 9 英寸吗?

【问题讨论】:

  • 您从...开始消毒的目的是什么?
  • '&#34 在 HTML 文本上下文中分别与 '" 相同。如果您使用它以纯文本形式保存到数据库或电子邮件,那么您就大错特错了。
  • What does FILTER_SANITIZE_STRING do? - 剧透:没有什么真正有意义或有用的。
  • 您需要针对目标使用环境进行消毒。如果字符串过滤器正在删除您需要的字符,那么您首先不应该使用该方法。
  • @mrun 这真是一个反问。 “消毒”作为一个概念充其量是令人讨厌的,并且没有千篇一律的消毒功能。在 99% 的情况下,消毒是无稽之谈。我会冒险并预测,如果 OP 知道他们正在消毒什么,他们就不会发布这个问题,因为他们会知道消毒的作用以及可能如何解决其不良副作用。

标签: php sanitization


【解决方案1】:

计算机数据本身既无害也无害。这只是一条信息,以后可以用于特定目的。

有时,数据被用作计算机源代码,而这些代码最终会导致物理操作(磁盘旋转、LED 闪烁、图片上传到远程计算机、恒温器关闭锅炉……)。那时(而且只有那时)数据会变得有害;由于软件错误,我们甚至不时失去昂贵的太空船。

您自己编写的代码可能与您的能力或诚信所决定的一样有害或无害。当您的应用程序存在允许执行不受信任的第三方代码的漏洞时,就会出现大问题。这在 Web 应用程序中尤为严重,这些应用程序连接到开放的互联网,并有望从世界任何地方接收数据。但是,这在物理上怎么可能?有几种方法,但最典型的情况是由于动态生成的代码,这在现代 www 中一直发生。您使用 PHP 生成 SQL、HTML、JavaScript... ) 有人可能被黑客入侵(您或您的用户)。

您每天都会在 Stack Overflow 上看到这一点:

$username = $_POST["username"];
$row = mysql_fetch_array(mysql_query("select * from users where username='$username'"));
<td><?php echo $row["title"]; ?></td>
var id = "<?php echo $_GET["id"]; ?>";

面对这个问题,有人声称:让我们进行消毒吧!很明显有些角色是邪恶的,所以我们将它们全部删除,我们就完成了,对吧?然后我们看到这样的东西:

$username = $_POST["username"];
$username = strip_tags($username);
$username = htmlentities($username);
$username = stripslashes($username);
$row = mysql_fetch_array(mysql_query("select * from users where username='$username'"));

这是一个令人惊讶的普遍误解,甚至被一些专业人士所采用。您到处都可以看到症状:您的评论首先被破坏了&lt; 符号,您在注册时收到“您的密码不能包含空格”,并且您在常见问题解答中阅读了Why can’t I use certain words like "drop" as part of my Security Question answers?。它甚至出现在计算机语言中:每当您在函数名称中读到“sanitize”、“escape”...(没有进一步的上下文)时,您都会很好地暗示这可能是一种错误的努力。

这一切都是为了明确区分数据和代码:用户提供数据,但只有您提供代码。并且没有通用的万能解决方案,因为每种计算机语言都有自己的语法和规则。 DROP TABLE users; 在 SQL 中可能非常危险:

mysql> DROP TABLE users;
Query OK, 56020 rows affected (0.52 sec)

(哎呀!)......但它并没有那么糟糕,例如JavaScript。看,它甚至没有运行:

C:\>node
> DROP TABLE users;
SyntaxError: Unexpected identifier
    at Object.exports.createScript (vm.js:24:10)
    at REPLServer.defaultEval (repl.js:235:25)
    at bound (domain.js:287:14)
    at REPLServer.runBound [as eval] (domain.js:300:12)
    at REPLServer.<anonymous> (repl.js:427:12)
    at emitOne (events.js:95:20)
    at REPLServer.emit (events.js:182:7)
    at REPLServer.Interface._onLine (readline.js:211:10)
    at REPLServer.Interface._line (readline.js:550:8)
    at REPLServer.Interface._ttyWrite (readline.js:827:14)
>

最后一个例子也说明这不仅仅是一个安全问题。即使您没有被黑客入侵,从随机输入生成代码也会让您的应用崩溃:

SELECT * FROM customers WHERE last_name='O'Brian';

您的 SQL 语法有误;查看与您的 MySQL 服务器版本相对应的手册,了解在“Brian”附近使用的正确语法

那么,如果没有通用的解决方案,那该怎么办呢?

  1. 了解问题:

    如果您不正确地注入原始文字数据,它可能会变成代码(有时是无效代码)。

  2. 使用每种技术的特定机制:

    如果目标语言需要转义:

    &lt;p&gt;&lt;3 to code&lt;/p&gt;&lt;p&gt;&amp;lt;3 to code&lt;/p&gt;

    ...在源语言中找到一个特定的工具来转义:

    echo '<p>' . htmlspecialchars($motto) . '</p>';
    

    如果语言/框架/技术允许在单独的通道中发送数据,请这样做:

     $sql = 'SELECT password_hash FROM user WHERE username=:username';
     $params = array(
         'username' => $username,
     );
    

【讨论】:

  • 我发现这个博客很好地概述了这个问题 kunststube.net/escapism - “伟大的逃避现实(或:你需要知道什么才能使用文本中的文本)”
猜你喜欢
  • 2012-01-15
  • 2012-07-13
  • 2023-01-06
  • 1970-01-01
  • 2016-03-15
  • 2015-01-23
  • 2014-02-09
  • 1970-01-01
  • 2018-05-05
相关资源
最近更新 更多