我目前正在基于PHP的CMS上工作很多,而我正处于这种状态时,我希望将用户输入的所有处理和卫生都移到一个中心位置。 (目前,这里是$ _REQUEST,$ _GET,等等)。
我非常喜欢filter_input(),并希望将它用于基本的卫生设施,但我不清楚这个功能是否真的是生产就绪。例如,documentation为$ type
命名以下参数 INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV, INPUT_SESSION (not implemented yet) and INPUT_REQUEST (not implemented yet).
自5.2.0以来该功能存在,为什么还没有实现两个关键要素呢?如果我想从$ _REQUEST获取数据,则必须使用用户提供的注释中的解决方法。有这个特殊原因吗?这个功能还处于某种形式吗?作为处理传入数据的第一个调用,它是否值得信赖?
也许熟悉PHP开发过程的人可以对此有所了解。
答案 0 :(得分:8)
我想将用户输入的所有处理和卫生移动到一个中心位置
是的,那将是多么可爱。它无法完成。这不是文本处理的工作方式。
如果要将文本从一个上下文插入另一个上下文,则需要使用正确的转义。 (mysql_real_escape_string用于MySQL字符串文字,htmlspecialchars用于HTML内容,urlencode用于URL参数,其他用于特定上下文)。在进行过滤时,在脚本开始时,您不知道输入结束的位置,因此您不知道如何逃避它。
也许一个输入字符串既可以进入数据库(需要进行SQL转义),也可以直接进入页面(需要进行HTML转义)。没有一个逃脱涵盖这两种情况。您可以一个接一个地使用两个转义符,但是HTML中的值将出现奇怪的反斜杠,数据库中的副本将充满&符号。几次这种错误编码,你得到的情况是,每当你编辑某些内容时,就会出现\\\\\\\\\\\\\\\\\\\\
和&
长字符串。
您可以在开始时一次性安全过滤的唯一方法是完全删除需要在任何中使用它们的情况下转义的所有字符。但是这意味着您的HTML中没有撇号或反斜杠,数据库中没有符号或更少的数据,并且可能还有一大堆其他不友好的标点符号。对于一个不带任意文本的简单网站,你可能会侥幸逃脱。但通常不会。
因此,当一种文本进入另一种文本时,您只能在运行中逃脱。避免此问题的最佳策略是尽可能避免将文本连接到其他上下文中,例如通过使用参数化查询而不是SQL字符串构建,以及定义具有良好短路的echo(htmlspecialchars())
函数name,以减少输入的工作量,或者使用默认情况下HTML转义的替代模板系统。
答案 1 :(得分:4)
答案 2 :(得分:3)
在编程中,您必须尽可能限制输入。这也适用于数据源。 $ _REQUEST包含$ _GET,$ _POST和$ _COOKIE中的所有内容,这可能会导致问题。
例如,如果您的CMS插件在其中一个插件中引入了一个新的特殊键,这恰好会在另一个插件中作为一个有意义的键存在,会发生什么?
所以不要使用$ _REQUEST。使用$ _GET,$ _POST或$ _COOKIE,以适合您的方案为准。 这是一个很好的做法,尽可能严格,这与PHP无关,但与一般的编程有关。