清理filter_var PHP字符串,但保持" '

时间:2016-03-07 15:01:11

标签: php sanitization

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

$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"?

1 个答案:

答案 0 :(得分:2)

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

有时,数据被用作计算机源代码,这样的代码最终会导致物理操作(磁盘旋转,LED闪烁,图片上传到远程计算机,恒温器关闭锅炉......)。然后(当时只有那时)数据会变得有害;我们偶尔会因为软件漏洞而丢失昂贵的太空船。

您自己编写的代码可能与您的能力或诚信所要求的一样有害或无害。当您的应用程序存在允许执行不受信任的第三方代码的漏洞时,就会出现一个大问题。这在Web应用程序中尤其严重,Web应用程序连接到开放式互联网,并且有望从世界上任何地方接收数据。但是,身体上可能的怎么样?有几种方法,但最典型的情况是由于动态生成的代码,这在现代www中一直发生。您使用PHP生成SQL,HTML,JavaScript ...如果您选择不受信任的任意数据(例如URL参数或表单字段)并使用它来编写稍后将执行的代码(由您的服务器或访问者的浏览器执行) )某人可能被黑客入侵(无论是您还是您的用户)。

你每天都会在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'"));

这是一个令人惊讶的广泛误解,即使是一些专业人士也采用了这种误解。您可以在任何地方看到这些症状:您的评论在第一个<符号处被删除,注册时会显示“您的密码不能包含空格”,并且您在常见问题解答中阅读了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. 使用每种技术的特定机制:

    如果目标语言需要转义:

    <p><3 to code</p><p>&lt;3 to code</p>

    ...找到一个特定的工具来逃避源语言:

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

    如果语言/框架/技术允许在单独的频道中发送数据,请执行以下操作:

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